删除选择提交并合并或重新绑定并添加重要提交

时间:2016-07-05 22:10:15

标签: git git-rebase git-commit git-revert

所以我正在检查其他solutions,但它并不适合我,我也在处理分支合并

git log
commit 6d034e1b1f03241b2c660312660ce29acca23f60
Author: ME <myfakemail@gmail.com>
Date:   Thu Jun 30 13:09:08 2016 +0100

    text so people click the button

commit b9295485e17ccb6662b688b5c0f796656ef5f0de
Author: Me-again <myfakemail@fakeville.com>
Date:   Wed Jun 29 17:22:33 2016 +0100

    Adding the 4th celebration to index.php

commit 01ab5a9cfcefe34e72f06f52974da96ce1c2980a
Author: Me-again <myfakemail@fakeville.com>
Date:   Wed Jun 29 12:40:37 2016 +0100

    do the status check after all stops have been performed

commit 904bfdfbc4b536d052e61a303a17e6e108b7d9fe
Author: ME <myfakemail@gmail.com>
Date:   Thu Jun 23 15:16:39 2016 +0100

    changing music to StarSpangled

commit 5874707b022fb6039df84372a750c8fc57215af1
Author: ME <myfakemail@gmail.com>
Date:   Thu Jun 23 15:15:30 2016 +0100

    Quintessential american music

commit 175d5e53c43c7175b6478070d5660e7426aeade9
Author: Me-again <myfakemail@fakeville.com>
Date:   Wed Jun 22 13:11:48 2016 +0100

    Adding error logging and messaging for stop and start

commit 630c25055044a44be304353d3d18e385fed091a3
Merge: 7019947 35eb826
Author: Not Me <notme@mail.com>
Date:   Fri Jun 17 16:57:17 2016 +0100
    Quintessential american music

commit 175d5e53c43c7175b6478070d5660e7426aeade9
Author: Me-again <myfakemail@fakeville.com>
Date:   Wed Jun 22 13:11:48 2016 +0100

    Adding error logging and messaging for stop and start

commit 630c25055044a44be304353d3d18e385fed091a3
Merge: 7019947 35eb826
Author: Not Me <notme@mail.com>
Date:   Fri Jun 17 16:57:17 2016 +0100

    Merge branch 'master' of https://github.com/ME/MyProject

commit 7019947ceea28bd80d020e062a003433529c2a5a
Author: Not Me <notme@mail.com>
Date:   Fri Jun 17 16:57:00 2016 +0100

    4th of July draft

commit 35eb826c39f8b8e0fafd51a9cebae68dd434c7eb
Merge: f0a144f 6a6937d
Author: Me-again <myfakemail@fakeville.com>
Date:   Fri Jun 17 16:26:18 2016 +0100

    Merge branch 'master' of https://github.com/ME/MyProject

    Entering the new cast iron  options

基本上我们有这个项目,并决定为我们的美国弟兄们添加一些味道/乐趣。唯一的事情是,虽然我们已准备好上升,但对该项目做了一些严肃的承诺。

现在第四次结束了,我想删除主题内容并恢复正常

我在想我的选择

  • 还原所有第4次相关提交
  • rebase并将两个严重的提交添加回代码

所以我跑了

git revert --no-commit 6d034e1b1f03241b2c660312660ce29acca23f60 b9295485e17ccb6662b688b5c0f796656ef5f0de    904bfdfbc4b536d052e61a303a17e6e108b7d9fe 5874707b022fb6039df84372a750c8fc57215af1 630c25055044a44be304353d3d18e385fed091a3 7019947ceea28bd80d020e062a003433529c2a5a
error: Commit 630c25055044a44be304353d3d18e385fed091a3 is a merge but no -m option was given.

从我所看到的情况来看,它让我处于半恢复状态,只有在暂存区域中删除了这些提交的编辑,但合并中引入的更改仍然存在

我最好还是修改到提交35eb826c39f8b8e0fafd51a9cebae68dd434c7eb 然后添加

  • 01ab5a9cfcefe34e72f06f52974da96ce1c2980a

  • 175d5e53c43c7175b6478070d5660e7426aeade9

对不起咆哮,但如果你git大师处于类似的情况,你会采取什么行动?

1 个答案:

答案 0 :(得分:1)

