使用filter-branch更改作者姓名后,Git提交重复

时间:2014-11-20 20:51:19

标签: git svn github version-control

我们接受了来自用户的拉取请求,其中作者姓名中的字符导致某些git工具出现问题。为了解决这个问题,我们按照此处的说明修改了提交历史记录: https://help.github.com/articles/changing-author-info/

现在我们的大多数提交都是重复的: https://github.com/CreateJS/EaselJS/commits/master/

我找到了潜在的解决方案,例如: git filter-branch duplicated commits

但是,我没有看到另一个分支,只是重复提交,在我们发现之前我又做了一次提交。我想确定我们不要把这更糟糕。任何帮助表示赞赏

1 个答案:

答案 0 :(得分:2)

从github的直接链接不清楚,但我克隆了回购,这使得它更加明显:

  • 您按照说明执行了filter-branch。这提出了一大堆新的提交。

  • 但是你(看起来像你)将旧的提交链与 new 提交链合并(另外还有一个提交,“Ticker clean) up和bug修复“),而不是强制覆盖旧存储库以丢弃所有旧提交。

如果按日期查看它们,这会使所有提交都重复(因为它们位于合并两个链的点之下)。

如果按图形拓扑顺序查看它们,您可以更容易地看到它是如何产生的(注意,这是在右侧截断以适合窗口):

*   f721f0c (HEAD, origin/master, origin/HEAD, master) Merge branch 'master' of 
|\  
| * 97ffb07 Documentation updates.
| * 3e777f2 Update docs and VERSIONS.
| * 1f32407 Swapped append/prepend naming.
| * dadd1c9 Fixed example in Graphics.append() docs.
| :
| :      [massive snippage, graph modified to show connections]
| :
| *   d0d7f36 Merge pull request #165 from julianklotz/master
| |\  
| | * e980526 Fix documentation Bug: CSS font attribute
| |/  
* | 4c4fe1a Ticker clean up and bug fixes.
* | 6738d23 Documentation updates.
* | 4fe4e97 Update docs and VERSIONS.
* | c17aa05 Swapped append/prepend naming.
* | 36dadb6 Fixed example in Graphics.append() docs.
: |
: |     [more snippage]
: |
* | 0960c56 Added Touch.disable() method. Fixed a very rare issue where Touch co
* |   c20ae9d Merge pull request #165 from julianklotz/master
|\ \  
| |/  
|/|   
| * 26eb5dd Fix documentation Bug: CSS font attribute
|/  
* a21f210 Added SpriteSheetBuilder demo with MovieClip source.
* 20d5dc7 Improvements to resolving mouse position on stage. Should now support 
:      [yet more snippage]

您需要记住的是,filter-branch与git中的所有内容一样,不会更改任何现有提交,只有添加新提交。当过滤器进行一些更改时,filter-branch脚本会生成与旧提交类似的(不同)提交,但应用了此更改。因此a21f210及以下版本未更改,但26eb5dde980526不同:它们具有相同的树和相同的父ID(a21f210),但不同的提交消息文本:1以换行结束,另一个不换行。

一旦某些提交不同,该提交的每个后代 - 每次提交“在图表之后”,即该提交的每个子项 - 必须不同,因为每个提交包含其父项的ID,作为其自己的ID的一部分。 (任何git对象的ID都是该对象内容的加密校验和,并且提交的内容包括父ID。)

如果/当您将此类过滤结果推送到共享存储库(如github)时,该共享存储库的每个用户必须根据过滤重新调整他们的副本。假设6738d23 Documentation updates.是过滤之前共享存储库中的内容,其他人都有6738d23,但您(在您的推送中)创建97ffb07 Documentation updates.,其他人必须接受他们拥有的任何提交6738d23的后代并将其重新加入97ffb07。这包括4c4fe1a Ticker clean up and bug fixes.(显然是你)的人。然后他们必须停止使用6738d23并开始使用97ffb07

如果上述假设是错误的 - 如果97ffb07是过滤前共享仓库中的内容,而6738d23是新版本,那么每个人都必须停止使用97ffb07版本改为开始使用6738d23

这个“每个人都必须停止使用A并开始使用B”这一事实使得重写历史如此痛苦,并在可能的情况下予以避免。如果有人错过了“停止使用A,开始使用B”指令,他们可能会创建一个合并 - 就像你所做的那样 - 将旧的“A及其所有父母”的历史重新合并,使其看起来像是(并且是)重复所有新的“B及其所有父母”的历史。

要解决此问题,您必须摆脱合并,即重新写入历史记录。