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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.