サブモジュールを含む2つのコミットの間に変更されたすべてのファイルのリストを取得したいと思います。
私はこれができることを知っています:
git diff --name-only --diff-filter=ACMR ${revision} HEAD
サブモジュールパスを含むファイルのリストを返しますが、その中のファイルは返しません。
例:サブモジュールを更新しました。スーパープロジェクトをコミットしました。次に、変更されたすべてのファイルのリストを取得します。
これを行う方法を知っていますか?
2017年更新:「 gitlabのサブモジュールでのコミットの差分を参照 」で述べたように、
Git 2.11(2016年11月)の紹介
git diff --submodule=diff
Git 2.14(2017年第3四半期)では、ネストされたサブモジュールに再帰することで改善されます。
Stefan Beller(stefanbeller
) による commit 5a52214 (2017年5月4日)を参照してください。
( Junio C Hamano-gitster
- によってマージ commit a531ecf 、2017年5月29日)
元の2012年の回答(2017年以前のGit 2.14)
多分単純な行で十分でしょう:
git submodule foreach --recursive git diff --name-status
これは実際にはサブモジュールwithinサブモジュール内のファイルをリストします。
(--recursive
オプションはgit1.7.3以降のものです)
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"
これは次のようなすべてのファイルを出力します(ベースはサブモジュールですが):HtmlTemplates/Css/Screen.css Base/Php/Classes/Helper.php
したがって、リビジョンと比較してすべての変更をリストする非常に簡単なスクリプト
#!/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
引数は1つです。比較したいリビジョンです。 fgrep "Subproject"
ではなくfgrep "Submodule"
があることを確認してください。
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
(サブモジュール名のスペースを機能させるには、さらにいくつかの二重引用符が必要になる場合があることに注意してください)。
2017年7月8日
submodule
の差分を含む差分を取得するには、次のコマンドを使用できます-
git diff --submodule=diff
注-これは Git 2.14. で導入されました。
「git diff --submodule = diff」はネストされたサブモジュールに再帰するようになりました。
git diff --submodule=diff
に問題があります:各サブモジュールに対して生成されたdiffにユーザーが指定したすべてのgit cli-optionsを渡しません。たとえば、git diff --binary --no-renames --submodule=diff ...
は、--binary
および--no-renames
をサブモジュールのインラインgit diffに渡しません。
https://github.com/git/git/blob/fe8321ec057f9231c26c29b364721568e58040f7/submodule.c#L62
編集: git-config :git -c diff.renames=false diff --submodules=diff COMMIT COMMIT
を使用して--no-renamesを渡す回避策が見つかりました。
しかし、それでも--binary
をサブモジュールのdiffに渡す方法はありません。git-configにはそのようなオプションがないためです。