Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 160 lines (144 sloc) 3.883 kb
e408d98 @thenigan Created script to perform directory diff using external diff tool
thenigan authored
1 #!/bin/sh -e
2 # Copyright 2010, Tim Henigan <tim.henigan@gmail.com>
3 #
4 # Perform a directory diff between commits in the repository using
5 # the external diff tool specified in the 'diff.tool' configuration
6 # option.
7
8 USAGE='<options> <commit>{0,2} -- <path>*
9
10 --cached Compare to the index rather than the working tree
11 commit SHA1 of a commit
12 path Limit the diff to the specified paths
13 '
14
15 . git-sh-setup
16
17 if [ -z $(git config --get diff.tool) ]; then
18 echo "Error: The 'diff.tool' configuration option must be set."
19 usage
20 fi
21
22 start_dir=$(pwd)
23 cd_to_toplevel # needed to access tar utility
24
25 # mktemp is not available on all platforms (missing from msysgit)
26 # Use a hard-coded tmp dir if it is not available
27 if [ -z $(which mktemp) ]; then
28 tmp=/tmp/git-diffall-tmp
29 else
98a89f0 Fixed mktemp call to work on OS X as well as other OSs
Daniel Bingham authored
30 tmp="$(mktemp -d -t tmp.XXXXXX)"
e408d98 @thenigan Created script to perform directory diff using external diff tool
thenigan authored
31 fi
32 mkdir -p "$tmp" "$tmp"/a "$tmp"/b
33
34 left=
35 right=
36 paths=
37 path_sep=
38 compare_staged=
39 common_anscestor=
40
41 while test $# != 0; do
42 case "$1" in
43 -h|--h|--he|--hel|--help)
44 usage
45 ;;
46 --cached)
47 compare_staged=1
48 ;;
49 --)
50 path_sep=1
51 ;;
52 -*)
53 echo Invalid option: "$1"
54 usage
55 ;;
56 *)
57 # could be commit, commit range or path limiter
58 case "$1" in
59 *...*)
60 left=${1%...*}
61 right=${1#*...}
62 common_anscestor=1
63 ;;
64 *..*)
65 left=${1%..*}
66 right=${1#*..}
67 ;;
68 *)
69 if [ -n "$path_sep" ]; then
70 if [ -z "$paths" ]; then
71 paths=$1
72 else
73 paths="$paths $1"
74 fi
75 elif [ -z "$left" ]; then
76 left=$1
77 elif [ -z "$right" ]; then
78 right=$1
79 else
80 if [ -z "$paths" ]; then
81 paths=$1
82 else
83 paths="$paths $1"
84 fi
85 fi
86 ;;
87 esac
88 ;;
89 esac
90 shift
91 done
92
93 # Determine the set of files which changed
94 if [ -n "$left" ] && [ -n "$right" ]; then
95 if [ -n "$compare_staged" ]; then
96 usage
97 elif [ -n "$common_anscestor" ]; then
98 git diff --name-only "$left"..."$right" -- "$paths" > "$tmp"/filelist
99 else
100 git diff --name-only "$left" "$right" -- "$paths" > "$tmp"/filelist
101 fi
102 elif [ -n "$left" ]; then
103 if [ -n "$compare_staged" ]; then
104 git diff --name-only --cached "$left" -- "$paths" > "$tmp"/filelist
105 else
106 git diff --name-only "$left" -- "$paths" > "$tmp"/filelist
107 fi
108 else
109 if [ -n "$compare_staged" ]; then
110 git diff --name-only --cached -- "$paths" > "$tmp"/filelist
111 else
112 git diff --name-only -- "$paths" > "$tmp"/filelist
113 fi
114 fi
115
116 # Exit immediately if there are no diffs
117 if [ ! -s "$tmp"/filelist ]; then
118 exit 0
119 fi
120
121 # Populate the tmp/b directory with the files to be compared
122 if [ -n "$right" ]; then
123 while read name; do
124 mkdir -p "$tmp"/b/"$(dirname "$name")"
125 git show "$right":"$name" > "$tmp"/b/"$name"
126 done < "$tmp"/filelist
127 elif [ -n "$compare_staged" ]; then
128 while read name; do
129 mkdir -p "$tmp"/b/"$(dirname "$name")"
130 git show :"$name" > "$tmp"/b/"$name"
131 done < "$tmp"/filelist
132 else
133 tar -c -T "$tmp"/filelist | (cd "$tmp"/b && tar -x)
134 fi
135
136 # Populate the tmp/a directory with the files to be compared
137 while read name; do
138 mkdir -p "$tmp"/a/"$(dirname "$name")"
139 if [ -n "$left" ]; then
140 git show "$left":"$name" > "$tmp"/a/"$name"
141 else
142 if [ -n "$compare_staged" ]; then
143 git show HEAD:"$name" > "$tmp"/a/"$name"
144 else
145 git show :"$name" > "$tmp"/a/"$name"
146 fi
147 fi
148 done < "$tmp"/filelist
149
150 cd "$tmp"
151 $(git config --get diff.tool) a b
152
153 # On exit, remove the tmp directory
154 cleanup () {
155 cd "$start_dir"
156 rm -rf "$tmp"
157 }
158
159 trap cleanup EXIT
Something went wrong with that request. Please try again.