41

我想获取所有文件的列表,这些文件在两次提交之间发生了变化,包括子模块中的那些。

我知道我可以这样做:

git diff --name-only --diff-filter=ACMR ${revision} HEAD

它返回一个文件列表,包括子模块路径,但不包括其中的文件。

示例:我更新了一个子模块。我提交了这个超级项目。现在我想获取所有已修改文件的列表。

您知道完成此任务的方法吗?

4

7 回答 7

48

2017 年更新:正如我在“ see diff of commit on submodule in gitlab ”中提到的,


2012 年原始答案(2017 年 Git 2.14 之前)

也许一条简单的线就足够了:

git submodule foreach --recursive git diff --name-status

这实际上会列出子模块中的子模块中的文件。
--recursive选项来自git1.7.3+)

于 2012-10-27T13:39:54.220 回答
5

您可以使用以下命令找出子模块在给定父模块提交时的版本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 Base/Php/Classes/Helper.php

于 2012-11-01T01:46:28.003 回答
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"

于 2012-05-26T01:15:50.693 回答
3

2017 年 7 月 8 日

现在要获得包括 a 的差异submodule,您可以使用命令 -

git diff --submodule=diff

注意 - 这已在Git 2.14.0中引入

“git diff --submodule=diff”现在递归到嵌套的子模块中。

于 2017-07-08T08:58:01.343 回答
2

Jamey Sharp的https://stackoverflow.com/a/13169898/5438298的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

(请注意,子模块名称中的空格可能需要更多的双引号才能起作用)。

于 2019-02-19T13:36:02.683 回答
0

我现在使用 git 2.32.0:

git diff --submodule=diff

并使用正则表达式模式解析输出:“--- a/(.*)”

于 2022-01-19T11:17:27.243 回答
-1

您可以使用

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”选项可能很重要,如下面的注释所示。

备注:我喜欢文件中完整的彩色差异,之后可以“htmlized”进行演示:

git -c color.diff=always --no-pager diff --submodule=diff HEAD~1 HEAD > diffFileName
于 2020-10-23T11:04:36.223 回答