提交显示在历史记录中,更改不在文件中,也不显示在单个文件提交历史记录中

时间:2016-04-14 16:44:11

标签: git github merge

我只是遇到了一个非常奇怪的问题。昨天我推了一个提交,之后有几个人推了推。现在我可以在github上看到我在历史记录中的提交,但是我所做的更改不在文件的HEAD修订版中,如果我查看单个文件的历史记录,我的提交不会显示。我的队友告诉我,他们所做的只是经常拉动和推动。与我更改的文件没有冲突。如果有人使用强制推动,我希望我的承诺完全消失。如果有人搞砸了合并冲突,我希望合并提交撤消我的更改并反映在文件的提交历史记录中。但不知怎的,情况也不是这样。简化:

  • 我更改了file.txt并提交了提交ABCD
  • 我将ABCD推送到github
  • 其他人推送其他提交,不影响file.txt
  • 如果我查看github上的存储库提交,我会看到我的提交,我可以提取更改差异
  • 如果我查看github上最新版本的file.txt,我的更改不存在
  • 如果我查看file.txt的提交历史记录,ABCD没有显示,那么该文件的最后一次提交就是ABCD之前的提交。

这样的事情是怎么发生的?

编辑:根据评论中的讨论,这是我的提交图

* | 8c1d372 ...
* |   98dbad7 Merge branch 'master'
|\ \  
| * | 8d64a09 ...
| * | 12beb68 ...
| * |   1c94b6d Merge branch 'master'
| |\ \  
| | * | 80b6285 ...
| | * | 9781fad ...
| | * | f12fc90 ...
| | * | 61411fa ...
| | * | 291333b ...
| * | | aeee93f ...
| |/ /  
| * |   bcfbf65 Merge branch 'master'

我失去的承诺是9781fad。如果我结账8c1d372,我的更改就会消失。然而,我之后的任何提交都不会影响我更改的文件。

3 个答案:

答案 0 :(得分:8)

实际答案(而不是超长评论)。

这是图形位,再加上我自己的注释:

* | 8c1d372 ...        <-- lacks desired changes
* |   98dbad7 Merge branch 'master'     <-- ? (interesting #1)
|\ \  
| * | 8d64a09 ...
| * | 12beb68 ...
| * |   1c94b6d Merge branch 'master'   <-- ? (interesting #2)
| |\ \  
| | * | 80b6285 ...    <-- probably also has desired changes
| | * | 9781fad ...    <-- is commit that makes desired changes
| | * | f12fc90 ...
| | * | 61411fa ...
| | * | 291333b ...
| * | | aeee93f ...
| |/ /  
| * |   bcfbf65 Merge branch 'master'

由于没有人明确地恢复你的更改,并且他们是一个文件没有其他人应该编辑,几乎可以肯定,谁丢失你的更改,通过做一个糟糕的合并这样做。

有两个有趣的合并,我已经标记过了。 #1,提交98dbad7,有两个父母:一个我们看不到(在图的底部),我们可以,8d64a09。从这一点开始git log将显示两个历史记录。 git show 98dbad7:path/to/file将显示附加到合并提交的文件的版本(即,无论谁做了合并,表示该文件的正确版本)。如果这是错误的版本 - 如果该文件缺少所需的更改 - 则合并本身变坏或输入错误。据推测,父母本底不应该有变化,所以在这一点上我们应该跟随另一个父母,即8d64a09

您可以git show 8d64a09:path/to/file查看该版本是否包含您的更改。如果您的更改在那里,那么删除它们的是98dbad7提交。如果您的更改,我们应该按下。

为了完整起见,我们可以查看12beb68,但这可能不是罪魁祸首。这是一个普通的提交,父母为1c94b6d

提交1c94b6d是我们第二次有趣的合并。与任何合并一样,它有两个(或更多,但通常是两个)父母。这次我们可以看到两者,它们都是提交80b6285aeee93f

提交80b6285可能有您的更改,因为它是一个普通提交,其父级9781fad 提交您的更改。并且提交aeee93f将不会有您的更改,因为它来自合并的一侧,嗯,没有您的更改。 :-)你可以git show 80b6285:path/to/file只是为了检查那个提交的人是不是秘密地(而不是公开地)还原它们,然后git show 1c94b6d:path/to/file来观察它是否是这个有趣的 - 合并 - #2放弃了你的改变。

很可能这些合并中的一个放弃了您的更改。 为什么仍然是一个有趣的问题,但必须由进行合并的人来回答。他们做了一些事情 - 也许是结账,也许是合并的标志 - 在合并期间放弃了你的变化。找出哪个合并删除了更改,并与任何人进行交谈,以了解他们做了什么,放弃了它们。

获取更改

恢复更改非常容易:只需使用为您运行差异的git cherry-pick,然后将该差异应用于当前提交。因此,您将回到master并简单地git cherry-pick 9781fad。这会将9781fad^9781fad的父级f12fc90)与9781fad区分开来 - 显示您的更改的差异 - 并将它们应用于当前提交并创建一个新的提交,重新使用原始邮件。 (如果你的提交影响了多个文件并且只应该将更改带回一个文件,那么它需要更多的工作,但假设它是一个文件,这是一个简单的修复。你仍然需要但是请确保在将来的合并中没有人撤消它。)

