如何在git中获取合并文件列表?

对于给定的合并提交,如何找出哪些文件合并了两个或更多父母的变化(有或没有冲突)?

而且,这是一个例子,只是为了衡量:

A -- B -- C -- E-- .. 
      \-- D --/  

我有以下文件

> B有f1,f2,f3,f5,f6
> C修改f1和f3.删除f2
> D修改f1,f3和f6.添加f4.
> E是合并提交,有f1,f3,f4,f5和f6.

我正在寻找在E中返回列表“f1 f3”的git命令,因为在E中,这些是C和D都改变的唯一两个文件.所有其他文件未被触及,或由单个父项更新只要.

用例如下:公司有一个SCM(不是git),开发人员将变更集(文件列表)提交给临时分支.在提交给主要开发分支之前,提交需要经过仔细检查和同行评审.偶尔(并且我的意思是经常),开发分支在提交之后进行,此时某些文件需要合并(并重新合并)才能被接受到开发分支.

在上面的示例中,底线表示临时分支,D是我的审核变更集.第一行是主开发分支,C是在此期间继续进行的提交.在E中,我已批准我的更改,并已更新并与新的dev-branch合并.现在的任务是提出一个我需要向上游推送到公司SCM的文件列表(记住,这是我需要提出的手动变更集).在E中更改的文件包括我在D中修改或添加的文件,并且已经向上游推送并且没有对应文件或者没有在dev分支中触及(在C中).并且在E中也是由其他人在dev分支中修改的文件,而我与之无关.这些是具有单个父项的文件.其余的是合并的文件(由Git自动或在发生冲突时由我自己).这就是我需要推动的清单.

最佳答案 (后期编辑:diff-tree的-c仅列出与所有父母不同的文件,即正是要求的文件:

git diff-tree -r -c $commit  # content that doesn't match any parent version

)
(后面的编辑:以上实际上并不完全正确:请求的内容以及下面打印的脚本是自合并库以来所有具有更改的父项的文件.根据定义,所有这些文件都需要合并解析.diff忽略合并解析的文件是结果一个父母.
)

好的,从编辑中看,你想要生成一个文件列表,以检查合并驱动程序可能的错误合并,这些文件结合了至少两个父项的实际更改.这样做你会:

(编辑:正确处理不包含已更改父级的更改的合并;还包含@ torek的简化.)

substantive-merges-in ()
{
    set -- `git rev-list $1^! --parents`;
    child=$1;
    shift;
    base=$(git merge-base "$@")
    for parent; do
        git diff-tree $base $parent -r --name-only --diff-filter=M
    done \
    | sort \
    | uniq -d
}
substantive-merges-in master

测试:

git init t;cd t
git checkout -b first
# msysgit doesn't install `seq`?
for i in 1 2 3 4 5 6 7 8 9 10; do echo $i >>both; done
cp both justfirst
git add *; git commit -minitial
git branch second
sed -i s/3/3onfirst/ both
sed -i s/3/3onfirst/ justfirst
git commit -amtwochanges
git checkout second
sed -i s/7/7onsecond/ both
git commit -amonechange
git merge first
substantive-merges-in HEAD          # should list 'both'
git checkout -B second second@{1}
git merge --no-commit first
git checkout --ours both
git commit -amstomp
substantive-merges-in HEAD          # should still list 'both'
点赞