我刚刚向错误的分支做出了完美的承诺。 我如何撤消在我的主分支中的最后一次提交,然后采取这些相同的更改,并将它们放入我的升级分支?


当前回答

在常见的情况下,你在提交之前忘记从master切换到你的特性分支:

git checkout -B feature
git branch -f master origin/master

将origin/master替换为您希望主分支指向的提交。例如,如果您希望它指向HEAD后面的3个提交,则使用HEAD~3,如果您希望它指向带有该哈希的提交,则使用a1b2c3d。

其思想是在当前提交上重新创建特性分支并切换到它。然后使master分支指向与origin/master相同的提交。

一般情况下

在一般情况下,你想在你的特性分支上重放在master上完成的提交,如下图所示:

A---B---C---D  $old_master                   A---B---C---D  master
    |        \                                   |        \
    |         G---H---I  master <- HEAD  =>      |         G---H---I
    |                                            | 
    `-E---F  feature                             `-E---F---G'--H'--I' feature <- HEAD

然后使用下面的命令在你的特性分支上选择你在master上做的提交。将$old_master替换为提交主机在进行更改之前所指向的哈希值。

git checkout feature
git cherry-pick $old_master..master
git branch -f master $old_master

如果需要,使用git stash -include-untracked隐藏你的本地更改,然后使用git stash pop取消隐藏。

不重写历史

除了选择特性分支上的更改之外,您还需要git恢复这些更改,而不是将主分支重置到过去。

git checkout feature
git cherry-pick $old_master..master
git checkout master
git revert $old_master..
git checkout feature

确保git不会将你的提交合并到特性中。如果你试图将你的特征分支合并回主分支,这些变化将被忽略,因为我们刚刚恢复了它们。

下面是结果的样子,rG, rH和rI分别是G, H和I的还原提交:

A---B---C---D             rG--rH--rI  master
    |        \           /
    |         G---H---I-`
    | 
    `-E---F---G'--H'--I' feature <- HEAD

其他回答

在常见的情况下,你在提交之前忘记从master切换到你的特性分支:

git checkout -B feature
git branch -f master origin/master

将origin/master替换为您希望主分支指向的提交。例如,如果您希望它指向HEAD后面的3个提交,则使用HEAD~3,如果您希望它指向带有该哈希的提交,则使用a1b2c3d。

其思想是在当前提交上重新创建特性分支并切换到它。然后使master分支指向与origin/master相同的提交。

一般情况下

在一般情况下,你想在你的特性分支上重放在master上完成的提交,如下图所示:

A---B---C---D  $old_master                   A---B---C---D  master
    |        \                                   |        \
    |         G---H---I  master <- HEAD  =>      |         G---H---I
    |                                            | 
    `-E---F  feature                             `-E---F---G'--H'--I' feature <- HEAD

然后使用下面的命令在你的特性分支上选择你在master上做的提交。将$old_master替换为提交主机在进行更改之前所指向的哈希值。

git checkout feature
git cherry-pick $old_master..master
git branch -f master $old_master

如果需要,使用git stash -include-untracked隐藏你的本地更改,然后使用git stash pop取消隐藏。

不重写历史

除了选择特性分支上的更改之外,您还需要git恢复这些更改,而不是将主分支重置到过去。

git checkout feature
git cherry-pick $old_master..master
git checkout master
git revert $old_master..
git checkout feature

确保git不会将你的提交合并到特性中。如果你试图将你的特征分支合并回主分支,这些变化将被忽略,因为我们刚刚恢复了它们。

下面是结果的样子,rG, rH和rI分别是G, H和I的还原提交:

A---B---C---D             rG--rH--rI  master
    |        \           /
    |         G---H---I-`
    | 
    `-E---F---G'--H'--I' feature <- HEAD

保留更改并取消提交 简单的解决方案是运行该命令。

git reset HEAD^

这将取消提交代码,同时保留您的更改

如果您已经执行了更改,则需要在重置HEAD后强制执行下一次推送。

git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force

警告:硬重置将撤销工作副本中任何未提交的修改,而强制推将完全覆盖远程分支的状态与本地分支的当前状态。

以防万一,在Windows上(使用Windows命令行,而不是Bash),它实际上是四个^^^^而不是一个,所以它是

git reset --hard HEAD^^^^

因此,如果你的场景是你已经提交给master,但打算提交给另一个分支(可能不存在,也可能不存在),但你还没有推送,这很容易修复。

// if your branch doesn't exist, then add the -b argument 
git checkout -b another-branch
git branch --force master origin/master

现在你对master的所有提交都将在另一个分支上。

来自:http://haacked.com/archive/2015/06/29/git-migrate/

对我来说,这个问题的解决方法是恢复我之前推送的提交,然后将该提交选择到另一个分支。

git checkout branch_that_had_the_commit_originally
git revert COMMIT-HASH
git checkout branch_that_was_supposed_to_have_the_commit
git cherry pick COMMIT-HASH

您可以使用git log来找到正确的散列,并且您可以随时推送这些更改!