偶尔,我会遇到一个非常奇怪且令人沮丧的问题。我提交并推送一些包含新文件和修改过的文件的更改,而我的同事则将其他一些不相关的内容提交给不同的文件。
现在,当他撤消我的更改时,我新添加的文件在他身边显示为未跟踪,我的更改将被恢复。不知道这一点,他提交并推送到存储库,我的更改完全被git遗忘。
例如,如果我更改了文件A
,那么如果我git log -p A
,我根本看不到他对我的更改的恢复,我也看不到我更改它的提交。但是,如果我查看git历史记录并找到该提交,我的更改就在那个提交中。我的提交仍然存在于git历史中,但是没有git提交可以恢复我的东西,但不知何故它在最新的master中被还原,因为我的提交中的更改已经以某种方式从master分支中删除。
有没有人遇到类似的东西?我的第一个想法是他在做出自己的改变之前就已经拉了,但是他声称他在拉扯之前已经做出了承诺。另一种可能性是他有一个IDE(PyCharm)里面有一个git客户端(但是他使用命令行git)以某种方式破坏了他机器中的git。另外需要注意的是,他在运行OS X时运行Windows,所以也许它可能是一个git版本冲突。
另一件可能很重要的事情:执行git log -p myfile
不会显示我更改过的提交,git log --follow -p myfile
显示我的更改,但没有显示其他更改还原它。
当我发出git log
时,我可以看到我做出更改的提交以及与fileA
相关的更改。只有当我发出git log -p fileA
时,我才能看到对fileA
的更改。所以,提交就在那里,合并为master,但它的效果已经消失了。
有什么想法吗?
答案 0 :(得分:3)
看起来推动更改的人(或他正在使用的IDE)正在进行强制推送(即git push -f
),其中git会覆盖历史记录。
要确认这一理论,你可以这样做:
创建一个新的repo克隆(因为在你当前的repo中,提交可能仍然可以通过一些本地分支或标记访问):
mkdir -p ~/temp-git-dir
cd ~/temp-git-dir
git clone <REPO-URL>
git fsck --unreachable --no-reflogs 2>/dev/null | grep 'unreachable commit' | awk '{print $3;}' | xargs -r -n 1 git show --oneline --name-status
如果你的提交是列出的提交之一,那么它就证实了这个理论。
<强>解决方案强>:
当工作流涉及多个开发人员时,允许强制推送回购总是一个坏主意。您可以与您的SCM管理员交谈,看看他们是否可以禁止强制推送或仅在真正需要时允许它。
工作流应该涉及,每个开发人员都试图从远程获取更改,并将本地提交与远程的新提交合并或重新绑定,然后将更新的refspec推回到远程。