Git合并 - 不完整、缺失的文件和文件夹

48
我正在尝试将开发分支合并到主分支中。
git checkout master    
git pull . dev

看起来一切都很顺利,虽然有一些冲突,但我已经解决了它们并提交了。但是当我检查这个新合并的工作树时,发现缺少了许多来自开发环境的文件夹和文件。

git status  // Shows conflicts & doesn't list some files/folders.    
git commit -a 

Created commit 55ffdd1: Merge branch 'dev' into master  

git diff dev --name-status

生成:

D       folders/lm.gif
D       folders/lmh.gif
...

有些文件/文件夹在“git status”中没有显示出来。当我解决了合并冲突后,它也没有出现在最终结果中。

另外,当我尝试再次合并时,它会显示:

git merge dev    
Already up-to-date.

然而,主分支明显缺少开发分支中的文件/文件夹。为什么会这样?难道那个文件夹及其所有内容都不应该被添加吗?'folders'在开发分支上被跟踪,所以当我进行合并时,它不应该被拉过来吗?

早些时候当出现合并冲突时,Git是否停止了合并过程并跳过了一些文件/文件夹?

开发分支有相当多的更改,我在以前使用 Git 时弄错了什么,现在某些文件/文件夹不会合并吗?(当我第一次创建开发分支时,我不知道我在做什么,并且像重置、还原等做了一些疯狂的事情。)

希望 Stack Overflow 上的 Git 大师们之一能够知道答案。

谢谢, Quang


回答

感谢 Walter,是的,这就是发生的事情。

经过一些调查,我发现发生的情况有点复杂。事实证明:

  1. 开发分支从主分支分支出来,具有所有文件。
  2. 第三个分支,让我们称其为“清理”,从开发分支分支出来。
  3. 清理分支删除了所有文件。
  4. 清理分支合并(或其他操作?)到主干。此时,文件已从主分支中删除。而“cleaned”分支也消失了。
  5. 在开发分支上,文件仍然存在,并且我继续添加到该分支中,相当长一段时间编辑文件。
  6. 开发分支与主分支合并,之前被清理删除的所有文件都不见了。

希望这对除了我之外还学到了很多如何使用 Git 日志、Git 显示和 Git reflog 调试发生了什么的人有所帮助。

谢谢!

如何修复

所以这就是我做的,将开发分支中之前删除的所有内容合并回主分支。

  1. 获取所有被删除的文件/文件夹(在dev分支上但在新合并的master分支上没有): git diff dev --name-status | grep D > deleted_files
  2. 输出所有文件和文件夹列表:git log --name-status > file_history 用于确定被删除文件的最后更新版本。
  3. 逐个遍历deleted_files列表,找到file_history中最新版本并将其恢复。例如:git checkout 25b8a44 view.php 其中25b8a44是view.php的最后更新版本的提交。我尝试使用cherry-pick和直接使用git checkout dev view.php,但我发现明确地使用提交ID会合并更多历史记录(包括导致该文件首次被删除的提交)。
  4. 一旦所有删除的文件都恢复了,快速检查git diff dev --name-status | grep D,确认所有文件已经复制过来。然后像Walter说的那样,进行修订提交:git commit --amend :)

你实际上可以这样做cat deleted_files | awk '{ print $2 }' | xargs -I haha git checkout develop haha,这样速度更快。感谢这个答案! - John Wu
3
请将您的答案转移到一个回答帖子中。 - jpmc26
1个回答

25

听起来好像git认为缺失的文件在从dev分支分离出来并合并到主分支之前的某个时刻已经被删除了。这是我能想到的唯一原因,解释了为什么git在合并过程中会静默地丢失跟踪文件。

不幸的是,我不知道有什么好的修复方法。我可能会手动重新添加所有从dev分支中删除的文件(或使用一些bash脚本),然后执行git commit --amend命令修改合并提交,将它们包含在内。


是的,这就是发生的事情。经过一些调查,我发现发生的事情有点复杂。原来是这样的。请参考上面的解释。 - Quang Van
另一种解决方案是将混合重置到分支中删除文件之前的时间,然后合并并强制推送新历史记录。如果您提交了错误的合并并且其他人已经拉取了它,则每个人都可能需要恢复到以前的提交并重新拉取。 - MrE
我也遇到了同样的问题,之前使用 git revert -m 1 commit 来撤销一些合并操作。我发现唯一的方法是手动比较差异并手动添加它们。结论:再也不要使用 git revert 了。 - Black

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