如何在Git中将提交从主干移动到分支?

Dan*_*nny 16 git branch git-svn git-rebase git-reset

我向主人做了一堆提交,并意识到他们应该在一个分支中.

我已经看过各种关于变基和合并以及重置主人的事情.但是没有任何操纵尝试产生了一个看起来像我正在尝试做的事情的历史.

我的尝试让我相信它需要一些组合rebase --onto并将reset --hard主人及时移回.但是我对Git分支的理解还有待改进.这样做的一部分是学习如何使用它.

应该注意的是,我试图移动的所有变化都没有被推出.

当前

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo
Run Code Online (Sandbox Code Playgroud)

期望的结果

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo
Run Code Online (Sandbox Code Playgroud)

has*_*sen 9

马丁答案的变化不一定适用于你的情况,但我想发布它无论如何:)

假设你忘了在提交时创建分支o,所以你有:

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]
Run Code Online (Sandbox Code Playgroud)

然后你意识到你真正想要的是:

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic
Run Code Online (Sandbox Code Playgroud)

在这种情况下你可以做的是o使用它的哈希创建一个分支:

git branch topic # creates new branch 'topic' - will be at commit `f`
git checkout o -b newmaster # creates new branch called newmaster pointing on commit `o` (please replace `o` with the actual hash)
git branch -M newmaster master # force rename newmaster to master (means master points on hash `o`)
Run Code Online (Sandbox Code Playgroud)

您将在主分支(提交o),所以作为最后一步,您可以:

git checkout topic
Run Code Online (Sandbox Code Playgroud)

哈希当然可以只是前5个字符..

编辑

你正在使用它并不重要git-svn,真正重要的是你之后的任何时候都没有发布你的主分支o

git中的一个分支实际上只是指向提交的指针.这就是分支如此便宜的原因:你只需创建一个指针,然后你就有了一个分支.

我不知道跟踪远程分支,你可能需要在重命名/移动分支后进行设置.


Von*_*onC 6

我不确定重命名分支是正确的解决方案,因为它会让你从:

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo
Run Code Online (Sandbox Code Playgroud)

至:

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk
Run Code Online (Sandbox Code Playgroud)

(如果你重命名remote/foo,这是不可取的:你应该先跟踪它,然后重命名,但即使最终结果与你需要的不同)

这不是你想要的"期望结果"(foo需要从F开始,而不是M):

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo
Run Code Online (Sandbox Code Playgroud)

你只能通过一个实现这一点 rebase --onto

git checkout --track -b origin/foo  # create a local branch named after the remote one
git branch tmp                      # mark current foo HEAD to 'F'
git branch -f foo master            # put foo where it should b: at 'f'
git branch -f master tmp^           # reset master to M, parent of tmp
git checkout tmp                    # go to where we must replay the commits
git rebase --onto tmp master foo    # replay a to f on top of tmp
git svn dcommit                     # push the local foo in order to update remote/foo
Run Code Online (Sandbox Code Playgroud)

给你:

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo
Run Code Online (Sandbox Code Playgroud)