Git远程跟踪分支与本地分支发生了分歧,尽管具有相同的提交但哈希值不同。

4
这是我的git repo当前状态(在GitX中可视化)。 '34e ...'和'c3d ...'提交(被注释为“Implemented a global ...”)是相同的。我用git diff确认了这一点,它们甚至有相同的提交时间!唯一的区别是它们的SHA。
我不知道如何让我的repo处于这种状态。虽然我不是git专家,但我已经使用它一段时间了,并且对所有基础知识都非常熟悉。这是突然发生的,我没有尝试任何以前没有使用过的git功能或工作流程,所以我感到相当困惑。
没有其他人向远程提交任何内容,因此我可以更改历史记录,但最好不要涉及这方面的解决方案。
我可以只做正常的合并或重定位主文件夹和origin/master,但我对此感到不舒服,因为历史记录将显示2个相同的提交。
有可能检出origin/master,然后重新定位从'a4a...'开始的所有提交到origin/master,然后将主文件夹切换到此新HEAD吗? (基本上仅保留'c3d ...'提交,由于它是重复项,因此无关紧要)
1)那么修复这种情况的首选方法是什么?
2)这是怎么发生的?有人遇到过这种情况吗?
编辑:
git diff c3db784817 34e1ab666a:没有输出。 git reflog master:9579294 master@ {0}:commit:为测试图像视图添加了仅调试的控制台打印
1155228 master@{1}: commit: 添加新标记接口,自定义单元格可以imp
a4ab788 master@{2}: commit: 添加了一个新的StyledRootElement,它可以自动应用于
c3db784 master@{3}: commit: 实现了一种全局技术,可以为所有现有样式
34e1ab6 master@{4}: commit: 实现了一种全局技术,可以为所有现有样式
8519fb1 master@{5}: commit: 扩展了remove方法,使调用者可以访问
30aeee6 master@{6}: commit: 基于侧滑视图添加了一个新的工厂方法

Bender:mt-d-styles tyson$ git reflog origin/master
34e1ab6 更新推送后的引用/远程origin/master@{0}
8519fb1 更新推送后的引用/远程origin/master@{1}
495e0ef 更新推送后的引用/远程origin/master@{2}
c5fec81 更新推送后的引用/远程origin/master@{3}
cba1e0f 更新推送后的引用/远程origin/master@{4}
9ee1ffb 更新推送后的引用/远程origin/master@{5}
68ee429 更新推送后的引用/远程origin/master@{6}
0e2d199 更新推送后的引用/远程origin/master@{7}
8a4de84 更新推送后的引用/远程origin/master@{8}

编辑2:
git log --format=raw --decorate --graph --all:

*  commit c3db7848171f396c5a595a35dd6b609c119f9e84 
| tree 998e9749546d05178798c8a462d3eff02a111f4c 
| parent 8519fb17e77b8ae865e071772ae652316df8822a 
| author Tyson <tyson> 1364529327 +0800 
| committer Tyson <tyson> 1364539365 +0800 
|  
|     Implemented a global technique for styling all existing MT.D element backg 
|  


| * commit 34e1ab666a81dde7582ee9e31bfa961420d38f55 (origin/master) 
|/  tree 38f9e0c3d936c702fdcd18d215a2f0a88280893b 
|   parent 8519fb17e77b8ae865e071772ae652316df8822a 
|   author Tyson <tyson> 1364529327 +0800 
|   committer Tyson <tyson> 1364529327 +0800 
|    
|      Implemented a global technique for styling all existing MT.D element bac 
|

git diff c3d784 34e1ab 显示什么? - kan
请提供git reflog mastergit reflog origin/master的输出。 - kan
请查看问题中的编辑。 - Tyson
这看起来像是您修改了提交。但不是使用命令行客户端。 - Chronial
@Chronial 是的,我经常在 GitX 中使用修改。但这仍然无法解释为什么 git diff 在这两者之间没有显示任何差异。出于好奇,是什么让 reflog 输出看起来像我进行了修改? - Tyson
我扩展了我的答案来回答那个问题。 - Chronial
1个回答

6
原因: 您可能进行了一些历史记录重写。如果提交完全相同,则SHA将自动相同。您在UI中看到的不是提交日期,而是作者日期。运行git log -- format = raw --decorate - graph --all 以获取更多详细信息。我猜您会发现本地版本的提交日期是一个较晚的日期。这是由历史记录重写引起的,通常是修改或变基。 解决方案: 如果您知道如何回退,可以尝试使用rebase拉取 – 如果提交确实相同,git应该意识到这一点,并添加一个提交。如果您不知道如何回退,请将master重新设置为origin/master,并在c3db784817处切断:
git rebase --onto origin/master c3db784817 master

在评论中的问题:

如何从 reflog 中知道您进行了修改:

c3db784 master@{3}: commit: Implemented a global technique for styling all exist
34e1ab6 master@{4}: commit: Implemented a global technique for styling all exist

您创建一个提交后,您的主分支位于34e1ab6。然后您推送了这个提交。然后您的主分支移动到c3db784——一个具有相同消息的提交,并且您的git客户端显示原因是commit。由于之间没有分支头移动,这很像一个修正提交。不过命令行客户端会说commit (amend)
而您的日志告诉我,您在unix时间1364529327(2013-03-28 20:55:27)进行了第一次提交,然后在unix时间1364539365(2013-03-28 23:42:45)对其进行了修改。(而且您可能住在美国;)

你说得对!请看我上面的第二次编辑,附带了 git log 的输出 - 不同的“提交者”时间。而且我经常使用修改功能。但这是否意味着我提交了一个提交,推送了它,然后进行了修改,从而只修改了本地提交? - Tyson
1
是的,您始终只会修改本地提交。而且您应该永远不要重写(=修改)已发布的历史记录。即使您什么也没有更改,修订也将“始终”进行重写,因为提交时间会更改 - 正如您所看到的那样。 - Chronial
嗯...我发誓我以前尝试过这样做(推送后修改),但是Git阻止了我,或者至少警告了我。也许是GitX的修改没有警告。无论如何,使用提交的SHA创建补丁的rebase --onto正是我要找的!非常有效!谢谢! - Tyson
我仍然不明白为什么树形ID 998e97438f9e0c 不同,但是 diff 没有显示任何内容。而且为什么 reflog 没有 (amend)。这只是 GitX 的错误吗? - kan
顺便说一句,git rebase origin/master就足以修复这样的历史记录,--onto选项是不必要的。 - kan
@kan:我在回复中已经说过了。但是根据我的经验,这个功能(补丁ID)并不总是能够正常工作。我认为缺少的(amend)是GitX的一个bug - 如果你想这么称呼它的话。不同的树确实很有趣。@Tyson:可以试着运行git cat-file -p **SHA**来进行调查吗? - Chronial

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接