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