12

Git branch heads and tags are pointers to commits, and these pointers can move either implicitly (after a commit) or explicitly (after a branch -m).

Does Git record the history of the state of these pointers?

I see at least two reasons for this:

  • To see the state of the repo two days ago, including where the branch heads pointed.
  • To make sure no history is lost because someone moved a branch head in a way that some commits become unreachable.

Note that the above are possible in Mercurial because it stores the branch name in each commit.

So again, in Git are the contents of .git/refs/ version controlled, or is there a way to make them so?

(I'm trying to decide on Mercurial or Git for a team, and I want to make sure all changes to the shared repo, including the refs, are recorded. I don't care what developers do to their private repos.)

Thank you.

Jake Lundy
  • 121
  • 1
  • 3

3 Answers3

9

They're not versioned, but the reflog feature keeps a local history that you can use to undo mistakes. However, if someone "rewinds" a branch head to discard some commits from the end, it'll become immediately obvious when another developer tries to update their checkout of that branch, because Git will refuse to make that change locally unless --force is used. You can easily just push the commits back to the shared repository at that point.

Wyzard
  • 33,849
  • 3
  • 67
  • 87
4

There are two ways:

git reflog

and:

git log -g

Equivalent with the first case:

git log --oneline -g
MAChitgarha
  • 3,728
  • 2
  • 33
  • 40
2

There are extensions to enterprise Git servers like Gerrit that will version your branch history. If a branch gets deleted or updated in a non fast forward way (push -f) it will back the previous version under a special ref so that they can be restored if needed and will not be pruned by garbage collection. Gerrit administrators can still remove selected commits if needed for legal reasons.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203