简体   繁体   中英

How to Checkout Specific Commit During Git Rebase

I'm in the middle of a git rebase. The branch off of which I am rebasing has a lot of changes involving the same code that I modified. I spent a lot of time working on the rebase, and I am almost finished. But I added a new feature at the commit that I'm working on right now, and that feature does not work anymore. I wrote this feature similarly to an existing feature, and I can see that the existing feature's functionality was changed by the code off of which I am rebasing.

I want to find the commit where the existing feature's functionality was changed. I wanted to start by checking out the last commit before I began to write my code the first time around, to make sure that the existing feature was actually changed. But when I try checking out a different commit, I get an error telling me that I need to merge files from the current step in my merge, and that I need to resolve my current index first. But I can't resolve my current index until I figure out how the existing feature was modified. What do I do?

The two comments you have (so far at least) are the keys to moving forward here.

Background

A paused (for any reason, including interactive rebase "edit" option) rebase has the work-tree in the detached HEAD mode. This is a slightly delicate state, and it's unwise to disturb the HEAD setting here (which git checkout of some other branch or commit will do).

A rebase that has paused due to a merge conflict is even worse: it not only has the detached HEAD mode going on, it has the index in conflicted state. Since the index is crucial to committing, the only thing you can do with this work-tree is either fix the conflict and continue, or terminate the rebase and put everything back the way you started.

You do not want to do these: you want to finish up the rebase, because:

I spent a lot of time working on the rebase, and I am almost finished.

The solution, then, is to get a different work-tree.

Get another work-tree

In modern Git (since Git version 2.5), there is a command, git worktree , with sub-commands to create a new work-tree. Each work-tree comes with its own HEAD and its own index. This means you can leave your existing repository in place, intact, with the ongoing rebase and its detached HEAD and perhaps-conflicted index, and just add a new work-tree that has the other branch checked out.

There have been a number of bugs found in git worktree since its 2.5 release; I'd avoid using it too heavily until about Git 2.15 or so when this rather nasty bug was fixed. 1 For just looking at a different branch, even the Git 2.5 version is fine, though.

If your Git predates 2.5, or you are nervous about the above bug, you can simply clone your existing repository. Clones take a little bit more disk space and time to make than added work-trees, but not a lot more, and they work in every version of Git.


1 I was bitten by this very bug myself. It's worth noting, though, that it is harmless if your objects (the ones that git gc might think are unreferenced) are younger than the prune expiration time, which is 14 days by default. Short-lived side worktrees will tend not to trigger these git worktree bugs (this one and a number of others fixed between 2.5 and 2.15).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM