From: Dan Holmsand <holmsand@gmail.com>
To: git@vger.kernel.org
Cc: Petr Baudis <pasky@ucw.cz>
Subject: [PATCH 5/6] Make cg-diff use optparse, and add features
Date: Thu, 09 Jun 2005 13:24:07 +0200 [thread overview]
Message-ID: <42A826D7.1060507@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 787 bytes --]
This adds some new features to cg-diff:
- diffstat (or rather git-apply --stat) support. The
"-d" option outputs (optionally colorized) diff stats
before the diff.
- support for more git-diff-[tree/cache] options:
-B, -R, -M, -C are now all passed on.
- The COGITO_AUTO_COLOR environment variable makes output
automatically colorized, if set and if we're on a color
capable terminal.
We also use the new optparse function from cg-Xlib, to allow
for e.g. "cg-diff -drorigin" and stuff.
Reuse colorization logic from cg-Xlib.
And use LESS to make "less" search for chunks and diff --git
markers. This allows you to "n" your way through a series
of diffs, and gives a nice visual separation of patches.
Signed-off-by: Dan Holmsand <holmsand@gmail.com>
---
[-- Attachment #2: 5-cg-diff.patch.txt --]
[-- Type: text/plain, Size: 6694 bytes --]
cg-diff | 222 +++++++++++++++++++++++++++++----------------------------------
1 files changed, 102 insertions(+), 120 deletions(-)
diff --git a/cg-diff b/cg-diff
--- a/cg-diff
+++ b/cg-diff
@@ -5,13 +5,16 @@
#
# Outputs a diff for converting the first tree to the second one.
# By default compares the current working tree to the state at the
-# last commit. The output will automatically be displayed in a pager
-# unless it is piped to a program.
+# last commit.
#
# OPTIONS
# -------
-# -c::
-# Colorize the diff output
+# -c, --color::
+# Colorize the diff output and use a pager for output (less by
+# default).
+#
+# -d, --diffstat::
+# Show `diffstat' before diff.
#
# -p::
# Instead of one ID denotes a parent commit to the specified ID
@@ -24,153 +27,132 @@
# empty revision which means '-r rev:' compares between 'rev' and
# 'HEAD', while '-r rev' compares between 'rev' and working tree.
#
+# -R::
+# Output diff in reverse.
+#
+# -M::
+# Detect renames.
+#
+# -C::
+# Detect copies (as well as renames).
+#
+# -B::
+# Detect rewrites.
+#
# -m::
# Base the diff at the merge base of the -r arguments (defaulting
-# to master and origin).
+# to HEAD and origin).
#
# ENVIRONMENT VARIABLES
# ---------------------
# PAGER::
# The pager to display log information in, defaults to `less`.
#
-# PAGER_FLAGS::
-# Flags to pass to the pager. By default `R` is added to the `LESS`
-# environment variable to allow displaying of colorized output.
+# COGITO_AUTO_COLOR::
+# If set, colorized output is used automatically on color-capable
+# terminals.
USAGE="cg-diff [-c] [-m] [-p] [-r FROM_ID[:TO_ID]] [FILE]..."
. ${COGITO_LIB}cg-Xlib
-id1=" "
-id2=" "
-parent=
-opt_color=
-mergebase=
-
-# TODO: Make cg-log use this too.
-setup_colors()
-{
- local C="diffhdr=1;36:diffhdradd=1;32:diffadd=32:diffhdrmod=1;35:diffmod=35:diffhdrrem=1;31:diffrem=31:diffhunk=36:diffctx=34:diffcctx=33:default=0"
- [ -n "$COGITO_COLORS" ] && C="$C:$COGITO_COLORS"
-
- C=${C//=/=\'$'\e'[}
- C=col${C//:/m\'; col}m\'
- #coldefault=$(tput op)
- eval $C
+unset id1 id2 parent diffprog sedprog diffstat difftmp opt_color renames
+dtargs=()
+
+show_diffstat() {
+ [ -s "$difftmp" ] || return
+ git-apply --stat "$difftmp"
+ echo
+ cat "$difftmp"
}
-while [ "$1" ]; do
- case "$1" in
- -c)
- opt_color=1
- setup_colors
- ;;
- -p)
+while optparse; do
+ if optparse -p; then
parent=1
- ;;
- -r)
- shift
- if echo "$1" | grep -q ':'; then
- id2=$(echo "$1" | cut -d : -f 2)
- [ "$id2" ] || log_end="HEAD"
- id1=$(echo "$1" | cut -d : -f 1)
- elif [ "$id1" = " " ]; then
- id1="$1"
+ elif optparse -m; then
+ incoming=1
+ elif optparse -r=; then
+ if [ -z "${id1+set}" ]; then
+ id1=$OPTARG
+ if [[ "$id1" == *:* ]]; then
+ id2=${id1#*:}
+ id1=${id1%:*}
+ fi
else
- id2="$1"
+ [ -z "${id2+set}" ] || die "too many revisions"
+ id2=$OPTARG
fi
- ;;
- -m)
- mergebase=1
- ;;
- *)
- break
- ;;
- esac
- shift
-done
-
-colorize() {
- if [ "$opt_color" ]; then
- gawk '
- { if (/^(Index:|diff --git) /)
- print "'$coldiffhdr'" $0 "'$coldefault'"
- else if (/^======*$/)
- print "'$coldiffhdr'" $0 "'$coldefault'"
- else if (/^\+\+\+/)
- print "'$coldiffhdradd'" $0 "'$coldefault'"
- else if (/^\*\*\*/)
- print "'$coldiffhdrmod'" $0 "'$coldefault'"
- else if (/^---/)
- print "'$coldiffhdrrem'" $0 "'$coldefault'"
- else if (/^(\+|new( file)? mode )/)
- print "'$coldiffadd'" $0 "'$coldefault'"
- else if (/^(-|(deleted file|old) mode )/)
- print "'$coldiffrem'" $0 "'$coldefault'"
- else if (/^!/)
- print "'$coldiffmod'" $0 "'$coldefault'"
- else if (/^@@ \-[0-9]+(,[0-9]+)? \+[0-9]+(,[0-9]+)? @@/)
- print gensub(/^(@@[^@]*@@)([ \t]*)(.*)/,
- "'$coldiffhunk'" "\\1" "'$coldefault'" \
- "\\2" \
- "'$coldiffctx'" "\\3" "'$coldefault'", "")
- else if (/^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/)
- print "'$coldiffcctx'" $0 "'$coldefault'"
- else
- print
- }'
+ elif optparse -c; then
+ opt_color=1
+ elif optparse -d || optparse --diffstat; then
+ diffstat=1
+ elif optparse -R; then
+ dtargs[${#dtargs[@]}]="-R"
+ elif optparse -M; then
+ [ "$renames" ] && optconflict
+ renames=1
+ dtargs[${#dtargs[@]}]="-M"
+ elif optparse -C; then
+ [ "$renames" ] && optconflict
+ renames=1
+ dtargs[${#dtargs[@]}]="-C"
+ elif optparse -B; then
+ dtargs[${#dtargs[@]}]="-B"
else
- cat
+ optfail
fi
-}
+done
-if [ "$parent" ]; then
- id2="$id1"
- id="$id2"; [ "$id" = " " ] && id=""
- id1=$(parent-id "$id" | head -n 1) || exit 1
-fi
+[ -n "$COGITO_AUTO_COLOR" -a -t 1 ] && [ "$(tput setaf 1 2>/dev/null)" ] &&
+opt_color=1
-if [ "$mergebase" ]; then
- [ "$id1" != " " ] || id1="master"
- [ "$id2" != " " ] || id2="origin"
- id1=$(git-merge-base $(commit-id "$id1") $(commit-id "$id2"))
-fi
+LESS=$'+/\013^@@.*@@|^diff.--git..*$'" $LESS"
+diffprog=git-diff-tree
-filter=$(mktemp -t gitdiff.XXXXXX)
-for file in "$@"; do
- echo "$file" >>$filter
-done
+if [ "$parent" ]; then
+ [ -z "${id2+set}" ] || die "too many revisions"
+ id2="$id1"
+ id1=$(parent-id "$id2" | head -n 1) || exit 1
+elif [ "$incoming" ]; then
+ tmp=$id1
+ id1="$(commit-id "${id2:-HEAD}")" || exit 1
+ id2="$(commit-id "${tmp:-origin}")" || exit 1
+ id1="$(git-merge-base "$id1" "$id2")" || exit 1
+fi
-if [ "$id2" = " " ]; then
- if [ "$id1" != " " ]; then
- tree=$(tree-id "$id1") || exit 1
- else
- tree=$(tree-id) || exit 1
- fi
+id1=$(tree-id "$id1") || exit 1
+if [ -z "${id2+set}" ]; then
# Ensure to only diff modified files
git-update-cache --refresh >/dev/null
-
- # FIXME: Update ret based on what did we match. And take "$@"
- # to account after all.
- ret=
- cat $filter | xargs git-diff-cache -r -p $tree | colorize | pager
-
- rm $filter
-
- [ "$ret" ] && die "no files matched"
- exit $ret
+ diffprog=git-diff-cache
+else
+ id2=$(tree-id "$id2") || exit 1
fi
-
-id1=$(tree-id "$id1") || exit 1
-id2=$(tree-id "$id2") || exit 1
-
[ "$id1" = "$id2" ] && die "trying to diff $id1 against itself"
+diffopts=(-r -p "${dtargs[@]}" $id1 $id2 "${ARGS[@]}")
+
+if [ "$diffstat" ]; then
+ difftmp=$(mktemp -t cgdiff.XXXXXX) || exit 1
+ trap "rm '$difftmp'" SIGTERM EXIT
+ $diffprog "${diffopts[@]}" > $difftmp
-cat $filter | xargs git-diff-tree -r -p $id1 $id2 | colorize | pager
+ diffprog=show_diffstat
+ diffopts=
+fi
-rm $filter
-exit 0
+if [ "$opt_color" ]; then
+ setup_colors
+ sedprog="$color_rules"
+
+ [ "$diffstat" ] && sedprog="$sedprog
+s,^\\( [^ ].*\\)\\( | *[0-9][0-9]* \\),$colfiles\\1$coldefault\\2,"
+
+ $diffprog "${diffopts[@]}" | sed -e "$sedprog" | pager
+ exit $PIPESTATUS
+else
+ $diffprog "${diffopts[@]}"
+fi
next prev reply other threads:[~2005-06-09 12:37 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-06-09 11:29 [PATCH 6/6] Make cg-log use optparse, and add features Dan Holmsand
2005-06-09 11:24 ` Dan Holmsand [this message]
2005-06-11 0:02 ` [PATCH 5/6] Make cg-diff " Petr Baudis
2005-06-11 14:29 ` [PATCH] Rewrite cg-diff colorization, add diffstat and reverse Dan Holmsand
2005-06-12 7:29 ` Petr Baudis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42A826D7.1060507@gmail.com \
--to=holmsand@gmail.com \
--cc=git@vger.kernel.org \
--cc=pasky@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).