tags:

views:

169

answers:

3

reflog vs GITK

The top image is the output of: git reflog.
The bottom is what GITK in GIT GUI (msysgit) shows me when I look at all branch history.

The last few commits do not show on GIT GUI.

  • Why do they not show on GITK (at least as a branch or something)?
  • How do I merge them into master?
  • I gather this happened when I checked out tag 0.42. Why is that not the same as master? (I had tagged the master in its latest state)
  • When I click push, why does the remote repo claim to be up to date.. shouldn't it try to update these commits into whatever branch they are in?

The first of the questions is important - I would like to begin to understand what GIT is thinking. It's more oracle than logic at this point.

If it makes a difference to see the earlier history, the project is a [pretty powerful] JS color picker that can be viewed here in its entirety.

+1  A: 

why to update these commits into whatever branch they are in?

That's just it: you are not on any branch but currently working on a detached head:

starting from version 1.5.0, the above command detaches your HEAD from the current branch and directly points at the commit named by the tag.

You might see it if you do a gitk --all

One way to fix it (if you have committed everything)

$ git log -1
# note the SHA-1 of latest commit
$ git checkout master
# reset your branch head to your previously detached commit
$ git reset --hard <commit-id>

Another way would be to merge your work into the current master HEAD which happens to be at the tag:

 $ git checkout -m 0.42

but that looses the history of your commits made on a detached HEAD.


I gather this happened when I checked out tag 0.42. Why is that not the same as master? (I had tagged the master in its latest state)

No it is not the same than master. As Jefromi points out in the comments, branch can move (or be renamed, or deleted, or...)
master was referring to the same commit than the '0.42' tag, but that won't be always the case.
With a checkout of a tag, you do not checkout a branch, hence the 'detached HEAD' state.


Note: as mentioned in this SO answer, the @{1} notation you see is $(git symbolic-ref HEAD)@{1}, i.e. it is uses reflog for current (here detached) branch, not HEAD reflog.

VonC
Clarification: You checked out the tag, which points to that particular commit. It does not point to the branch. (It can't - the branch could move!) The branch and tag just happen to be in the same place right now. You checked out the tag, though, so git checked out that commit and detached your HEAD.
Jefromi
@Jefromi: I am still editing the answer, one of the latest edit mentions just your clarification ;)
VonC
Because I checked out to a tag - which could move - and then started changing things, I am on a detached head. A detached head is not a branch, and therefore does not display or update remotely. Got it, though I still don't understand why not [despite your comment on the other thread].I don't understand the merge instructions. I already did the checkout back to master, and know the commit's SHA (see the reflog image). Do I now just reset --hard? If so, to which commit-id.. b88fd04?
SamGoody
@samgoody: no the tags never move, that is the all point of a tags. Branches move (they are just pointer on branch HEAD). In your case, you would indeed reset to commit `b88fd04`, because that would move master HEAD to that commit, effectively making all those commits made on a detached branch part of the master branch.
VonC
+1  A: 

The easiest way to resurrect your commits is to point some branch head to them. You know the SHAs, so it's easy:

git branch resurrected_junk 1b8c11d

(this is a SHA read from your screenshot), could be also

git branch resurrected_junk HEAD@1

This will point a branch to the most recent of your lost commits - the earlier ones are probably parents of the most recent one, so they will be on this new branch; if they aren't (that means there are two "shadow branches" of lost commits), you would have to review all the commits and reiterate the procedure for the commits that are missing.

In your case, I guess you'll get a history like this:

Master --> Optimize toRGB --> ... ---> shortened toRGB = resurrected_junk

Then, refresh your gitk view and the commits should show up. (I'm using qgit, so I'm just guessing)

After that, you should be able to merge/push/whatever yow want them (as you like).

jpalecek
Please be more descriptive - I don't understand. To which commit do I do the resurrected_junk; the earliest of my detached commits, the latest of them, or to all of them? Also, what does that mean "could be also".. if I do git branch resurrected_junk HEAD@1 will I then have everything happily in master where I need it? Will I have to branches that I can then merge together?
SamGoody
The latest commit; "could be also" means HEAD@1 is in your case just a more convenient name for 1b8c11d. It won't put your commits into master, there will be another branch. You'll be able to merge it into master if you want; it should be an easy fast-forward merge in your case.
jpalecek
+1  A: 

In Git commits form a directed acyclic graph where each commit points to one or more parent commits. In addition to the commit objects you also have ref (i.e. reference) objects: branches and tags. They point to various commits in the commit graph. Your problem is that you weren't on a branch when you made the commits and no branch (or tag) points to them. At any time you can use commands

git status

and

git branch

to check whether you are on a branch or not.

Why do they not show on GITK (at least as a branch or something)?

As far as I know Gitk looks for the commit objects starting from the refs. If no ref points to your commits (or the directed acyclic graph of commits that leads to them) they are effectively invisible.

How do I merge them into master?

Fortunately the reflog facility keeps track of operations like checkouts and commits (among other things). In your reflog listing you can see the entry for your last commit:

1b8c11d HEAD@{1} commit: Shortened toRgb() function

You should be able to merge the commits to your master branch by using the SHA1 ID you see in the reflog:

git checkout master
git merge 1b8c11d

I gather this happened when I checked out tag 0.42. Why is that not the same as master? (I had tagged the master in its latest state)

The main difference between branches and tags is that a tag always points to the same commit but a branch moves forward. For example, if you are on branch "master" and make a new commit, the "master" branch moves forward and starts pointing to the new commit you just created. When you checkout commits, tags or branches Git takes your commands quite literally and checks out exactly what you asked for.

When I click push, why does the remote repo claim to be up to date.. shouldn't it try to update these commits into whatever branch they are in?

Your commits aren't on any branch. You first need to merge them to a branch (e.g. to master) as shown above. After this the push should work normally.

kaitanie