16

我向 master 提交了一堆代码,然后意识到它们应该在一个分支中。

我看过关于变基、合并和重置主人的各种事情。但是,任何操纵尝试都没有产生像我正在尝试做的那样的历史。

我的尝试使我相信它需要某种组合rebase --onto并将reset --hard主人及时移回。但是我对 Git 分支的理解还有一些不足之处。这样做的一部分是学习如何使用它。

应该注意的是,我试图移动的所有更改都没有被推出。

当前的

  * remote/trunk
--o--a--b--c--d--e--f     <- master
  |
  o                       <- remote branch foo

期望的结果

  * remote/trunk
--o                       <- master
  |
  o--a--b--c--d--e--f     <- remote branch foo
4

3 回答 3

9

马丁答案的变体不一定适用于您的情况,但我还是想发布它:)

假设您忘记在 commit 处创建分支o,那么您有:

x--y--z--o--a--b--c--d--e--f  master
         |
         +
   [forgot to make a branch here]

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

x--y--z--o   master
         |
         +--a--b--c--d--e--f  topic

在这种情况下,您可以做的是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`)

您将位于主分支 (commit o),因此作为最后一步,您可以:

git checkout topic

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

编辑

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

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

不过,我不知道如何跟踪远程分支,您可能需要在重命名/移动分支后进行设置。

于 2010-03-04T02:25:41.170 回答
6

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

  * remote/trunk
--M--a--b--c--d--e--f     <- master
  |
  F                       <- remote branch foo

到:

--F                       <- master
  |
  M--a--b--c--d--e--f     <- remote branch foo
  * remote/trunk

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

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

  * remote/trunk
--M                       <- master
  |
  F--a--b--c--d--e--f     <- remote branch foo

您只能通过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

给你:

  * remote/trunk
--M                             <- master
  |
  F--a'--b'--c'--d'--e'--f'     <- local foo and remote branch foo
于 2010-03-04T05:23:21.427 回答
1

几乎正确了 hasen j 的建议,但我不得不做一些小的修改(我使用 git-svn):

# create the branch with your commits
git branch performance
# fork the master to a new branch at the commit before your local, non pushed commits
git branch newmaster 2d0516dfe8252de87
# checkout your branch 
git checkout performance
# rename the newmaster
git branch -M newmaster master
# now checkout the master
git checkout master

你不能重命名你所在的分支,所以我检查了我移动提交的性能分支。

于 2011-12-01T15:17:52.057 回答