我们的开发团队正在使用git,我们最近至少两次丢失了对文件的更改。我们正在使用私人Github回购。
在目前的情况下,我们可以返回Github上的日志并查看我对文件所做的一些更新。后来,另一个团队成员更改了文件的不同部分,似乎已经破坏了我的更改。我仍然在当地有它们。
还有其他人经历过这个吗?任何原因或解决方案?
我不认为任何人都在做任何变革或任何幻想 - 只是拉动和推动。
答案 0 :(得分:7)
我想补充几句话。我最近注意到在git中非常奇怪的行为。因此,我的团队遇到了很大的问题。 我不知道它是怎么发生的,但似乎我的回购中的历史是不一致的。
小插图:
提交XXXXXXXX:
行“bar”已添加到文件foo中。
......正在进行中...
稍后提交许多提交(假设约为100):
此文件中不再存在行“bar”!!
调查:
1.我检查了文件的历史:
git log foo 和 gitk foo
我甚至将每次提交的连续blob与外部工具(gvimdiff)进行了比较。 有趣的是我发现了两个提交(让我们称之为YYY和ZZZ)。 来自提交YYY的文件foo的blob包含“bar”,但来自ZZZ的blob没有.b 当我用gitk(和gitweb)检查那些提交的commitdiff时,我注意到在ZZZ中没有删除行“bar”的操作。 是否可能存在介于两者之间并在空气中溶解的情况? 或者也许提交ZZZ只是删除我的行和嵌入在git(或gitk)中的diff工具坏了?
2.我搜索了可以使用“git log -S”删除此行的提交,如:
git log -S'bar' - foo
事实证明这条线从未删除过。事实上它增加了两次。第一次将其引入项目时,第二次将其再次添加为紧急错误修复程序。
我真的很喜欢使用git甚至说服几个朋友使用它,但如果这种魔法继续发生,我将不得不开始寻找其他选择。
答案 1 :(得分:3)
我的团队也发生过类似的事情。
经验教训:当你拉动时,你应该注意合并冲突。如果有拉动冲突,git不会将合并的更改提交到您的本地仓库,您必须在解决冲突后执行此操作。否则,在推送时,您将使用本地副本覆盖远程仓库不包含远程用户所做的更改。这解释了一些您可能看到未提交的“奇怪文件”,但您确定这不是您的更改 - 这表示“拉”合并冲突,并且 - 再次 - 您必须在解决后将这些更改提交到本地冲突,然后推送到远程。
如果您在合并时没有冲突 - 不会出现丢失更改的问题。因为git获取,合并并提交到本地副本,然后'push'然后将这些合并的更改传播到remote。
答案 2 :(得分:2)
我遇到了类似的问题,在一般日志中我可以看到我对文件所做的更改,但是当我检查文件的特定日志时,这些更改不会显示,只显示我的同事的更改。我很确定这是因为我的同事以某种方式搞砸了合并......但我仍然希望这会出现在日志中。
答案 3 :(得分:1)
虽然我不能谈谈你的具体问题,但我能说的是,昨天我经历了非常相似的事情。我有一个设计师在代码中搜索一些URL,并在我正在完成的iPhone应用程序中更新一些图像,并没有告诉我它。我推动了我所做的改变,这些改变也触及了其中一些文件(不同的点),并且它被拒绝为非本地快进。所以我拉了,发生冲突,解决了他们并推了推。问题解决了。但是,我在此过程中撤消了他的代码更改。
我最近添加到我的工作流程中的一件事由于我昨天在github私人仓库上遇到的问题非常类似;是为了隐藏我即将进行的更改,从回购中提取并应用我的存储。如果有冲突,请解决,然后再推。
答案 4 :(得分:1)
我的猜测是提交者之间有不同的配置,可能有人错过了autocrlf配置。
Git以某种方式考虑完全不同的同一个文件的两个修订版,从而用另一个分支的较新更改覆盖旧文件。
如果三向合并(默认递归)发现两个完全不同的子节点(即由于CRLF配置错误),合并后的结果将是最新的,没有冲突。
答案 5 :(得分:0)
我们遇到了同样的问题:Dev A做了一个改变。 Dev B改变了其他的东西。在Dev B推动他的改变后,Dev A所做的改变“消失了”。 Dev B在几周前所做的改变,但似乎没有人注意到Dev A的改变直到现在。
变化“消失”的真正原因是我们用来查看历史记录(TFS)的工具显示的是不正确的历史版本。当我们使用不同的工具(SmartGit和SourceTree)查看时,我们看到了真正发生的事情:有人在尝试修复合并冲突时覆盖了更改,并且覆盖在普通视图中。
所以,失去变化的并不是git,而是我们使用的工具给了我们错误的历史观。只是要注意的事情。
我们一直在使用git一年,99%的时间使用git“出错”,这实际上是由一个不太了解git的人造成的。唯一一次“git”是一个CRLF问题,但实际上是因为我们不太了解git并且(感谢SO)它很容易处理。
因此,请务必仔细查看,您可能会发现问题可归结为某人不理解git并做一些他们不应该做的事情。
答案 6 :(得分:0)
就我而言,我藏了一些更改以处理紧急错误修复程序,只是忘了将其隐藏并提交
答案 7 :(得分:0)
我设法在Visual Studio中重现了这个实例。
在VS的冲突解决屏幕中,一旦您完成了从两个分支中选择更改的操作,如果您在单击“接受合并”之前未手动保存文件,它将使用左侧的(旧版本),而不会在其他情况下提示丢失更改。
答案 8 :(得分:0)
遇到此问题,并发现以下snippet有助于分析:
git for-each-ref --sort=-committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate)%(color:reset))'
这使一个人可以看到所有分支(sort=-committerdate
)中对仓库(refs/heads/
)的最后提交。
样本观察:
feature/blah_a - 9e492d9 - done b4 but committed l8r - (Sat Sep 15 14:29:53 2020)
feature/blah_b - f98db7a - something - (Sat Sep 26 11:38:42 2020)
feature/blah_c - 4ab7ee7 - somethang - (Tue Sep 24 17:38:25 2020)
读者会注意到,feature/blah_a
早于其他人,但后来合并,造成中间值机的“损失”。
另一个“易于记忆”的片段是:
git log -20 --date=iso --pretty=format:'%cd %h %d'
虽然输出简短,但会提供一个快速快照,指示HEAD commit是否早于以后的引用。