# [PATCHSET] cg-log cleanups and enhancements

11 messages from 2005-06-04 to 2005-06-04. Participants: Jonas Fonseca.
Thread: https://gitlist.dev/t/832

## Jonas Fonseca, 2005-06-04 14:38

Subject: [PATCHSET] cg-log cleanups and enhancements
Message-ID: <20050604143831.GD12615@diku.dk>
URL: https://gitlist.dev/e/20050604143831.GD12615%40diku.dk

```
The patchset contains the following 10 patches:

  [PATCH 1/10] Cleanup conversion to human readable date
  [PATCH 2/10] Separate handling of tree and parent in commit headers
  [PATCH 3/10] Separate handling of author and committer in commit headers
  [PATCH 4/10] First parse all commit header entries then print them
  [PATCH 5/10] Move printing of the commit info line inside the loop
  [PATCH 6/10] Remove the catch all rule
  [PATCH 7/10] Move log printing to separate function
  [PATCH 8/10] Move the username matching inside the loop
  [PATCH 9/10] Move file matching inside the loop.
  [PATCH 10/10] Add -s option to show log summary

-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:39

Subject: [PATCH 1/10] Cleanup conversion to human readable date
Message-ID: <20050604143906.GE12615@diku.dk>
URL: https://gitlist.dev/e/20050604143906.GE12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Simplify the date substitution to reduce code duplication.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log     |    8 ++------
 cg-mkpatch |    7 ++-----
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -188,12 +188,8 @@ $revls | $revsort | while read time comm
 
 				date=(${rest#*> })
 				pdate="$(showdate $date)"
-				if [ "$pdate" ]; then
-					echo -n $color$key $rest | sed "s/>.*/> $pdate/"
-					echo $coldefault
-				else
-					echo $color$key $rest $coldefault
-				fi
+				[ "$pdate" ] && rest="${rest%> *}> $pdate"
+				echo $color$key $rest $coldefault
 				;;
 			"tree"|"parent")
 				if [ -z $tree1 ]; then
diff --git a/cg-mkpatch b/cg-mkpatch
--- a/cg-mkpatch
+++ b/cg-mkpatch
@@ -53,11 +53,8 @@ showpatch () {
 		"author"|"committer")
 			date=(${rest#*> })
 			pdate="$(showdate $date)"
-			if [ "$pdate" ]; then
-				echo $key $rest | sed "s/>.*/> $pdate/" >>$header
-			else
-				echo $key $rest >>$header
-			fi
+			[ "$pdate" ] && rest="${rest%> *}> $pdate"
+			echo $key $rest >>$header
 			;;
 		"")
 			cat

-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:39

Subject: [PATCH 2/10] Separate handling of tree and parent in commit headers
Message-ID: <20050604143937.GF12615@diku.dk>
URL: https://gitlist.dev/e/20050604143937.GF12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Parse tree and parent commit header entries separately so the logic for
deciding where to save the IDs can be removed. Save all parents in an array.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -162,8 +162,8 @@ fi
 
 $revls | $revsort | while read time commit parents; do
 	trap exit SIGPIPE
-	tree1=
-	tree2=
+	tree=
+	parents=()
 	[ "$revfmt" = "git-rev-list" ] && commit="$time"
 	if [ $# -ne 0 ]; then
 		parent=$(git-cat-file commit $commit | sed -n '2s/parent //p;2Q')
@@ -191,17 +191,17 @@ $revls | $revsort | while read time comm
 				[ "$pdate" ] && rest="${rest%> *}> $pdate"
 				echo $color$key $rest $coldefault
 				;;
-			"tree"|"parent")
-				if [ -z $tree1 ]; then
-					tree1=$rest
-				elif [ -z $tree2 ]; then
-					tree2=$rest
-				fi
+			"tree")
+				tree="$rest"
+				echo $colheader$key $tree $coldefault
+				;;
+			"parent")
+				parents[${#parents[@]}]="$rest"
 				echo $colheader$key $rest $coldefault
 				;;
 			"")
 				if [ -n "$list_files" ]; then
-					list_commit_files "$tree1" "$tree2"
+					list_commit_files "$tree" "${parents[0]}"
 				fi
 				echo; sed -re '
 					/ *Signed-off-by:.*/Is//'$colsignoff'&'$coldefault'/

-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:40

Subject: [PATCH 3/10] Separate handling of author and committer in commit headers
Message-ID: <20050604144002.GG12615@diku.dk>
URL: https://gitlist.dev/e/20050604144002.GG12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Parse and print the author and committer header entries so the color logic
can be removed.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -162,6 +162,8 @@ fi
 
 $revls | $revsort | while read time commit parents; do
 	trap exit SIGPIPE
+	author=
+	committer=
 	tree=
 	parents=()
 	[ "$revfmt" = "git-rev-list" ] && commit="$time"
@@ -179,17 +181,19 @@ $revls | $revsort | while read time comm
 		while read key rest; do
 			trap exit SIGPIPE
 			case "$key" in
-			"author"|"committer")
-				if [ "$key" = "author" ]; then
-					color="$colauthor"
-				else
-					color="$colcommitter"
-				fi
-
-				date=(${rest#*> })
+			"author")
+				author="$rest"
+				date=(${author#*> })
+				pdate="$(showdate $date)"
+				[ "$pdate" ] && author="${author%> *}> $pdate"
+				echo $colauthor$key $author $coldefault
+				;;
+			"committer")
+				committer="$rest"
+				date=(${committer#*> })
 				pdate="$(showdate $date)"
-				[ "$pdate" ] && rest="${rest%> *}> $pdate"
-				echo $color$key $rest $coldefault
+				[ "$pdate" ] && committer="${committer%> *}> $pdate"
+				echo $colcommitter$key $committer $coldefault
 				;;
 			"tree")
 				tree="$rest"

-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:40

Subject: [PATCH 4/10] First parse all commit header entries then print them
Message-ID: <20050604144035.GH12615@diku.dk>
URL: https://gitlist.dev/e/20050604144035.GH12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Change the main loop to first parse all header entries before printing
them. Makes the cg-log output more independent of the order of the git
commit header.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |   26 ++++++++++++++++----------
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -183,27 +183,33 @@ $revls | $revsort | while read time comm
 			case "$key" in
 			"author")
 				author="$rest"
-				date=(${author#*> })
-				pdate="$(showdate $date)"
-				[ "$pdate" ] && author="${author%> *}> $pdate"
-				echo $colauthor$key $author $coldefault
 				;;
 			"committer")
 				committer="$rest"
-				date=(${committer#*> })
-				pdate="$(showdate $date)"
-				[ "$pdate" ] && committer="${committer%> *}> $pdate"
-				echo $colcommitter$key $committer $coldefault
 				;;
 			"tree")
 				tree="$rest"
-				echo $colheader$key $tree $coldefault
 				;;
 			"parent")
 				parents[${#parents[@]}]="$rest"
-				echo $colheader$key $rest $coldefault
 				;;
 			"")
+				echo ${colheader}tree $tree $coldefault
+
+				for parent in "${parents[@]}"; do
+					echo ${colheader}parent $parent $coldefault
+				done
+
+				date=(${author#*> })
+				pdate="$(showdate $date)"
+				[ "$pdate" ] && author="${author%> *}> $pdate"
+				echo ${colauthor}author $author $coldefault
+
+				date=(${committer#*> })
+				pdate="$(showdate $date)"
+				[ "$pdate" ] && committer="${committer%> *}> $pdate"
+				echo ${colcommitter}committer $committer $coldefault
+
 				if [ -n "$list_files" ]; then
 					list_commit_files "$tree" "${parents[0]}"
 				fi

-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:41

Subject: [PATCH 5/10] Move printing of the commit info line inside the loop
Message-ID: <20050604144105.GI12615@diku.dk>
URL: https://gitlist.dev/e/20050604144105.GI12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Printing of all the log headers are now handled the same place.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -176,7 +176,6 @@ $revls | $revsort | while read time comm
 	if [ "$user" ]; then
 		git-cat-file commit $commit | grep -e '^author ' -e '^committer ' | grep -qi "$user" || continue
 	fi
-	echo $colheader""commit ${commit%:*} $coldefault;
 	git-cat-file commit $commit | \
 		while read key rest; do
 			trap exit SIGPIPE
@@ -194,6 +193,7 @@ $revls | $revsort | while read time comm
 				parents[${#parents[@]}]="$rest"
 				;;
 			"")
+				echo ${colheader}commit ${commit%:*} $coldefault
 				echo ${colheader}tree $tree $coldefault
 
 				for parent in "${parents[@]}"; do
-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:41

Subject: [PATCH 6/10] Remove the catch all rule
Message-ID: <20050604144131.GJ12615@diku.dk>
URL: https://gitlist.dev/e/20050604144131.GJ12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
All commit header entries are already be handled so no need for a default
case pattern.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -219,11 +219,7 @@ $revls | $revsort | while read time comm
 					s/./    &/
 				'
 				;;
-			*)
-				echo $colheader$key $rest $coldefault
-				;;
 			esac
-
 		done
 	echo
 done | pager
-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:42

Subject: [PATCH 7/10] Move log printing to separate function
Message-ID: <20050604144203.GK12615@diku.dk>
URL: https://gitlist.dev/e/20050604144203.GK12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Each commit log is now handled in the new print_commit_log() function.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -160,22 +160,13 @@ else
 	revfmt="git-rev-list"
 fi
 
-$revls | $revsort | while read time commit parents; do
-	trap exit SIGPIPE
+print_commit_log() {
+	commit="$1"
 	author=
 	committer=
 	tree=
 	parents=()
-	[ "$revfmt" = "git-rev-list" ] && commit="$time"
-	if [ $# -ne 0 ]; then
-		parent=$(git-cat-file commit $commit | sed -n '2s/parent //p;2Q')
-		diff_ops=
-		[ "$parent" ] || diff_ops=--root
-		[ "$(git-diff-tree -r $diff_ops $commit $parent "$@")" ] || continue
-	fi
-	if [ "$user" ]; then
-		git-cat-file commit $commit | grep -e '^author ' -e '^committer ' | grep -qi "$user" || continue
-	fi
+
 	git-cat-file commit $commit | \
 		while read key rest; do
 			trap exit SIGPIPE
@@ -221,5 +212,20 @@ $revls | $revsort | while read time comm
 				;;
 			esac
 		done
+}
+
+$revls | $revsort | while read time commit parents; do
+	trap exit SIGPIPE
+	[ "$revfmt" = "git-rev-list" ] && commit="$time"
+	if [ $# -ne 0 ]; then
+		parent=$(git-cat-file commit $commit | sed -n '2s/parent //p;2Q')
+		diff_ops=
+		[ "$parent" ] || diff_ops=--root
+		[ "$(git-diff-tree -r $diff_ops $commit $parent "$@")" ] || continue
+	fi
+	if [ "$user" ]; then
+		git-cat-file commit $commit | grep -e '^author ' -e '^committer ' | grep -qi "$user" || continue
+	fi
+	print_commit_log $commit
 	echo
 done | pager
-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:42

Subject: [PATCH 8/10] Move the username matching inside the loop
Message-ID: <20050604144242.GL12615@diku.dk>
URL: https://gitlist.dev/e/20050604144242.GL12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
By handling -u in the commit parsing loop no extra git-cat-file call is
necessary. Keep the line-based matching scheme so that it is still possible
to restrict searches by using prefixing the search string with either
'author' or 'committer' (e.g. -u'author.*miciah').

This change also magically removes trailing empty lines from commit logs.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -184,6 +184,10 @@ print_commit_log() {
 				parents[${#parents[@]}]="$rest"
 				;;
 			"")
+				if [ "$user" ]; then
+					echo -e "author $author\ncommitter $committer" \
+						| grep -qi "$user" || return
+				fi
 				echo ${colheader}commit ${commit%:*} $coldefault
 				echo ${colheader}tree $tree $coldefault
 
@@ -223,9 +227,9 @@ $revls | $revsort | while read time comm
 		[ "$parent" ] || diff_ops=--root
 		[ "$(git-diff-tree -r $diff_ops $commit $parent "$@")" ] || continue
 	fi
-	if [ "$user" ]; then
-		git-cat-file commit $commit | grep -e '^author ' -e '^committer ' | grep -qi "$user" || continue
+	log="$(print_commit_log $commit)"
+	if [ "$log" ]; then
+		echo "$log"
+		echo
 	fi
-	print_commit_log $commit
-	echo
 done | pager
-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:43

Subject: [PATCH 9/10] Move file matching inside the loop.
Message-ID: <20050604144306.GM12615@diku.dk>
URL: https://gitlist.dev/e/20050604144306.GM12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
Handling of -f is done inide the loop so no extra git-cat-file call is
necessary. Store file arguments to cg-log in an array to make them easier
to access from print_commit_log().

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-log |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -73,6 +73,7 @@ log_start=
 log_end=
 user=
 mergebase=
+files=()
 
 while [ "$1" ]; do
 	case "$1" in
@@ -107,6 +108,7 @@ while [ "$1" ]; do
 		mergebase=1
 		;;
 	*)
+		files=("$@")
 		break
 		;;
 	esac
@@ -184,6 +186,12 @@ print_commit_log() {
 				parents[${#parents[@]}]="$rest"
 				;;
 			"")
+				if [ "$files" ]; then
+					parent="${parents[0]}"
+					diff_ops=
+					[ "$parent" ] || diff_ops=--root
+					[ "$(git-diff-tree -r $diff_ops $commit $parent "${files[@]}")" ] || return 1
+				fi
 				if [ "$user" ]; then
 					echo -e "author $author\ncommitter $committer" \
 						| grep -qi "$user" || return
@@ -221,12 +229,6 @@ print_commit_log() {
 $revls | $revsort | while read time commit parents; do
 	trap exit SIGPIPE
 	[ "$revfmt" = "git-rev-list" ] && commit="$time"
-	if [ $# -ne 0 ]; then
-		parent=$(git-cat-file commit $commit | sed -n '2s/parent //p;2Q')
-		diff_ops=
-		[ "$parent" ] || diff_ops=--root
-		[ "$(git-diff-tree -r $diff_ops $commit $parent "$@")" ] || continue
-	fi
 	log="$(print_commit_log $commit)"
 	if [ "$log" ]; then
 		echo "$log"
-- 
Jonas Fonseca

```

