Git “missing” commit

匿名 (未验证) 提交于 2019-12-03 08:42:37

问题:

I'm in a situation where some changes made in a feature branch are not reflected in master, even though this branch was merged into it. I'm at a loss to understand why. For simplicity, let's say this commit has a hash "A" and changed file "file"

This can probably best be illustrated by the following commands:

$ git checkout master  $ git branch --contains A * master feature_branch  $ git log file | grep A (no output)  $ git checkout feature_branch  $ git log file | grep A A 

Can anyone explain what's going on here? More importantly, is there anything that can be done to prevent this in the future?

EDIT:

As mentioned by a few people, the following does show the commit:

$ git checkout master  $ git log --follow file | grep A A 

But the thing is... the file was not renamed. So that doesn't fully explain things, either..

回答1:

You are a victim of an evil merge.

Here is how to reproduce it

git init testrepo cd testrepo  touch initial git add initial git commit -m 'initial commit'  git checkout -b feature_branch echo "A" >> file git add file git commit -m 'file committed'  git checkout master 

Now do an interactive merge as if there were merge conflicts

git merge --no-commit --no-ff feature_branch 

and move the file file (evil merge).

testrepo (master|MERGING)  git mv file someOtherFile git commit 

Now you will see that branch master contains the commit (in my case 9469682) that introduced file file

 git branch --contains 9469682   feature_branch  * master 

But a git log will not show it, because it was moved

 git log -- file  (no output) 

Use

git log --follow -- file 

and the commit appears again.

Also keep in mind that the merge can get more evil. If the file's content also changed a lot than èven git log --follow will not detect it, because of the rename threshold.

In this case use git log --follow --find-renames= to adjust the rename threshold.

If generating diffs, detect and report renames for each commit. For following files across renames while traversing history, see --follow. If n is specified, it is a threshold on the similarity index (i.e. amount of addition/deletions compared to the file’s size). For example, -M90% means Git should consider a delete/add pair to be a rename if more than 90% of the file hasn’t changed. Without a % sign, the number is to be read as a fraction, with a decimal point before it. I.e., -M5 becomes 0.5, and is thus the same as -M50%. Similarly, -M05 is the same as -M5%. To limit detection to exact renames, use -M100%. The default similarity index is 50%.



回答2:

If somehow the location of the file has changed, you might need to tell git log to follow:

$ git checkout master $ git log --follow -- file | grep A 

You can check if there is a difference between git log --oneline -- file and git log --oneline --follow -- file, to see if the file has been relocated.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!