我想获得所有文件的列表,这些文件在两个提交之间发生了变化,包括子模块中的那些。
我知道我可以这样做:
git diff --name-only --diff-filter=ACMR ${revision} HEAD
它返回一个文件列表,包括子模块路径,但不包含。
中的文件实施例: 我已经更新了一个子模块。我提交了超级项目。现在我想获得所有已修改文件的列表。
你知道如何完成这项工作吗?
答案 0 :(得分:26)
2017年更新:正如我在“see diff of commit on submodule in gitlab”中提到的那样,
Git 2.11(2016年11月)介绍
git diff --submodule=diff
Git 2.14(2017年第3季度)将通过递归嵌套子模块来改进这一点。
请commit 5a52214查看Stefan Beller (stefanbeller
)(2017年5月4日)
(2017年5月29日Junio C Hamano -- gitster
-- commit a531ecf合并)
2012年原创答案(2017年之前的Git 2.14)
也许一条简单的线就足够了:
git submodule foreach --recursive git diff --name-status
这实际上会列出子模块中子模块中的文件
(--recursive
选项来自git1.7.3 +)
答案 1 :(得分:4)
您可以使用git ls-tree
找出子模块在给定父模块提交时所处的版本:
subcommit=$(git ls-tree $parentcommit $submodulepath | awk '{print $3}')
所以这里有一个脚本应该可以帮助你解决问题,直到输出格式化等等:
#!/bin/sh
function compare {
if [[ -z "$3" ]];
then git diff --name-only --ignore-submodules=all --diff-filter=ACMR "$1" "$2"
else git diff --name-only --ignore-submodules=all --diff-filter=ACMR "$1" "$2" | awk -v r=$3 '{ print "" r "/" $0}'
fi
for submodule in `git submodule | awk '{print $2}'`
do
old=$(git ls-tree $1 $submodule | awk '{print $3}')
new=$(git ls-tree $2 $submodule | awk '{print $3}')
(cd $submodule; compare $old $new $submodule)
done
}
compare "$1" "$2"
这将输出这样的所有文件(尽管Base是子模块): HtmlTemplates / CSS / Screen.css 碱/ PHP /类别/ Helper.php
答案 2 :(得分:3)
因此,非常简单的脚本列出了与修订版相比的所有更改
#!/bin/sh
echo "Listing changes for super module"
git diff $1 --name-only
subs=(`git submodule | awk '{print $2}'`)
for sub in ${subs[*]}; do
lastrevision=`git diff $1 $sub | fgrep "Subproject" | head -n1 | awk '{print $3}'`
cd $sub
echo "Listing changes for $sub"
git diff $lastrevision --name-only
cd ..
done
它需要一个参数 - 您要与之比较的修订版本。
确保有fgrep "Subproject"
,而不是fgrep "Submodule"
。
答案 3 :(得分:2)
https://stackoverflow.com/a/13169898/5438298的Jamey Sharp的Windows变体应为
@echo off
if NOT %1.==. goto has_rev1
@echo git diff --name-only including submodules
@echo usage:
@echo ^ ^ %~n0 ^<revision1^> [^<revision2^>^|HEAD]
@exit /b 1
:has_rev1
setlocal
set rev1=%1
if %2.==. (set rev2=HEAD) else (set rev2=%2)
call :show_diff %rev1% %rev2%
exit /b
::eof
:show_diff
setlocal ENABLEDELAYEDEXPANSION
for /f "tokens=*" %%l in ('git --no-pager diff --name-only --ignore-submodules^=all --line-prefix^=%3 %1 %2') do set fwds=%%l & set bcks=!fwds:/=\! & echo !bcks!
endlocal
::git submodule is too slow for this
::for /f "tokens=2" %%d in ('git submodule') do call :subm %1 %2 %%d %3
if exist .gitmodules for /f "tokens=1,3*" %%p in (.gitmodules) do if %%p.==path. call :subm %1 %2 %%q %3
exit /b
::show_diff
:subm
setlocal
for /f "tokens=3" %%r in ('git ls-tree %1 %3') do set rev1=%%r
for /f "tokens=3" %%r in ('git ls-tree %2 %3') do set rev2=%%r
set fwdslash=%3
set bckslash=%fwdslash:/=\%
pushd %bckslash%
call :show_diff %rev1% %rev2% %4%bckslash%\
popd
endlocal
exit /b
::subm
(请注意,子模块名称中的空格可能需要更多的双引号才能起作用)。
答案 4 :(得分:1)
7月8,2017
现在要获得包含submodule
的差异的差异,您可以使用命令 -
git diff --submodule=diff
注意 - Git 2.14.0
引入了此功能&#34; git diff --submodule = diff&#34;现在递归到嵌套的子模块。
答案 5 :(得分:1)
key
有一个问题:它没有将用户指定的所有git cli-option传递给为每个子模块生成的diff。例如,git diff --submodule=diff
不会将git diff --binary --no-renames --submodule=diff ...
和--binary
传递到子模块的内联git diff中。
https://github.com/git/git/blob/fe8321ec057f9231c26c29b364721568e58040f7/submodule.c#L620
编辑:找到一种解决方法,可以使用git-config:--no-renames
传递--no重命名。
但是仍然无法将git -c diff.renames=false diff --submodules=diff COMMIT COMMIT
传递给子模块diff,因为git-config中没有这样的选项。
答案 6 :(得分:0)
您可以使用
git -c color.diff=false diff --submodule=diff HEAD~1 HEAD | sed -n -e s/^diff\ --git\ a\\///p
仅显示文件列表(以HEAD〜1和HEAD作为参考)。
我喜欢
git -c color.diff=false diff --submodule=diff HEAD~1 HEAD | grep -E "^(diff|Submodule)\ "
按子模块将文件分组。根据终端的不同,使用“ --no-pager”选项可能很重要,如下文所示。
备注:我喜欢文件中完整的彩色差异,可以对其进行“ HTML化”以供日后展示:
git -c color.diff=always --no-pager diff --submodule=diff HEAD~1 HEAD > diffFileName