git revert <commit_hash>
一个人是行不通的。-m
必须指定,对此我感到很困惑。
有人经历过吗?
git
与git-flow
每个人都使用的-ish工作流程不匹配的示例。如果您已develop
签出,则当然要还原引入错误的2提交功能分支,而不是恢复多年的共享dev分支。觉得需要选择它很荒谬-m 1
。
git revert <commit_hash>
一个人是行不通的。-m
必须指定,对此我感到很困惑。
有人经历过吗?
git
与git-flow
每个人都使用的-ish工作流程不匹配的示例。如果您已develop
签出,则当然要还原引入错误的2提交功能分支,而不是恢复多年的共享dev分支。觉得需要选择它很荒谬-m 1
。
Answers:
该-m
选项指定父编号。这是因为合并提交具有多个父项,而Git不自动知道哪个父项是主线,哪个父项是要取消合并的分支。
当您在的输出中查看合并提交时git log
,您会看到其父行以以下行列出Merge
:
commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <ben@example.com>
Date: Wed Aug 17 22:49:41 2011 +0100
Merge branch 'gh-pages'
Conflicts:
README
在这种情况下,git revert 8f937c6 -m 1
将使您的树恢复原状8989ee0
,并git revert -m 2
恢复树的状态7c6b236
。
为了更好地了解父ID,可以运行:
git log 8989ee0
和
git log 7c6b236
8989ee0
,7c6b236
其中一个去。我将如何理解?
git log 8989ee0
和git log 7c6b236
,则应该知道答案。
这是一个完整的示例,希望对您有所帮助:
git revert -m 1 <commit-hash>
git push -u origin master
<commit-hash>
您想还原的合并的提交哈希值在哪里,并且如该答案的说明所述,-m 1
表明您想还原到合并之前的第一个父级的树。
该git revert ...
行实质上是提交更改的内容,而第二行是通过将更改推送到远程分支来公开更改的。
git revert
命令已经提交了创建的提交对象。为此,您必须输入--no-commit
标志
Ben告诉过您如何还原合并提交,但您务必要意识到这样做非常重要
“ ... 声明您将永远不希望合并带来的树更改。因此,以后的合并将仅带来不是先前还原的合并的祖先的提交所引起的树更改。这可能是,也可能不是您想要什么。 ” (git-merge手册页)。
从手册页链接的文章/邮件列表消息详细介绍了所涉及的机制和注意事项。只要确保您了解,如果您还原合并提交,就不能再稍后再次合并分支并期望返回相同的更改。
您可以按照以下步骤还原不正确的提交或将远程分支重置回正确的HEAD /状态。
git checkout development
从git log复制提交哈希(即错误提交之前的提交ID)
git log -n5
输出:
提交7cd42475d6f95f5896b6f02e902efab0b70e8038“将分支'wrong-commit'合并到'开发'”中
提交f9a734f8f44b0b37ccea769b9a2fd774c0f0c012“这是错误的提交”
commit 3779ab50e72908da92d2cfcd72446d
将分支重置为上一步中复制的提交哈希
git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
git status
以显示属于错误提交的所有更改。git reset --hard
即可还原所有这些更改。git push -f origin development
为了保持日志干净无事(这种方法有一些缺点(由于推-f)):
git checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>
“ commit-hash-before-merge”来自合并后的日志(git日志)。
push -f
一个共享的回购
有时,最有效的回滚方法是退回并替换。
git log
使用第二次提交哈希(完整哈希,要在列出错误之前将其还原回的哈希),然后从那里重新分支。
git checkout -b newbranch <HASH>
然后删除旧分支,将新分支复制到其位置,然后从那里重新启动。
git branch -D oldbranch
git checkout -b oldbranch newbranch
如果已广播,则从所有存储库中删除旧分支,将重做分支推到最中央,然后再拉回所有分支。
如果要还原merge
提交,这是您必须要做的。
git log
以查找您的合并提交的ID。您还将找到与合并关联的多个父ID(请参见下图)。记下以黄色显示的合并提交ID。父ID是在下一行写为的ID Merge: parent1 parent2
。现在...
短篇故事:
git revert <merge commit id> -m 1
这将打开一个vi
用于输入提交消息的控制台。编写,保存,退出,完成!很长的故事:
切换到进行合并的分支。就我而言,它是test
分支,而我正尝试从中删除该feature/analytics-v3
分支。
git revert
是用于还原所有提交的命令。但是在还原merge
提交时有一个讨厌的把戏。您需要输入-m
标志,否则它将失败。从这里开始,您需要确定是否要还原分支,并使其看起来像是完全打开parent1
或parent2
通过它:
git revert <merge commit id> -m 1
(恢复为parent2
)
git revert <merge commit id> -m 2
(恢复为parent1
)
您可以git登录这些父母,以确定您想走哪条路,这是所有困惑的根源。
所有的答案已经涵盖了大部分内容,但是我会加5美分。简而言之,还原合并提交非常简单:
git revert -m 1 <commit-hash>
如果您有权限,则可以将其直接推送到“ master”分支,否则只需将其推送到“ revert”分支并创建提取请求。
您可能会在这里找到关于此主题的更多有用信息:https : //itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html
我发现在两个已知的端点之间创建一个反向补丁并应用该补丁是可行的。假设您已经从master分支甚至是master分支的备份(master_bk_01012017)创建了快照(标签)。
假设您合并到master中的代码分支是mycodebranch。
git diff --binary master..master_bk_01012017 > ~/myrevert.patch
git apply --check myrevert.patch
git am --signoff < myrevert.patch
git branch mycodebranch_fix
git checkout mycodebranch_fix
git revert [SHA]
正确标记的答案对我有用,但是我不得不花一些时间来确定发生了什么。
比方说,我们得到了分支机构A和B ..您合并一个分支到分支B和推分支B将因此现在的合并是其中的一部分。但要回到上次提交前合并。什么做你做?
git log
您将看到最近提交的历史记录-提交具有commit / author / date属性,而合并也具有merge属性-因此您将看到如下所示:
commit: <commitHash>
Merge: <parentHashA> <parentHashB>
Author: <author>
Date: <date>
使用git log <parentHashA>
和git log <parentHashB>
-您将看到那些父分支的提交历史-列表中的第一个提交是最新的
<commitHash>
你想要的承诺,去你的git的根文件夹和使用git checkout -b <newBranchName> <commitHash>
-这将创造一个新的分支从去年开始提交你所选择的合并之前..瞧,准备好了!有关git revert -m的git doc提供了一个确切解释此链接的链接:https : //github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt
我在PR上也遇到了这个问题,该PR已合并到GitHub存储库的master分支中。
因为我只是想修改一些修改过的文件,但不是全部的变化PR带来的,我不得不amend
在merge commit
与git commit --am
。
脚步:
git add *
或git add <file>
git commit --am
并验证git push -f
为什么有趣:
我从此链接中找到了有关如何还原合并的很好的解释,并复制并粘贴了下面的解释,以防万一下面的链接不起作用。
如何恢复错误的合并 Alan(alan@clueserver.org)说:
我有一个总公司。我们从一些开发人员正在从事的工作中得到了一个分支。他们声称已经准备好了。我们将其合并到master分支中。它破坏了某些内容,因此我们还原了合并。他们对代码进行更改。他们说到可以了,我们又合并了。在检查时,我们发现在还原之前进行的代码更改不在master分支中,但是在更改之后的代码更改在master分支中。并寻求帮助以从这种情况中恢复过来。
“合并还原”之后的历史记录如下所示:
---o---o---o---M---x---x---W
/
---A---B
其中A和B的关系不太好,M是使这些过早的更改进入主线的合并,x是与支行所做的和主线已经进行的更改无关的更改,W是“还原合并M”(W看起来M倒置吗?)。IOW,“ diff W ^ .. W”类似于“ diff -RM ^ .. M”。
可以通过以下方式进行合并的“还原”:
$ git revert -m 1 M 分支分支的开发人员修复了错误之后,历史记录可能如下所示:
---o---o---o---M---x---x---W---x
/
---A---B-------------------C---D
C和D用于修复A和B中的损坏,并且W之后,您可能已经在主线上进行了一些其他更改。
如果合并更新的边分支(在其顶端带有D),则对A或B所做的任何更改都不会出现在结果中,因为它们已由W恢复。这就是Alan看到的。
Linus解释了这种情况:
恢复常规提交只会有效地撤消该提交所做的操作,并且非常简单。但是,还原合并提交也会撤消提交更改的数据,但是对合并所产生的历史记录的影响绝对没有任何作用。因此,合并仍将存在,并且仍将其视为将两个分支合并在一起,并且将来的合并将把合并视为最后一个共享状态-还原引入的合并的还原将完全不影响此状态。因此,“还原”撤消了数据更改,但实际上不是从某种意义上说是“撤消”,它不会撤消提交对存储库历史记录的影响。因此,如果您将“还原”视为“撤消”,那么您将总是会错过这部分还原。是的,它撤消数据,但是不,它不会撤消历史记录。在这种情况下,您需要首先还原以前的还原,这将使历史记录如下所示:
---o---o---o---M---x---x---W---x---Y
/
---A---B-------------------C---D
其中Y是W的还原。可以通过以下方式完成“还原的还原”:
$ git revert W 此历史记录(忽略W和W..Y更改之间的可能冲突)等同于历史记录中根本没有W或Y:
---o---o---o---M---x---x-------x----
/
---A---B-------------------C---D
并且再次合并侧分支将不会因较早的还原和还原的还原而引起冲突。
---o---o---o---M---x---x-------x-------*
/ /
---A---B-------------------C---D
当然,在C和D中所做的更改仍然可能与任何x所做的冲突,但这只是正常的合并冲突。
正如瑞安(Ryan)所言,这git revert
可能会使合并变得很困难,所以git revert
可能不是您想要的。我发现git reset --hard <commit-hash-prior-to-merge>
在这里使用命令更有用。
一旦你已经完成了艰难的复位部分,然后你可以强制推到远程分支,即git push -f <remote-name> <remote-branch-name>
,在<remote-name>
通常命名origin
。从那时起,您可以根据需要重新合并。