我想要重基到一个特定的提交,而不是另一个分支的HEAD:

A --- B --- C          master
 \
  \-- D                topic

to

A --- B --- C          master
       \
        \-- D          topic

而不是

A --- B --- C          master
             \
              \-- D    topic

我怎样才能做到呢?


当前回答

我使用了上述解决方案的混合:

$ git branch temp <specific sha1>
$ git rebase --onto temp master topic
$ git branch -d temp

我发现它更容易阅读和理解。接受的解决方案导致我的合并冲突(懒得手动修复):

$ git rebase temp
First, rewinding head to replay your work on top of it...
Applying: <git comment>
Using index info to reconstruct a base tree...
M       pom.xml
.git/rebase-apply/patch:10: trailing whitespace.
    <some code>
.git/rebase-apply/patch:17: trailing whitespace.
        <some other code>
warning: 2 lines add whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging pom.xml
CONFLICT (content): Merge conflict in pom.xml
error: Failed to merge in the changes.
Patch failed at 0001 <git comment>
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

其他回答

上面jsz的注释为我节省了大量的痛苦,所以这里有一个基于它的逐步接收人,我一直在使用它来将任何提交重置/移动到任何其他提交之上:

找到要重基(移动)的分支的先前分支点-称其为旧父结点。在上面的例子中是A 找到你想要移动的分支的上面的提交-称为新父。在这个例子中是B 你需要在你的分支上(你移动的那个分支): 应用你的rebase: git rebase—到<new parent> <old parent>

在上面的例子中,这很简单:

   git checkout topic
   git rebase --onto B A

既然调整基地是如此重要,下面是内斯特·米利耶夫(Nestor Milyaev)答案的扩展。结合jsz和Adam Dymitruk回答中的Simon South的评论,得到了这个命令,无论它是从主分支的提交A还是C中分支,它都可以在topic分支上工作:

git checkout topic
git rebase --onto <commit-B> <pre-rebase-A-or-post-rebase-C-or-base-branch-name>

注意,最后一个参数是必需的(否则它会倒带分支以提交B)。

例子:

# if topic branches from master commit A:
git checkout topic
git rebase --onto <commit-B> <commit-A>
# if topic branches from master commit C:
git checkout topic
git rebase --onto <commit-B> <commit-C>
# regardless of whether topic branches from master commit A or C:
git checkout topic
git rebase --onto <commit-B> master

最后一个命令是我通常使用的命令。

一个更简单的解决方案是git rebase <SHA1 of B> topic。不管你的头在哪里,这都是有效的。

我们可以从git rebase文档中确认这种行为

<upstream>要比较的上游分支。可能是任何有效的 提交,而不仅仅是一个现有的分支名称。默认为配置的 当前分支的上游。

你可能会想,如果我在上面的命令中也提到topic的SHA1会发生什么?

git rebase <SHA1 of B> <SHA1 from topic>

这也可以工作,但rebase不会使Topic指向这样创建的新分支,HEAD将处于分离状态。因此,从这里开始,您必须手动删除旧的Topic,并在rebase创建的新分支上创建一个新的分支引用。

如果您希望返回到不止一次提交,还有另一种方法。

下面是一个返回到n次提交的例子:

git branch topic master~n

为了解决这个问题,还可以这样做:

git branch topic master~1

该命令在git 2.7.4版本上运行良好。还没在其他版本上测试过。

你甚至可以采取直接的方法:

git checkout topic
git rebase <commitB>