Re: Help rescuing a repository
- From
- Luke Lu <git@vicaya.com>
- Date
- Jun 11, 2008, 05:04 UTC
- Message-ID
- <025E3DB6-D0A8-497E-A5EF-9B4011FA3272@vicaya.com>
- In-Reply-To
- <alpine.LFD.1.10.0806101848320.3101@woody.linux-foundation.org>
On Jun 10, 2008, at 7:08 PM, Linus Torvalds wrote:
Show 23 quoted lines
> > 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?
Show 23 quoted lines
>> 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.
Show 62 quoted lines
> 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