{"thread":{"id":"28818","subject":"[PATCH v3] Display change history as a diff between two dirs","startedAt":"2011-11-01T21:37:07Z","lastAt":"2011-11-01T21:37:07Z","messageCount":1,"participants":["Roland Kaufmann"],"isPatch":true,"patchVersion":3,"patchTotal":null},"messages":[{"id":"178650","messageId":"4EB06683.2020900@gmail.com","threadId":"28818","inReplyTo":null,"subject":"[PATCH v3] Display change history as a diff between two dirs","fromName":"Roland Kaufmann","fromEmail":"rlndkfmn+git@gmail.com","sentAt":"2011-11-01T21:37:07Z","receivedAt":"2011-11-01T21:37:07Z","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---\nIssues addressed in this revision are:\n\n* Diff-viewer is searched for in order: env. var. GIT_EXTERNAL_TREEDIFF,\n  env. var. GIT_EXTERNAL_DIFF, conf. of git-difftool.\n\n  If dir. comp. is found useful, there should probably be some config\n  var. to control it too, but I think that will require some refactoring\n  of git-mergetool--lib.\n\n* Only platforms where mktemp is known to exist (and have sane options)\n  are explicitly tested for; the default is to fallback to a Perl module\n  implementation which is heavier, but has a greater chance of working\n  I reckon (git-send-email uses this module).\n\n* Less convoluted testing of empty directory.\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..8ff0124\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 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..c5834ae\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 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 ! -f \"$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"}]}