Re: git diff across submodules
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Sep 19, 2012, 22:31 UTC
- Message-ID
- <7v4nmtfxvx.fsf@alter.siamese.dyndns.org>
- In-Reply-To
- <7vobl3m8pb.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
Show 18 quoted lines
> I also suspect that you do not have to change "git diff" at all to > show the patch recursively by using the attribute mechanism (look in > Documentation/gitattributes.text for a string GIT_EXTERNAL_DIFF). > It might be just as simple as doing this: > > echo >.gitattributes "/lib/frotz diff=subrecurse" > git config diff.subrecurse.command $HOME/bin/diff-subrecurse > cat >$HOME/bin/diff-subrecurse <<\-EOF > #!/bin/sh > path=$1 old_hex=$3 new_hex=$6 > unset GIT_DIR > cd "$path" || exit 1 > git diff "$old_hex" "$new_hex" > EOF > chmod +x $HOME/bin/diff-subrecurse > > The corner cases like "new submodule", "removed submodule" are left > as an exercise to the reader ;-)
It turns out that essentially the above outline I concocted in my MUA is usable almost as-is.
Here is what I ended up with.
* In .git/config of the superproject, I added this:
[diff "submodule-recurse"] command = src/bin/diff-submodule-recurse
* In the superproject, src/bin/diff-submodule-recurse has this (this is probably whitespace damaged---the lines must be indented by HT for the here document to correctly work):
#!/bin/sh
# $1 $2 $3 $4 $5 $6 $7
# path old-file old-hex old-mode new-file new-hex new-mode case "$#,$4,$7" in
7,160000,160000) ;;
*) echo "diff --git a/$1 b/$1"
echo "(punt)"
exit
;;
esac
unset GIT_DIR
cd "$1" || {
cat <<-\EOF
diff --git a/$1 b/$1
(cannot chdir to $1)
-Subproject commit $3
+Subproject commit $6
EOF
}
git --no-pager diff --src-prefix="s/$1/" --dst-prefix="m/$1/" "$3" "$6"* In .gitattributes of the superproject, I have this:
/var diff=submodule-recurse
The superproject in this case is a repository to control what I have in my $HOME directory (e.g. it has src/dot/Makefile that builds and installs the appropriate dotfiles, src/bin/Makefile that builds and installs to $HOME/bin, etc.), and one subdirectory, 'var', is a submodule that is only cloned to some but not all machines I clone this superproject to.
With this setting, things like
$ git diff HEAD~20
show differences with recursion into the var/ submodule just fine.