# HG changeset patch # User Mathias De Maré # Date 2014-12-10 09:32:51 # Node ID 01a8dfc79cdc3037e6f15e91fcaec65de15b9057 # Parent 49a58b33d1ced975fee1e3fd7bb8fca0084017c0 subrepo: add partial diff support for git subrepos So far, git subrepositories were silently ignored for diffs. This patch adds support for git subrepositories, with the remark that --include and --exclude are not supported. If --include or --exclude are used, the subrepo is ignored. diff --git a/mercurial/help/subrepos.txt b/mercurial/help/subrepos.txt --- a/mercurial/help/subrepos.txt +++ b/mercurial/help/subrepos.txt @@ -98,8 +98,8 @@ Interaction with Mercurial Commands :diff: diff does not recurse in subrepos unless -S/--subrepos is specified. Changes are displayed as usual, on the subrepositories - elements. Git and Subversion subrepositories are currently - silently ignored. + elements. Git subrepositories do not support --include/--exclude. + Subversion subrepositories are currently silently ignored. :forget: forget currently only handles exact file matches in subrepos. Git and Subversion subrepositories are currently silently ignored. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -1593,6 +1593,48 @@ class gitsubrepo(abstractsubrepo): return scmutil.status(modified, added, removed, deleted, unknown, ignored, clean) + @annotatesubrepoerror + def diff(self, ui, diffopts, node2, match, prefix, **opts): + node1 = self._state[1] + cmd = ['diff'] + if opts['stat']: + cmd.append('--stat') + else: + # for Git, this also implies '-p' + cmd.append('-U%d' % diffopts.context) + + gitprefix = os.path.join(prefix, self._path) + + if diffopts.noprefix: + cmd.extend(['--src-prefix=%s/' % gitprefix, + '--dst-prefix=%s/' % gitprefix]) + else: + cmd.extend(['--src-prefix=a/%s/' % gitprefix, + '--dst-prefix=b/%s/' % gitprefix]) + + if diffopts.ignorews: + cmd.append('--ignore-all-space') + if diffopts.ignorewsamount: + cmd.append('--ignore-space-change') + if self._gitversion(self._gitcommand(['--version'])) >= (1, 8, 4) \ + and diffopts.ignoreblanklines: + cmd.append('--ignore-blank-lines') + + cmd.append(node1) + if node2: + cmd.append(node2) + + if match.anypats(): + return #No support for include/exclude yet + + if match.always(): + ui.write(self._gitcommand(cmd)) + elif match.files(): + for f in match.files(): + ui.write(self._gitcommand(cmd + [f])) + elif match(gitprefix): #Subrepo is matched + ui.write(self._gitcommand(cmd)) + def shortid(self, revid): return revid[:7] diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t --- a/tests/test-subrepo-git.t +++ b/tests/test-subrepo-git.t @@ -103,6 +103,15 @@ clone root, make local change $ echo ggg >> s/g $ hg status --subrepos M s/g + $ hg diff --subrepos + diff --git a/s/g b/s/g + index 089258f..85341ee 100644 + --- a/s/g + +++ b/s/g + @@ -1,2 +1,3 @@ + g + gg + +ggg (no-eol) $ hg commit --subrepos -m ggg committing subrepository s $ hg debugsub @@ -664,4 +673,112 @@ Test that sanitizing is omitted in meta checking out detached HEAD in subrepo s check out a git branch if you intend to make changes +check differences made by most recent change + $ cd s + $ cat > foobar << EOF + > woopwoop + > + > foo + > bar + > EOF + $ git add foobar $ cd .. + + $ hg diff --subrepos + diff --git a/s/foobar b/s/foobar + new file mode 100644 + index 0000000..8a5a5e2 + --- /dev/null + +++ b/s/foobar + @@ -0,0 +1,4 @@ + +woopwoop + + + +foo + +bar (no-eol) + + $ hg commit --subrepos -m "Added foobar" + committing subrepository s + created new head + + $ hg diff -c . --subrepos --nodates + diff -r af6d2edbb0d3 -r 255ee8cf690e .hgsubstate + --- a/.hgsubstate + +++ b/.hgsubstate + @@ -1,1 +1,1 @@ + -32a343883b74769118bb1d3b4b1fbf9156f4dddc s + +fd4dbf828a5b2fcd36b2bcf21ea773820970d129 s + diff --git a/s/foobar b/s/foobar + new file mode 100644 + index 0000000..8a5a5e2 + --- /dev/null + +++ b/s/foobar + @@ -0,0 +1,4 @@ + +woopwoop + + + +foo + +bar (no-eol) + +check output when only diffing the subrepository + $ hg diff -c . --subrepos s + diff --git a/s/foobar b/s/foobar + new file mode 100644 + index 0000000..8a5a5e2 + --- /dev/null + +++ b/s/foobar + @@ -0,0 +1,4 @@ + +woopwoop + + + +foo + +bar (no-eol) + +check output when diffing something else + $ hg diff -c . --subrepos .hgsubstate --nodates + diff -r af6d2edbb0d3 -r 255ee8cf690e .hgsubstate + --- a/.hgsubstate + +++ b/.hgsubstate + @@ -1,1 +1,1 @@ + -32a343883b74769118bb1d3b4b1fbf9156f4dddc s + +fd4dbf828a5b2fcd36b2bcf21ea773820970d129 s + +add new changes, including whitespace + $ cd s + $ cat > foobar << EOF + > woop woop + > + > foo + > bar + > EOF + $ echo foo > barfoo + $ git add barfoo + $ cd .. + + $ hg diff --subrepos --ignore-all-space + diff --git a/s/barfoo b/s/barfoo + new file mode 100644 + index 0000000..257cc56 + --- /dev/null + +++ b/s/barfoo + @@ -0,0 +1 @@ + +foo (no-eol) + $ hg diff --subrepos s/foobar + diff --git a/s/foobar b/s/foobar + index 8a5a5e2..bd5812a 100644 + --- a/s/foobar + +++ b/s/foobar + @@ -1,4 +1,4 @@ + -woopwoop + +woop woop + + foo + bar (no-eol) + + $ hg diff --subrepos --stat + barfoo | 1 + + foobar | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) (no-eol) + +ensure adding include/exclude ignores the subrepo + $ hg diff --subrepos -I s/foobar + $ hg diff --subrepos -X s/foobar + + $ cd ..