{"thread":{"id":"29739","subject":"[PATCH v4] Display change history as a diff between two dirs","startedAt":"2012-02-25T21:47:47Z","lastAt":"2012-02-27T11:31:39Z","messageCount":3,"participants":["Roland Kaufmann","Junio C Hamano"],"isPatch":true,"patchVersion":4,"patchTotal":null},"messages":[{"id":"185441","messageId":"4F495703.10401@gmail.com","threadId":"29739","inReplyTo":null,"subject":"[PATCH v4] Display change history as a diff between two dirs","fromName":"Roland Kaufmann","fromEmail":"rlndkfmn+git@gmail.com","sentAt":"2012-02-25T21:47:47Z","receivedAt":"2012-02-25T21:47:47Z","isPatch":true,"sender":{"key":"rlndkfmn+git@gmail.com","avatar":null},"body":"Watching patches serially it can be difficult to get an overview of how\na pervasive change is distributed through-out different modules. Thus;\n\nExtract snapshots of the files that have changed between two revisions\ninto temporary directories and launch a graphical tool to show the diff\nbetween them.\n\nUse existing functionality in git-diff to get the files themselves, and\ngit-difftool to launch the diff viewer.\n\nBased on a script called 'git-diffc' by Nitin Gupta.\n\nSigned-off-by: Roland Kaufmann <rlndkfmn+git@gmail.com>\n---\nIssue addressed in this revision:\n* If changes were made in subdirectories the script though the diff\n  set between the two trees was empty, because it only checked for\n  regular files.\n\n contrib/dirdiff/README                 |   10 ++++\n contrib/dirdiff/git-dirdiff--helper.sh |   37 ++++++++++++++++\n contrib/dirdiff/git-dirdiff.sh         |   72 ++++++++++++++++++++++++++++++++\n contrib/dirdiff/git-dirdiff.txt        |   71 +++++++++++++++++++++++++++++++\n 4 files changed, 190 insertions(+), 0 deletions(-)\n create mode 100644 contrib/dirdiff/README\n create mode 100755 contrib/dirdiff/git-dirdiff--helper.sh\n create mode 100755 contrib/dirdiff/git-dirdiff.sh\n create mode 100644 contrib/dirdiff/git-dirdiff.txt\n\ndiff --git a/contrib/dirdiff/README b/contrib/dirdiff/README\nnew file mode 100644\nindex 0000000..d06461a\n--- /dev/null\n+++ b/contrib/dirdiff/README\n@@ -0,0 +1,10 @@\n+# install on GNU, BSD:\n+for f in \"\" \"--helper\"; do\n+  b=git-dirdiff$f\n+  sudo install -m 0755 contrib/dirdiff/$b.sh $(git --exec-path)/$b\n+done\n+\n+# install on Windows\n+for /f %a in ('git --exec-path') do set GIT_PATH=%a\n+set GIT_PATH=%GIT_PATH:/=\\%\n+for %a in (\"\" \"--helper\") do copy contrib\\dirdiff\\git-dirdiff%~a.sh \"%GIT_PATH%\\%~a\" /y\ndiff --git a/contrib/dirdiff/git-dirdiff--helper.sh b/contrib/dirdiff/git-dirdiff--helper.sh\nnew file mode 100755\nindex 0000000..a23efee\n--- /dev/null\n+++ b/contrib/dirdiff/git-dirdiff--helper.sh\n@@ -0,0 +1,37 @@\n+#!/bin/sh\n+#\n+# Accumulate files in a changeset into a pre-defined directory.\n+#\n+# Copyright (C) 2011-2012 Roland Kaufmann\n+#\n+# Based on a script called git-diffc by Nitin Gupta and valuable\n+# suggestions by Junio C. Hamano.\n+#\n+# This file is licensed under the GPL v2, or a later version\n+# at the discretion of the official Git maintainer.\n+\n+. git-sh-setup\n+\n+# check that we are called by git-dirdiff\n+test -z \"$__GIT_DIFF_DIR\" &&\n+  die Error: Do not call $(basename \"$0\") directly\n+\n+# what is the directory name of the file that has changed\n+RELDIR=$(dirname \"$1\") ||\n+  exit $?\n+\n+# don't attempt to copy new or removed files\n+if test \"$2\" != \"/dev/null\"\n+then\n+  mkdir -p \"$__GIT_DIFF_DIR/old/$RELDIR\" ||\n+    exit $?\n+  cp \"$2\" \"$__GIT_DIFF_DIR/old/$1\" ||\n+    exit $?\n+fi\n+if test \"$5\" != \"/dev/null\"\n+then\n+  mkdir -p \"$__GIT_DIFF_DIR/new/$RELDIR\" ||\n+    exit $?\n+  cp \"$5\" \"$__GIT_DIFF_DIR/new/$1\" ||\n+    exit $?\n+fi\ndiff --git a/contrib/dirdiff/git-dirdiff.sh b/contrib/dirdiff/git-dirdiff.sh\nnew file mode 100755\nindex 0000000..33c294d\n--- /dev/null\n+++ b/contrib/dirdiff/git-dirdiff.sh\n@@ -0,0 +1,72 @@\n+#!/bin/sh\n+#\n+# Display differences between two commits with a directory comparison.\n+#\n+# Copyright (C) 2011-2012 Roland Kaufmann\n+#\n+# Based on a script called git-diffc by Nitin Gupta and valuable\n+# suggestions by Junio C. Hamano.\n+#\n+# This file is licensed under the GPL v2, or a later version\n+# at the discretion of the official Git maintainer.\n+\n+. git-sh-setup\n+\n+# TMPDIR points to the designated space for temporary files; only if\n+# not set use /tmp (MSYS even mounts %TEMP% to there)\n+test -z \"$TMPDIR\" && TMPDIR=/tmp\n+\n+# create a temporary directory to hold snapshots of changed files\n+# fallback on crippled platforms is to use a Perl module\n+case $(uname -s) in\n+Linux | *BSD | Darwin | windows* | CYGWIN_NT*)\n+  __GIT_DIFF_DIR=$(mktemp -d \"$TMPDIR/git-dirdiff.XXXXXX\")\n+  ;;\n+*)\n+  __GIT_DIFF_DIR=$(perl -e \"use File::Temp qw/tempdir/; print tempdir(\\\"git-dirdiff.XXXXXX\\\", DIR=>\\\"$TMPDIR\\\")\")\n+  ;;\n+esac\n+test -d \"$__GIT_DIFF_DIR\" -a -w \"$__GIT_DIFF_DIR\" ||\n+  die Error: Could not create a temporary subdir in $TMPDIR\n+\n+# cleanup after we're done\n+trap 'rm -rf $__GIT_DIFF_DIR' 0\n+\n+# export this variable so that scripts called indirectly can access it\n+export __GIT_DIFF_DIR\n+\n+# let the helper script accumulate all changed files into the temporary\n+# directory letting 'git diff' do all the heavy lifting\n+GIT_EXTERNAL_DIFF=git-dirdiff--helper git --no-pager diff \"$@\" ||\n+  exit $?\n+\n+# first and second argument will always be the special directory links\n+# if there are no hidden files nor regular files, then $3 will be the\n+# second wildcard unexpanded\n+isempty () {\n+  set - $1/.* $1/*\n+  test ! -e \"$3\"\n+}\n+\n+# no-op if no files were changed\n+isempty \"$__GIT_DIFF_DIR/old\" && isempty \"$__GIT_DIFF_DIR/new\" &&\n+  exit 0\n+\n+# if a different tool is setup for tree comparison, launch that instead\n+# if GIT_EXTERNAL_TREEDIFF is not set, then use GIT_EXTERNAL_DIFF\n+if test -n \"$GIT_EXTERNAL_DIFF\"\n+then\n+  GIT_DIFFTOOL_EXTCMD=$GIT_EXTERNAL_DIFF\n+  export GIT_DIFFTOOL_EXTCMD\n+fi\n+if test -n \"$GIT_EXTERNAL_TREEDIFF\"\n+then\n+  GIT_DIFFTOOL_EXTCMD=$GIT_EXTERNAL_TREEDIFF\n+  export GIT_DIFFTOOL_EXTCMD\n+fi\n+\n+# run original diff program, reckoning it will understand directories\n+# modes and shas does not apply to the root directories so submit dummy\n+# values for those, hoping that the diff tool does not use them.\n+git-difftool--helper - \"$__GIT_DIFF_DIR/old\" deadbeef 0755 \"$__GIT_DIFF_DIR/new\" babeface 0755 ||\n+  exit $?\ndiff --git a/contrib/dirdiff/git-dirdiff.txt b/contrib/dirdiff/git-dirdiff.txt\nnew file mode 100644\nindex 0000000..b80430a\n--- /dev/null\n+++ b/contrib/dirdiff/git-dirdiff.txt\n@@ -0,0 +1,71 @@\n+git-dirdiff(1)\n+==============\n+\n+NAME\n+----\n+git-dirdiff - Show changes using directory compare\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git dirdiff' [<options>] [<commit> [<commit>]] [--] [<path>...]\n+\n+DESCRIPTION\n+-----------\n+'git dirdiff' is a git command that allows you to compare revisions\n+as a difference between two directories. 'git dirdiff' is a frontend\n+to linkgit:git-diff[1].\n+\n+OPTIONS\n+-------\n+See linkgit:git-diff[1] for the list of supported options.\n+\n+ENVIRONMENT VARIABLES\n+---------------------\n+'GIT_EXTERNAL_TREEDIFF'::\n+\tWhen 'GIT_EXTERNAL_TREEDIFF' is set, the program named by it is\n+\tused as a diff viewer. The program must accept 7 parameters, where\n+\tparameter 2 is the path to a temporary directory containing the\n+\t\"old\" revision, and parameter 5 is the path of the \"new\" revision.\n+\tThe other five parameters will only contain dummy values, and their\n+\tcontents are subject to change.\n+\n+'GIT_EXTERNAL_DIFF'::\n+\tIf and only if 'GIT_EXTERNAL_TREEDIFF' is not set, 'git dirdiff'\n+\twill use the contents of 'GIT_EXTERNAL_DIFF' as the name of the\n+\tdiff viewer.\n+\n+CONFIG VARIABLES\n+----------------\n+If none of the above environment variables are set, 'git dirdiff' will\n+use the same config variables as linkgit:git-difftool[1] to determine\n+which difftool should be used.\n+\n+TEMPORARY FILES\n+---------------\n+'git dirdiff' creates a directory with 'mktemp' to hold snapshots of the\n+files which are different in the two revisions. This directory is removed\n+when the diff viewer terminates.\n+\n+NOTES\n+-----\n+The diff viewer must support being passed directories instead of files\n+as its arguments.\n++\n+Files that are not put under version control are not included when\n+viewing the difference between a revision and the working directory.\n+\n+SEE ALSO\n+--------\n+linkgit:git-diff[1]::\n+\t Show changes between commits, commit and working tree, etc\n+\n+linkgit:git-difftool[1]::\n+\tShow changes using common diff tools\n+\n+linkgit:git-config[1]::\n+\t Get and set repository or global options\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\n-- \n1.7.1\n"},{"id":"185479","messageId":"7vlinpcewj.fsf@alter.siamese.dyndns.org","threadId":"29739","inReplyTo":"4F495703.10401@gmail.com","subject":"Re: [PATCH v4] Display change history as a diff between two dirs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-02-27T00:13:00Z","receivedAt":"2012-02-27T00:13:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Roland Kaufmann <rlndkfmn+git@gmail.com> writes:\n\n> Watching patches serially it can be difficult to get an overview of how\n> a pervasive change is distributed through-out different modules. Thus;\n>\n> Extract snapshots of the files that have changed between two revisions\n> into temporary directories and launch a graphical tool to show the diff\n> between them.\n>\n> Use existing functionality in git-diff to get the files themselves, and\n> git-difftool to launch the diff viewer.\n>\n> Based on a script called 'git-diffc' by Nitin Gupta.\n>\n> Signed-off-by: Roland Kaufmann <rlndkfmn+git@gmail.com>\n> ---\n\nSorry, but I completely forgot about this three-month old topic (the last\ndiscussion was early November last year).\n\nHow does this compare with Tim Henigan's \"diffall\"?  I think the problem\nthese two topics try to address is the same, and their approach may be\nsimilar enough that having one consolidated effort might be worth it.\n\nI seem to have suggested during the previous review round of this series\nthe same thing I suggested to Tim, that we _might_ want to instead have\nthe logic to populate the two temporary trees on the core side with a new\nexternal diff interface.\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/184458/focus=184462\n"},{"id":"185514","messageId":"CANEMaQTfHMeoomeQ=7vqyj9SAwcmxJczqYE19+c49R6FyNGh0w@mail.gmail.com","threadId":"29739","inReplyTo":"7vlinpcewj.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v4] Display change history as a diff between two dirs","fromName":"Roland Kaufmann","fromEmail":"rlndkfmn+git@gmail.com","sentAt":"2012-02-27T11:31:39Z","receivedAt":"2012-02-27T11:31:39Z","isPatch":true,"sender":{"key":"rlndkfmn+git@gmail.com","avatar":null},"body":"On Mon, Feb 27, 2012 at 01:13, Junio C Hamano <gitster@pobox.com> wrote:\n> How does this compare with Tim Henigan's \"diffall\"?  I think the problem\n> these two topics try to address is the same, and their approach may be\n> similar enough that having one consolidated effort might be worth it.\n\nYes, I certainly agree. From a quick glance it seems to do exactly the\nsame thing (and both take inspirations from scripts already floating\naround on the net); I guess that is a sign that it is an idea whose time\nhas come! :-)\n\nThe major difference is that Tim's version generate the list of files\nand then extract them, whereas my current version piggybacks on\nthe external diff interface (as you suggested in one of the previous\nreviews). Which of these approaches -- if any -- has the most merit\nI think depends on the plans for that interface.\n\nBut until that's decided upon, it would have been nice if a version\ncould hang out in contrib/ to gather some experience.\n\n-- \n   Roland.\n"}]}