name=
head_from=
-diff_opts=
-diff_committed_only=yes # will be unset for index/worktree
## Parse options
while [ -n "$1" ]; do
arg="$1"; shift
case "$arg" in
- -i)
+ -i|-w)
[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
- head_from=-i
- diff_opts="$diff_opts --cached";
- diff_committed_only=;;
- -w)
- [ -z "$head_from" ] || die "-i and -w are mutually exclusive"
- head_from=-w
- diff_committed_only=;;
+ head_from="$arg";;
-*)
echo "Usage: tg [...] patch [-i | -w] [NAME]" >&2
exit 1;;
setup_pager
-cat_file "$name:.topmsg" $head_from
-echo
-[ -n "$(git grep $diff_opts '^[-]--' ${diff_committed_only:+"$name"} -- ".topmsg")" ] || echo '---'
-
-# Evil obnoxious hack to work around the lack of git diff --exclude
-git_is_stupid="$(get_temp tg-patch-changes)"
-git diff --name-only $diff_opts "$base_rev" ${diff_committed_only:+"$name"} -- |
- fgrep -vx ".topdeps" |
- fgrep -vx ".topmsg" >"$git_is_stupid" || : # fgrep likes to fail randomly?
-if [ -s "$git_is_stupid" ]; then
- cd "$root_dir"
- cat "$git_is_stupid" | xargs git diff -a --patch-with-stat $diff_opts "$base_rev" ${diff_committed_only:+"$name"} --
-else
+
+# put out the commit message
+# and put an empty line out, if the last one in the message was not an empty line
+# and put out "---" if the commit message does not have one yet
+cat_file "$name:.topmsg" $head_from |
+ awk '
+/^---/ {
+ has_3dash=1;
+}
+ {
+ need_empty = 1;
+ if ($0 == "")
+ need_empty = 0;
+ print;
+}
+END {
+ if (need_empty)
+ print "";
+ if (!has_3dash)
+ print "---";
+}
+'
+
+b_tree=$(pretty_tree "$name" -b)
+t_tree=$(pretty_tree "$name" $head_from)
+
+if [ $b_tree = $t_tree ]; then
echo "No changes."
+else
+ git diff-tree -p --stat $b_tree $t_tree
fi
echo '-- '