在这里了解Git:

  • Git总是添加新内容。还原添加了新提交。 rebase添加了新的提交。就此而言,合并会添加新提交。

  • 但是git rebase以一种不同寻常的方式添加了新的提交。它复制现有提交,将它们更改为补丁(或大部分等同于git cherry-pick个动作),然后将补丁应用于不同的早期比以前更晚的起点。

  • 此外,git rebase通常跳过合并提交。以这种方式复制合并提交是不可能的,因此如果您使用--preserve选项(尝试保留合并),git rebase 重新执行合并,而不是试图复制它们。 (如果它起作用的话,它的工作情况通常取决于合并最初的简单程度以及你将新的提交链移动到的位置。

    < / LI>
  • 交互式 rebase允许您选择要复制的提交,以及是否停止和调整副本。这意味着如果你复制一连串的提交,就会遗漏一个&#34; bad&#34;一,你得到一个新的连锁店,永远不会让'#34;坏&#34;更改。它还可以让你&#34;挤压&#34;几个提交到单个提交中,通过应用来自除最后一个提交之外的所有提交的更改而不进行新提交尚未,然后使用最终工作树和提交文本进行新提交来自所有提交(并将您的文本编辑为单个消息)。

  • 一旦rebase完成复制提交,它就会移动分支名称,这样它就不会指向分支的上一个提示,而是指向最常见的复制提交。旧提交仍在您的存储库中,但效果是,就好像它们已被删除,并且分支重绕,然后在您将其复制到的新位置添加新副本。

    这意味着其他任何使用原始提交的人 - 假设您已经发布(通常为git push - )并且其他人拥有原件 - 现在必须采取一些特殊措施来解释您的& #34;复制和倒回并指向副本&#34;效果。

  • 最后,由于Git是围绕这个&#34;添加新东西&#34;模型,如果你总是以最简单的方式添加新的东西 - 包括普通的恢复 - 那么Git周围的每个人和所有东西都可以正常工作而不需要额外的摆弄。

结论:恢复更容易

所以,您可能确实希望恢复,就像您尝试过一样。

在我看来,你的git revert序列中几乎所有事情都是正确的。你做了一件完全可选的事情 - 你选择了--no-commit,这样所有的还原都可以组合成一个大的&#34;撤消一堆东西&#34;提交 - 然后你遇到的问题是恢复合并比恢复&#34;常规&#34; (非合并)提交。

如何恢复工作

恢复合并提交更难的原因与行动机制有关。为了做一个还原,Git本质上是一个&#34;向后差异&#34;而不是比较&#34;之前&#34; vs&#34;在&#34;之后,看看如何将旧版本更改为新版本,Git比较&#34;&#34; vs&#34;之前&#34;,看看如何改回来。

为了实现任一比较,Git需要两个提交ID:&#34;之前&#34;版本和&#34;之后&#34;版。对于普通(非合并)提交,这很容易。提交本身是&#34;在&#34;之后,其父级是&#34;之前的#34;。运行git log --oneline --graph --decorate以直观地查看父/子关系。现在注意普通的非合并提交有一个父级。但是,合并提交有两个(或更多)父项,这意味着git revert不知道哪个被视为&#34;之前&#34;版本

这就是你得到is a merge but no -m option was given错误的原因:提交是一个合并,git revert需要知道哪个更改为撤消,即要比较哪个父。 (你几乎肯定想在这里-m 1。)

因为您使用了--no-commit,所以Git每次都会按照命令行中的指定一次恢复一个,而不提交。它然后点击错误并停止,因此它没有恢复该合并,也没有在命令行上列出任何后续提交。

如果没有--no-commit,Git会每次还原,然后提交还原,当您对-m投诉失败时,会让您处于更明显的状态。

不幸的是,您必须指定-m选项以还原合并提交,并且您不得指定-m选项以还原非合并提交。这意味着您必须使用多个git revert命令。

好消息是,您可以继续使用现有的git revert --no-commit:只需git revert -n -m 1 <the merge>,然后git revert -n每次额外提交(只需再做一次)。完成所有操作后,git commit结果将撤消一个巨型还原中的所有内容。

或者,如果您希望一次还原一件事 - 这样可以更容易地看到您正在做的事情,当您从现在开始回顾这一年时,也会让它更嘈杂(因此也更难)看看你在做什么 - 你可以使用git reset --hard返回最近提交的索引/登台区域和工作树状态:

$ git reset --hard HEAD

当然,假设当你启动整个git revert序列时,所有内容(索引和工作树都是)都是干净的。现在你可以:

$ git revert ...

每次提交,这次没有-n。 (这假设你已经改变了想要进行一次重大逆转的想法。)

我怎么做

请注意,您可以一次还原一个,然后使用git rebase -i将它们全部压缩成一个大的还原。这最终与使用git revert -n完全相同:首先你创建一个由六个单独的恢复链组成的链,然后将(未发布的)链折叠成一个大的恢复,然后你发布(git push)最后一个结果

我可能会这样做,以便我可以验证每个版本是否正常工作,查看具有六个单独提交的版本,稍微思考一下,然后决定未来我是不是喜欢这个或者一个大的-revert,然后rebase-and-push,或者只是推送,基于此。