## Jonas Fonseca, 2005-06-04 14:43

Subject: [PATCH 10/10] Add -s option to show log summary
Message-ID: <20050604144334.GN12615@diku.dk>
URL: https://gitlist.dev/e/20050604144334.GN12615%40diku.dk
In-Reply-To: <20050604143831.GD12615@diku.dk>

```
When passing -s to cg-log each log entry is summarized in one line. The line
carries info about commit date, author, first log line and the commit id. It
will look something like the following (with only:

  2005-05-20 11:46 Linus Torvalds   sparse cleanup   e99d59ff0bff349ef20...

The result ends up being 130 chars wide however the commit id is placed so
that it can easily be hidden if line wrapping in the pager is enabled.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
---

 cg-Xlib |    4 +++-
 cg-log  |   53 ++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/cg-Xlib b/cg-Xlib
--- a/cg-Xlib
+++ b/cg-Xlib
@@ -47,10 +47,12 @@ mktemp () {
 
 showdate () {
 	date="$1"
+	format="$2"
+	[ "$format" ] || format=-R
 	sec=${date[0]}; tz=${date[1]}
 	dtz=${tz/+/}
 	lsec=$(expr $dtz / 100 \* 3600 + $dtz % 100 \* 60 + $sec)
-	pdate="$(date -Rud "1970-01-01 UTC + $lsec sec" 2>/dev/null)"
+	pdate="$(date -ud "1970-01-01 UTC + $lsec sec" "$format" 2>/dev/null)"
 
 	echo "${pdate/+0000/$tz}"
 }
diff --git a/cg-log b/cg-log
--- a/cg-log
+++ b/cg-log
@@ -14,15 +14,21 @@
 # cg-log then displays only changes in those files.
 #
 # -c::
-#	Add color to the output. Currently, the colors are:
-#	- `author`:	'cyan'
-#	- `committer`:	'magenta'
-#	- `header`:	'green'
-#	- `files`:	'blue'
-#	- `signoff`:	'yellow'
+#	Colorize to the output. When getting log summary the `date` is
+#	colored 'green', the `author` is colored 'cyan', the `commit ID`
+#	is colored 'blue' and the special line trimming character (~) is
+#	colored 'magenta'. +
+#	+
+#	When getting the full log the colors are:
+#		- `author`:	'cyan'
+#		- `committer`:	'magenta'
+#		- `header`:	'green'
+#		- `files`:	'blue'
+#		- `signoff`:	'yellow'
 #
 # -f::
-#	List affected files.
+#	List affected files. This option does not make sense when using
+#	`-s` to get a log summary.
 #
 # -r FROM_ID[:TO_ID]::
 #	Limit the log information to a set of revisions using either
@@ -36,6 +42,12 @@
 #	End the log listing at the merge base of the -r arguments
 #	(defaulting to master and origin).
 #
+# -s::
+#	Show a one line summary for each log entry. The summary contains
+#	information about the commit date, the author, the first line
+#	of the commit log and the commit ID. Long author and commit log
+#	titles are trimmed but marked with an ending tilde (~).
+#
 # -uUSERNAME::
 #	List only commits where author or committer contains 'USERNAME'.
 #	The search for 'USERNAME' is case-insensitive.
@@ -55,7 +67,7 @@
 #
 #	$ cg-log -r releasetag-0.9:releasetag-0.10
 
-USAGE="cg-log [-c] [-f] [m] [-uUSERNAME] [-r FROM_ID[:TO_ID] FILE..."
+USAGE="cg-log [-c] [-f] [-m] [-s] [-uUSERNAME] [-r FROM_ID[:TO_ID] FILE..."
 
 . ${COGITO_LIB}cg-Xlib
 # Try to fix the annoying "Broken pipe" output. May not help, but apparently
@@ -71,6 +83,7 @@ coldefault=
 list_files=
 log_start=
 log_end=
+summary=
 user=
 mergebase=
 files=()
@@ -107,6 +120,9 @@ while [ "$1" ]; do
 	-m)
 		mergebase=1
 		;;
+	-s)
+		summary=1
+		;;
 	*)
 		files=("$@")
 		break
@@ -196,6 +212,8 @@ print_commit_log() {
 					echo -e "author $author\ncommitter $committer" \
 						| grep -qi "$user" || return
 				fi
+				[ "$summary" ] && continue
+
 				echo ${colheader}commit ${commit%:*} $coldefault
 				echo ${colheader}tree $tree $coldefault
 
@@ -222,6 +240,23 @@ print_commit_log() {
 					s/./    &/
 				'
 				;;
+			*)
+				# Print summary
+				author="${author% <*}"
+				date=(${committer#*> })
+				date="$(showdate $date '+%F %H:%M')"
+				title="$key $rest"
+				if [ "${#title}" -gt 51 ]; then
+					title="${title:0:50}$colcommitter~"
+				fi
+				if [ "${#author}" -gt 20 ]; then
+					author="${author:0:19}$colcommitter~"
+				fi
+
+				printf "$colheader$date $colauthor%-20s $coldefault%-51s $colfiles${commit%:*}$coldefault\n" \
+					"$author" "$title"
+				return
+				;;
 			esac
 		done
 }
@@ -232,6 +267,6 @@ $revls | $revsort | while read time comm
 	log="$(print_commit_log $commit)"
 	if [ "$log" ]; then
 		echo "$log"
-		echo
+		[ "$summary" ] || echo
 	fi
 done | pager
-- 
Jonas Fonseca

```
