Git: How to rebase to a specific commit?

2019-01-21 01:14发布

I'd like to rebase to a specific commit, not to a HEAD of the other branch:

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

to

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

instead of

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

How can I achieve that?

8条回答
小情绪 Triste *
2楼-- · 2019-01-21 01:53

I've used a mixture of solutions described above:

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

I found it much easier to read and understand. The accepted solution lead me to a merge conflict (too lazy to fix by hand):

$ 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".
查看更多
霸刀☆藐视天下
3楼-- · 2019-01-21 01:54

A simpler solution is git rebase <SHA1 of B> topic. This works irrespective of where your HEAD is.

We can confirm this behaviour from git rebase doc

<upstream> Upstream branch to compare against. May be any valid commit, not just an existing branch name. Defaults to the configured upstream for the current branch.


You might be thinking what will happen if I mention SHA1 of topic too in the above command ?

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

My little experiment shows that the command will execute but instead it will rebase a copy of topic branch there instead of rebasing topic branch. In short it does not work as we were expecting it to work. Hence don't use like this.

查看更多
神经病院院长
4楼-- · 2019-01-21 01:57

You can even take a direct approach:

git checkout topic
git rebase <commitB>
查看更多
三岁会撩人
5楼-- · 2019-01-21 01:57

The comment by jsz above saved me tons of pain, so here's a step-by-step recipie based on it that I've been using to rebase/move any commit on top of any other commit:

  1. Find a previous branching point of the branch to be rebased (moved) - call it old parent. In the example above that's A
  2. Find commit on top of which you want to move the branch to - call it new parent. In the exampe that's B
  3. You need to be on your branch (the one you move):
  4. Apply your rebase: git rebase --onto <new parent> <old parent>

In the example above that's as simple as:

   git checkout topic
   git rebase --onto B A
查看更多
我想做一个坏孩纸
6楼-- · 2019-01-21 01:57

There is another way of doing it or if you wish to move back to more than just one commit.

Here is a an example to move back to n number of commits:

git branch topic master~n

For the sake of this question, this can also be done:

git branch topic master~1

The command works perfectly on git version 2.7.4. Haven't tested it on any other version.

查看更多
可以哭但决不认输i
7楼-- · 2019-01-21 02:01

You can avoid using the --onto parameter by making a temp branch on the commit you like and then use rebase in it's simple form:

git branch temp master^
git checkout topic
git rebase temp
git branch -d temp
查看更多
登录 后发表回答