Re: Help rescuing a repository

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Jun 10, 2008, at 7:08 PM, Linus Torvalds wrote:

On Tue, 10 Jun 2008, Luke Lu wrote:

I was doing some git rebase -i in a topic branch (topic/ser) to squash and reorder some commits. There were some conflicts. I fixed the conflicts and typed git rebase --continue. The cycle continued a few times and then this
happened:

13 files changed, 68 insertions(+), 41 deletions(-)
error: Ref refs/heads/topic/ser is at 5cfb6b694f2d5a1ff429fe86f6c5ecafed159e47
but expected a10a7127be3441c732cab5baa2dd8684591f91f7
fatal: Cannot lock the ref 'refs/heads/topic/ser'.

Ok, you seem to have committed something in another session (other window
or something) at the same time as doing that git rebase series. As a
result, the rebasing commit was unhappy, because you basically ripped the
rug out from under it by changing the branch it was working on.

So you've seen this problem before?

I *might* have committed something in the same branch, while the git
rebase -i editor window is open (there are a lot of commits to reorder and squash, so I used another window to look at the commits I'm not sure
about. I might have done a quick fix (likely whitespace errors :) and
committed)

Yup, that would explain it.

I have the gut feeling that it might be fixable by some magical incantation to connect the refs to my branch. But I don't know git internal very well. I need
your help. My work obviously depend upon it.

Most likely, the only thing you actually need to do is simply

	git rebase --abort

and it will just take you back to the state you were in before the rebase,
and now you'll have to redo it all.

Before I thought of that, I just used the trusted git reflog to find the last commit I made before the rebase commits and did a git reset -- hard to that commit. It returned the tree to normal. Fortunately I have rerere enabled (by creating the .git/rr-cache directory, because I read your and Junio's posts on kernel trap). so I don't have to do much work to reedit the conflicts.

BUT. You can also decide that instead of doing that, you want to keep the work you did do, and just try to continue. You'll just need to figure out
where you are, and where the rest of the commits you want to do are.

And those things should not be so hard to figure out, at least if you
still have a reasonably good idea about what the commits were that you
cared about. You just need to find all the relevant development tips, and
it turns out that that is actually mostly pretty easy.

You have one right there: the current disconnected HEAD you are on is one tip. You can save that one away by making that a real branch, so you don't
lose it, with something like

	git branch middle-of-rebase

which will just take your current state, and make it the new branch
'middle-of-rebase'.

You can also try to get a better view of where you are by doing

	gitk --all

to show all the branches graphically, which is usually a great way to get your bearings. Keep the gitk window open in the background as a reference.

After that, do

	git log -g

wher the "-g" (or "--walk-reflogs" for the long version) just means that
instead of looking through history as a chain of commits and their
parents, you look through not the chain of commits, but as the chain of reflog entries (which are basically about how the HEAD has changed due to
the commands you have done).

In all of that info, look for the place you want to go back to, and just start all over from there. You can either re-use one of your old branches
and just start over from some state that you want:

	git checkout <branch>
	git reset --hard <startingpoint>

or you can decide that you want to start a new branch to fix up the mess

	git checkout -b <newbranch> <startingpoint>

and only when it's all fixed up and you're happy will you change any of
your old branches.

I'm still not sure how to fixed it up and keep the merge results though. Just work on the tree (middle-of-rebase, which is actually the end of rebase, when it blowed up) until it's good and reset --hard my branch to it?

But it may well be that "git rebase --abort" and re-doing everything is
the least confusing option.


git rebase --abort, I think, would actually blow away my last commit (I sneaked in) though. git reset --hard to that last commit is probably the right thing to do. The least confusing option would be to update the error message to be a bit more informative, like "Did you change the branch while rebasing? git reset --hard to your last known commit and redo the rebase". Yet another safeguard would be for git commit to check if there is a rebase in progress and warn or abort the commit.

Anyway, thanks for the informative reply. I have more confidence in git due to this accident :)

__Luke

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux