我想将我已经承诺掌握的最后几个提交移动到一个新的分支,然后在完成这些提交之前将主人带回去。不幸的是,我的 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 想要的,它需要两个步骤:
newbranch
上你想要的newbranch
执行
git checkout master
git log
注意在newbranch
上你想要的哈希值(比如说 3)。我将在这里使用:
C commit: 9aa1233
D commit: 453ac3d
E commit: 612ecb3
注意:您可以使用前七个字符或整个提交哈希
newbranch
git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233
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 想要的,它需要两个步骤:
newbranch
上你想要的newbranch
执行
git checkout master
git log
注意在newbranch
上你想要的哈希值(比如说 3)。我将在这里使用:
C commit: 9aa1233
D commit: 453ac3d
E commit: 612ecb3
注意:您可以使用前七个字符或整个提交哈希
newbranch
git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233
git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233
git cherry-pick将这三个提交应用于 newbranch。