← Back to context

Comment by Certhas

2 days ago

The real "internal model" of git contains much more data/moving parts.

There isn't one tree of commits, there are typically at least two: local and remote

Branches are not just pointers to commits, but also possibly related to pointers in the other tree via tracking.

Stash and index and the actual contents of the working directory are additional data that live outside the tree of commits. When op says "avoid git reset hard" it's because of how all these interact.

Files can be tracked, untracked and ignored not ignored. All four combinations are possible.

None of these seem to preclude a command to make an arbitrary branch point to an arbitrary commit without changing anything else.

  • This works if the branch exists or creates it if it doesn't exist, but not if it's checked out.

        git branch -f branch_name commit
    

    if it's checked out:

        git reset --hard commit

    • > but not if it's checked out

      ...and for a good reason that should be apparent to anyone who understands git's model (HEAD points to a ref in this case, so if you suddenly change what that ref points to without updating the working tree you create an inconsistency).

      You can do that manually of course (with `git update-ref` or even a text editor), but then you get to clean up the mess yourself.

      8 replies →