协慌网

登录 贡献 社区

使用 Git 将最近的提交移动到新分支

我想将我已经承诺掌握的最后几个提交移动到一个新的分支,然后在完成这些提交之前将主人带回去。不幸的是,我的 Git-fu 还不够强大,有什么帮助吗?

即我怎么能从这里走出来

master A - B - C - D - E

这个?

newbranch     C - D - E
             /
master A - B

答案

搬到新的分支机构

警告:此方法有效,因为您使用第一个命令创建一个新分支: git branch newbranch 。如果要将提交移动到现有分支 ,则需要在执行git reset --hard HEAD~3之前将更改合并到现有分支中git reset --hard HEAD~3 (请参阅下面的移动到现有分支 )。 如果您不先合并更改,它们将会丢失。

除非涉及其他情况,否则可以通过分支和回滚轻松完成。

# Note: Any changes not committed will be lost.
git branch newbranch      # Create a new branch, saving the desired commits
git reset --hard HEAD~3   # Move master back by 3 commits (GONE from master)
git checkout newbranch    # Go to the new branch that still has the desired commits

但要确保要返回多少次提交。或者,您可以代替HEAD~3 ,只需提供要在 (/ current)分支上 “恢复” 的提交(或者像origin / master这样的引用)的哈希,例如:

git reset --hard a1b2c3d4

* 1 您只会从主分支 “丢失” 提交,但不要担心,您将在 newbranch 中进行这些提交!

警告:使用 Git 2.0 及更高版本,如果您稍后在原始( master )分支上重新git rebase新分支,则在 rebase 期间可能需要显式的--no-fork-point选项以避免丢失结转提交。 branch.autosetuprebase always设置branch.autosetuprebase always使这更有可能。有关详细信息,请参阅John Mellor 的答案

转移到现有分支

如果要将提交移动到现有分支 ,它将如下所示:

git checkout existingbranch
git merge master
git checkout master
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch

对于那些想知道它为什么起作用的人(就像我一开始):

您想要返回到 C,并将 D 和 E 移动到新分支。这是它最初的样子:

A-B-C-D-E (HEAD)
        ↑
      master

git branch newBranch

newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

git reset --hard HEAD~2

newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

由于分支只是一个指针,因此master指向最后一次提交。当你创建newBranch 时 ,你只需要创建一个指向最后一次提交的新指针。然后使用git reset指针移回两次提交。但是既然你没有移动newBranch ,它仍然指向它最初的提交。

一般来说...

在这种情况下,sykora 公开的方法是最佳选择。但有时并不是最容易的,也不是一般的方法。对于一般方法,使用git cherry-pick

要实现 OP 想要的,它需要两个步骤:

第 1 步 - 注意在newbranch上你想要的newbranch

执行

git checkout master
git log

注意在newbranch上你想要的哈希值(比如说 3)。我将在这里使用:
C commit: 9aa1233
D commit: 453ac3d
E commit: 612ecb3

注意:您可以使用前七个字符或整个提交哈希

第 2 步 - 将它们放在newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

或(在 Git 1.7.2 + 上,使用范围)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git cherry-pick将这三个提交应用于 newbranch。

搬到新的分支机构

警告:此方法有效,因为您使用第一个命令创建一个新分支: git branch newbranch 。如果要将提交移动到现有分支 ,则需要在执行git reset --hard HEAD~3之前将更改合并到现有分支中git reset --hard HEAD~3 (请参阅下面的移动到现有分支 )。 如果您不先合并更改,它们将会丢失。

除非涉及其他情况,否则可以通过分支和回滚轻松完成。

# Note: Any changes not committed will be lost.
git branch newbranch      # Create a new branch, saving the desired commits
git reset --hard HEAD~3   # Move master back by 3 commits (GONE from master)
git checkout newbranch    # Go to the new branch that still has the desired commits

但要确保要返回多少次提交。或者,您可以代替HEAD~3 ,只需提供要在 (/ current)分支上 “恢复” 的提交(或者像origin / master这样的引用)的哈希,例如:

git reset --hard a1b2c3d4

* 1 您只会从主分支 “丢失” 提交,但不要担心,您将在 newbranch 中进行这些提交!

警告:使用 Git 2.0 及更高版本,如果您稍后在原始( master )分支上重新git rebase新分支,则在 rebase 期间可能需要显式的--no-fork-point选项以避免丢失结转提交。 branch.autosetuprebase always设置branch.autosetuprebase always使这更有可能。有关详细信息,请参阅John Mellor 的答案

转移到现有分支

如果要将提交移动到现有分支 ,它将如下所示:

git checkout existingbranch
git merge master
git checkout master
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch

对于那些想知道它为什么起作用的人(就像我一开始):

您想要返回到 C,并将 D 和 E 移动到新分支。这是它最初的样子:

A-B-C-D-E (HEAD)
        ↑
      master

git branch newBranch

newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

git reset --hard HEAD~2

newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

由于分支只是一个指针,因此master指向最后一次提交。当你创建newBranch 时 ,你只需要创建一个指向最后一次提交的新指针。然后使用git reset指针移回两次提交。但是既然你没有移动newBranch ,它仍然指向它最初的提交。

一般来说...

在这种情况下,sykora 公开的方法是最佳选择。但有时并不是最容易的,也不是一般的方法。对于一般方法,使用git cherry-pick

要实现 OP 想要的,它需要两个步骤:

第 1 步 - 注意在newbranch上你想要的newbranch

执行

git checkout master
git log

注意在newbranch上你想要的哈希值(比如说 3)。我将在这里使用:
C commit: 9aa1233
D commit: 453ac3d
E commit: 612ecb3

注意:您可以使用前七个字符或整个提交哈希

第 2 步 - 将它们放在newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

或(在 Git 1.7.2 + 上,使用范围)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git cherry-pick将这三个提交应用于 newbranch。