答案 1 :(得分:2)

此答案包含有关如何找到答案的说明。

使用提交图查看器(或只是git log --graph,通常最好调用git log --graph --oneline --decorate --all)来查看您的特定提交在Git DAG方面的位置。如果图形很好且线性,则很容易理解。如果它充满了分支和合并操作,那将会更加棘手,并且很可能有人做了导致问题的错误合并。如果它充满了未合并的分支,或者甚至只有一个未合并的分支,也许这就是问题。

(使用--all将显示所有标签,包括所有分支名称,使用--decorate会将标签附加到他们指向的提交。--oneline选项只会压缩将输出记录到每次提交一行,在文本窗口中输入更多内容。)

使用git show查看任何普通(非合并)提交:这会显示提交元数据(作者,时间,日志消息)并运行git diff来比较该提交的树与该提交的父级的树。例如,git show ABCD应该显示您的更改,因为与您在提交ABCD之前创建的树相比,您提交的树对该文件进行了更改。

假设您的提交ABCD位于图表中您希望的位置,请查看后续提交(再次使用git show) - 后续提交是接近HEAD的提交 - 要查看谁解除了你的改变。然后你可以尝试弄清楚他们是如何做到的,也许是通过与他们交谈。

如果后续提交是合并 - 提交两个或更多父母 - git show通常不会显示您,并且您需要使用git show -m或运行{{ 1}}手动,查看两个比较:从第一个父级到该提交,从第二个父级到该提交。 git diff标志告诉-m为您执行两个单独的差异。 (您可以为非合并提交提供git show;它不会对这些提交任何内容。它不是默认值,因为通常合并会显示大量冗余更改。)

(顺便说一下,-m并没有真正显示文件历史记录&#34;因为Git没有拥有每个文件的历史记录。相反,{{1}通过从git log -- path开始返回提交图来查找所有可以访问的提交,但是然后抛出似乎不会影响相关文件的提交。它不清楚为什么你没有看到你的git log提交在这里,但日志的图形版本和HEAD输出应该更清楚。)

以下评论:在查看标有ABCDgit show的提交时,如果git log输出有说明(签出时4,我们会看到5,4,3 ,2和1,但在签出5时,我们只看到3和2),53中至少有一个必须是合并提交。

假设4是(单个)合并提交,我们可以将此特定图形片段绘制为:

4

此处分支(5)指向提交... <- 1 <------- 4 <- 5 <-- master / ... <- 2 <- 3 <-- ,这是一个普通的非合并提交,而提交master指向提交5:{{1 }}是5的父级。提交4 合并提交,合并提交45的内容;它有两个父项41(按某种顺序)。提交33不合并为其父级。我们对提交13几乎一无所知:我把它们描绘成好像有不同的父母,但也许他们有同一个父母。

提交2是合并,或者12都是合并的可能性;我们可以肯定地说,基于54开始5时出现,而不是从1git log时出现的5git log 1}} 3的历史记录中的不是

请注意,历史记录是通过沿箭头方向指向箭头,而不是箭头。如果我们从1开始并且3是合并,则它有两个出站箭头,因此我们按照两个历史记录来获取{的历史记录{1}}。

虽然5垂直绘制历史记录(并且没有放入箭头),但它会显示相同的信息,但无法看到而没有4,但是对于未来的操作来说非常重要,例如依赖于图表的合并。

请注意如果上面的图片片段是准确的(我还在猜测,因为你还没有发布4输出片段),那么我们几乎可以肯定地说到发生了什么您在提交git log --graph中的更改:在--graph中进行合并的任何人都告诉Git消除您的更改,转而采用提交git log --graph --oneline --decorate --all中的任何内容。

答案 2 :(得分:0)

这可能会帮助正在寻找答案的人。

https://confluence.atlassian.com/bitbucketserverkb/different-file-content-for-the-same-commit-has-being-displayed-in-bitbucket-server-830275709.html

似乎有一种叫做“邪恶合并”的东西。 :D