Git正在丢失单个文件的历史记录/内容。

8

我在一家小公司工作,我们的 Git 仓库有些混乱。我刚刚执行了 git pull 命令,结果我之前做的更改都不见了!

当我在主分支上使用 HEAD 时,git log 显示我的最后一次提交记录 b94940c63ef965ce45b0d64ccfba4359134d2552

现在,如果我对丢失了更改的问题文件执行 git log filename 命令,则该提交记录不会显示(只显示早期提交记录)。

执行 git log --follow filename 命令后,我的提交记录 b94940c63ef965ce45b0d64ccfba4359134d2552 被显示为最近的提交记录。

确实,如果我执行以下命令:

git checkout b94940c63ef965ce45b0d64ccfba4359134d2552
git log filename

然后提交被展示了,我的修改已经在文件里了!

换句话说,我所做的提交显示在分支历史记录中(阻止了分支合并),但是单个修改过的文件却没有该提交的历史记录!(除非我明确地检出该提交)。

问题:

  1. 这到底是怎么发生的?

  2. 我该如何解决?(我们的 repo 中有多个文件存在问题)

4个回答

5

好的,问题已经找到了。当一位同事拉取时,出现了一些冲突。他没有解决这些冲突,而是重置了每个暂存文件。这就相当于在个别旧文件上执行git checkout old_version操作。因此,主分支上的HEAD引用了一些旧版本文件。

现在我正在手动恢复他误删的内容。

故事的寓意:对单个文件进行修改的git操作(checkout、reset等)是非常危险的。


6
这并不是真正的道德教训。道德教训是:“学会解决合并冲突”。它适用于任何版本控制系统,而且根据围绕它存在的问题数量来看,似乎是开发人员中最不常实践的技能。 - Ryan Stewart
1
完全同意,@Ryan,问题通常会因为人们“手动恢复他所破坏的内容”而被拖延,而不是撤销更改并让他正确地合并。 - Karl Bielefeldt

1

这只是一条注释,但读起来可能会很困难。在检查主分支后:

git checkout master

输出结果是什么

git status

并且

git whatchanged -m -p <path>

并且

git log --graph --oneline b94940c63ef965ce45b0d64ccfba4359134d2552..master

?


注:对于未来的评论者:whatchanged从git log --follow获取差异 - UsAaR33

0

您实际上可以在要查看可能已丢失提交的文件的文件夹中使用此bash脚本:

#!/bin/zsh
for f in $(find . -name '*.php')
do
 follow=$(git log --oneline -1 --pretty=format:"%h" -- $f)
 log=$(git log --follow --oneline -1 --pretty=format:"%h" -- $f)
 
 if [ $log != $follow ]; then
    echo "follow $follow , log $log => $f"
   fi

done


0

首先,你应该了解Git命令的作用以及存储在代码库中的数据。

  • 获取一个历史可视化工具,如Giggle或Gitk,以查看您的提交历史并查看哪个提交基于哪个提交。

  • git pull执行两个操作:它从远程代码库检索新提交,并将远程代码库的头与您当前的头(在当前分支中)合并。

因此,在这种情况下,您可能希望更加小心。而不是使用git pull,您可以使用git fetch并手动合并需要合并的内容。这样,您就可以控制自己所做的编辑。

关于你目前的情况,我不认为 Git 会丢失数据。你说你的文件仍然在历史记录中。所以现在你可能需要进行一些创造性的重置(恢复到旧版本)或补丁(可能需要手动操作),以使你的项目文件达到你想要的状态。

感谢您对Giggle和Gitk的建议。它们很有用,但只是告诉我与控制台显示相同的内容;分支具有正确的历史记录-文件不是。某种方式,文件处于错误的版本上。幸运的是,没有数据丢失,所以我可以进行重置。但我只是担心其他事情正在发生(并且很快会再次出现问题)-这就是为什么我想知道事情是如何变成这样的原因。 - UsAaR33

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