threads / patch / 25489

v3, 12 partscat_file: take -i/-w parameters

Subject: [TopGit PATCH v3 02/12] cat_file: take -i/-w parameters

## tl;dr

12 messages between Oct 20, 2010 and Oct 20, 2010. Diffs are folded; open one to read it.

replies: 11people: 1as markdown or json

Bert Wesarg· Oct 20, 2010, 20:17 UTC · lore

[TopGit PATCH v3 01/12] provide a global temporary directory

The standard procedure 'tmp=mktemp; trap "rm $tmp" 0' was broken with the introduction of the pager. Which overwrites the trap itself to close and remove the pager fifo.

Now tg provides a temp playground and all other temp files should be created inside this directory and only this directory will be removed with the exit trap. setup_pager still overwrites the trap, but keeps the rm command from the global temp directory. To simplify this the new function get_temp() is provided.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 hooks/pre-commit.sh |    3 +--
 tg-export.sh        |    3 +--
 tg-info.sh          |    3 +--
 tg-mail.sh          |    4 +---
 tg-patch.sh         |    3 +--
 tg-push.sh          |    3 +--
 tg-summary.sh       |    3 +--
 tg-update.sh        |    3 +--
 tg.sh               |   27 +++++++++++++++++++--------
 9 files changed, 27 insertions(+), 25 deletions(-)
Show changes to 9 files +27 −25

hooks/pre-commit.sh, tg-export.sh, tg-info.sh, tg-mail.sh, tg-patch.sh, tg-push.sh, tg-summary.sh, tg-update.sh, tg.sh

diff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh
index 4f2f16f..c52a268 100644
--- a/hooks/pre-commit.sh
+++ b/hooks/pre-commit.sh
@@ -95,9 +95,8 @@ BEGIN      { in_hunk = 0; }
 	done
 
 # check for repetitions of deps
-depdir="$(mktemp -t -d tg-depdir.XXXXXX)" ||
+depdir="$(get_temp tg-depdir -d)" ||
 	die "Can't check for multiple occurrences of deps"
-trap "rm -rf '$depdir'" 0
 cat_file "(i):.topdeps" |
 	while read dep; do
 		[ ! -d "$depdir/$dep" ] ||
diff --git a/tg-export.sh b/tg-export.sh
index 6d82d55..921e933 100644
--- a/tg-export.sh
+++ b/tg-export.sh
@@ -57,8 +57,7 @@ if [ -z "$branches" ]; then
 fi
 
 
-playground="$(mktemp -d -t tg-export.XXXXXX)"
-trap 'rm -rf "$playground"' EXIT
+playground="$(get_temp tg-export -d)"
 
 
 ## Collapse driver
diff --git a/tg-info.sh b/tg-info.sh
index 7d6a34c..10e257e 100644
--- a/tg-info.sh
+++ b/tg-info.sh
@@ -51,7 +51,7 @@ fi
 git cat-file blob "$name:.topdeps" |
 	sed '1{ s/^/Depends: /; n; }; s/^/         /;'
 
-depcheck="$(mktemp -t tg-depcheck.XXXXXX)"
+depcheck="$(get_temp tg-depcheck)"
 missing_deps=
 needs_update "$name" >"$depcheck" || :
 if [ -n "$missing_deps" ]; then
@@ -72,6 +72,5 @@ if [ -s "$depcheck" ]; then
 else
 	echo "Up-to-date."
 fi
-rm "$depcheck"
 
 # vim:noet
diff --git a/tg-mail.sh b/tg-mail.sh
index 8167ade..dd4a95a 100644
--- a/tg-mail.sh
+++ b/tg-mail.sh
@@ -34,7 +34,7 @@ if [ -n "$in_reply_to" ]; then
 fi
 
 
-patchfile="$(mktemp -t tg-mail.XXXXXX)"
+patchfile="$(get_temp tg-mail)"
 
 $tg patch "$name" >"$patchfile"
 
@@ -54,6 +54,4 @@ people=
 # NOTE: git-send-email handles cc itself
 eval git send-email $send_email_args "$people" "$patchfile"
 
-rm "$patchfile"
-
 # vim:noet
diff --git a/tg-patch.sh b/tg-patch.sh
index 7bafdfe..68efcf0 100644
--- a/tg-patch.sh
+++ b/tg-patch.sh
@@ -51,7 +51,7 @@ 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="$(mktemp -t tg-patch-changes.XXXXXX)"
+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?
@@ -61,7 +61,6 @@ if [ -s "$git_is_stupid" ]; then
 else
 	echo "No changes."
 fi
-rm "$git_is_stupid"
 
 echo '-- '
 echo "tg: ($base_rev..) $name (depends on: $(cat_file "$topic:.topdeps" | paste -s -d' '))"
diff --git a/tg-push.sh b/tg-push.sh
index 199d738..a928fba 100644
--- a/tg-push.sh
+++ b/tg-push.sh
@@ -45,8 +45,7 @@ for name in $branches; do
 	ref_exists "$name" || die "detached HEAD? Can't push $name"
 done
 
-_listfile="$(mktemp -t tg-push-listfile.XXXXXX)"
-trap "rm -f \"$_listfile\"" 0
+_listfile="$(get_temp tg-push-listfile)"
 
 push_branch()
 {
diff --git a/tg-summary.sh b/tg-summary.sh
index af16888..612bd27 100644
--- a/tg-summary.sh
+++ b/tg-summary.sh
@@ -55,10 +55,9 @@ EOT
 fi
 
 if [ -n "$sort" ]; then
-	tsort_input=`mktemp`
+	tsort_input="$(get_temp tg-summary-sort)"
 	exec 4>$tsort_input
 	exec 5<$tsort_input
-	rm $tsort_input
 fi
 
 ## List branches
diff --git a/tg-update.sh b/tg-update.sh
index b256c7c..5162c52 100644
--- a/tg-update.sh
+++ b/tg-update.sh
@@ -27,7 +27,7 @@ base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)"
 
 ## First, take care of our base
 
-depcheck="$(mktemp -t tg-depcheck.XXXXXX)"
+depcheck="$(get_temp tg-depcheck)"
 missing_deps=
 needs_update "$name" >"$depcheck" || :
 [ -z "$missing_deps" ] || die "some dependencies are missing: $missing_deps"
@@ -96,7 +96,6 @@ if [ -s "$depcheck" ]; then
 else
 	info "The base is up-to-date."
 fi
-rm "$depcheck"
 
 # Home, sweet home...
 # (We want to always switch back, in case we were on the base from failed
diff --git a/tg.sh b/tg.sh
index 8264a3b..3805eeb 100644
--- a/tg.sh
+++ b/tg.sh
@@ -150,7 +150,7 @@ recurse_deps()
 	_name="$1"; # no shift
 	_depchain="$*"
 
-	_depsfile="$(mktemp -t tg-depsfile.XXXXXX)"
+	_depsfile="$(get_temp tg-depsfile)"
 	# If no_remotes is unset check also our base against remote base.
 	# Checking our head against remote head has to be done in the helper.
 	if test -z "$no_remotes" && has_remote "top-bases/$_name"; then
@@ -183,7 +183,6 @@ recurse_deps()
 		eval "$_cmd"
 	done <"$_depsfile"
 	missing_deps="${missing_deps# }"
-	rm "$_depsfile"
 	return $_ret
 }
 
@@ -334,19 +333,28 @@ setup_pager()
 	# now spawn pager
 	export LESS="${LESS:-FRSX}"	# as in pager.c:pager_preexec()
 
-	_pager_fifo_dir="$(mktemp -t -d tg-pager-fifo.XXXXXX)"
-	_pager_fifo="$_pager_fifo_dir/0"
-	mkfifo -m 600 "$_pager_fifo"
+	# setup_pager should be called only once per command
+	pager_fifo="$tg_tmp_dir/pager"
+	mkfifo -m 600 "$pager_fifo"
 
-	"$TG_PAGER" < "$_pager_fifo" &
-	exec > "$_pager_fifo"		# dup2(pager_fifo.in, 1)
+	"$TG_PAGER" < "$pager_fifo" &
+	exec > "$pager_fifo"		# dup2(pager_fifo.in, 1)
 
 	# this is needed so e.g. `git diff` will still colorize it's output if
 	# requested in ~/.gitconfig with color.diff=auto
 	export GIT_PAGER_IN_USE=1
 
 	# atexit(close(1); wait pager)
-	trap "exec >&-; rm \"$_pager_fifo\"; rmdir \"$_pager_fifo_dir\"; wait" EXIT
+	# deliberately overwrites the global EXIT trap
+	trap "exec >&-; rm -rf \"$tg_tmp_dir\"; wait" EXIT
+}
+
+# get_temp NAME [-d]
+# creates a new temporary file (or directory with -d) in the global
+# temporary directory $tg_tmp_dir with pattern prefix NAME
+get_temp()
+{
+	mktemp ${2-} "$tg_tmp_dir/$1.XXXXXX"
 }
 
 ## Startup
@@ -366,6 +374,9 @@ tg="tg"
 # make sure merging the .top* files will always behave sanely
 setup_ours
 setup_hook "pre-commit"
+# create global temporary directories, inside GIT_DIR
+tg_tmp_dir="$(mktemp -d "$git_dir/tg-tmp.XXXXXX")"
+trap "rm -rf \"$tg_tmp_dir\"" EXIT
 
 ## Dispatch
 
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

This changes the way how cat_file selects the source of the file. It accepts an optional parameter which is either -i or -w and will react on this instead of the branch name. tg-patch is updated accordingly and can now accepts the current branch name as argument with -i or -w given.

cat_file was also broken for the worktree case when we are not in the top level.

Also, tg-patch allowed to be on the top-base branch, but -i and -w doesn't make sense there too.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 hooks/pre-commit.sh |    2 +-
 tg-patch.sh         |   25 ++++++++++++++-----------
 tg.sh               |   23 ++++++++++++++---------
 3 files changed, 29 insertions(+), 21 deletions(-)
Show changes to 3 files +29 −21

hooks/pre-commit.sh, tg-patch.sh, tg.sh

diff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh
index c52a268..9519560 100644
--- a/hooks/pre-commit.sh
+++ b/hooks/pre-commit.sh
@@ -97,7 +97,7 @@ BEGIN      { in_hunk = 0; }
 # check for repetitions of deps
 depdir="$(get_temp tg-depdir -d)" ||
 	die "Can't check for multiple occurrences of deps"
-cat_file "(i):.topdeps" |
+cat_file "$head_:.topdeps" -i |
 	while read dep; do
 		[ ! -d "$depdir/$dep" ] ||
 			die "Multiple occurrences of the same dep: $dep"
diff --git a/tg-patch.sh b/tg-patch.sh
index 68efcf0..85346ec 100644
--- a/tg-patch.sh
+++ b/tg-patch.sh
@@ -5,7 +5,7 @@
 
 name=
 
-topic=
+head_from=
 diff_opts=
 diff_committed_only=yes	# will be unset for index/worktree
 
@@ -16,11 +16,13 @@ while [ -n "$1" ]; do
 	arg="$1"; shift
 	case "$arg" in
 	-i)
-		topic='(i)'
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from=-i
 		diff_opts="$diff_opts --cached";
 		diff_committed_only=;;
 	-w)
-		topic='(w)'
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from=-w
 		diff_committed_only=;;
 	-*)
 		echo "Usage: tg [...] patch [-i | -w] [NAME]" >&2
@@ -31,22 +33,23 @@ while [ -n "$1" ]; do
 	esac
 done
 
+head="$(git symbolic-ref HEAD)"
+head="${head#refs/heads/}"
 
-[ -n "$name"  -a  -z "$diff_committed_only" ]  &&
-	die "-i/-w are mutually exclusive with NAME"
-
-[ -n "$name" ] || name="$(git symbolic-ref HEAD | sed 's#^refs/\(heads\|top-bases\)/##')"
+[ -n "$name" ] ||
+	name="$head"
 base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" ||
 	die "not a TopGit-controlled branch"
 
-# if not index/worktree, topic is current branch
-[ -z "$topic" ] && topic="$name"
+if [ -n "$head_from" ] && [ "$name" != "$head" ]; then
+	die "$head_from makes only sense for the current branch"
+fi
 
 
 
 setup_pager
 
-cat_file "$topic:.topmsg"
+cat_file "$name:.topmsg" $head_from
 echo
 [ -n "$(git grep $diff_opts '^[-]--' ${diff_committed_only:+"$name"} -- ".topmsg")" ] || echo '---'
 
@@ -63,7 +66,7 @@ else
 fi
 
 echo '-- '
-echo "tg: ($base_rev..) $name (depends on: $(cat_file "$topic:.topdeps" | paste -s -d' '))"
+echo "tg: ($base_rev..) $name (depends on: $(cat_file "$name:.topdeps" $head_from | paste -s -d' '))"
 branch_contains "$name" "$base_rev" ||
 	echo "tg: The patch is out-of-date wrt. the base! Run \`$tg update\`."
 
diff --git a/tg.sh b/tg.sh
index 3805eeb..650ee59 100644
--- a/tg.sh
+++ b/tg.sh
@@ -18,21 +18,26 @@ die()
 	exit 1
 }
 
-# cat_file "topic:file"
-# Like `git cat-file blob $1`, but topics '(i)' and '(w)' means index and worktree
+# cat_file TOPIC:PATH [FROM]
+# cat the file PATH from branch TOPIC when FROM is empty.
+# FROM can be -i or -w, than the file will be from the index or worktree,
+# respectively. The caller should than ensure that HEAD is TOPIC, to make sense.
 cat_file()
 {
-	arg="$1"
-	case "$arg" in
-	'(w):'*)
-		cat "${arg#(w):}"
+	path="$1"
+	case "${2-}" in
+	-w)
+		cat "$root_dir/${path#*:}"
 		;;
-	'(i):'*)
+	-i)
 		# ':file' means cat from index
-		git cat-file blob "${arg#(i)}"
+		git cat-file blob ":${path#*:}"
+		;;
+	'')
+		git cat-file blob "$path"
 		;;
 	*)
-		git cat-file blob "$arg"
+		die "Wrong argument to cat_file: '$2'"
 		;;
 	esac
 }
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 03/12] pretty_tree: globalize and respect -i/-w options

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 tg-export.sh |   13 ++-----------
 tg.sh        |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 11 deletions(-)
Show changes to 2 files +49 −11

tg-export.sh, tg.sh

diff --git a/tg-export.sh b/tg-export.sh
index 921e933..486ec94 100644
--- a/tg-export.sh
+++ b/tg-export.sh
@@ -62,15 +62,6 @@ playground="$(get_temp tg-export -d)"
 
 ## Collapse driver
 
-# pretty_tree NAME
-# Output tree ID of a cleaned-up tree without tg's artifacts.
-pretty_tree()
-{
-	git ls-tree --full-tree "$1" \
-	| awk -F '	' '$2 !~ /^.top/' \
-	| git mktree
-}
-
 create_tg_commit()
 {
 	name="$1"
@@ -111,7 +102,7 @@ collapsed_commit()
 			echo "TopGit-driven merge of branches:"
 			echo
 			cut -f 2 "$playground/$name^parents"
-		} | git commit-tree "$(pretty_tree "refs/top-bases/$name")" \
+		} | git commit-tree "$(pretty_tree "$name" -b)" \
 			$(for p in $parent; do echo -p $p; done))"
 	fi
 
@@ -226,7 +217,7 @@ linearize()
 	else
 		retmerge=0;
 
-		git merge-recursive "$(pretty_tree "refs/top-bases/$_dep")" -- HEAD "$(pretty_tree "refs/heads/$_dep")" || retmerge="$?";
+		git merge-recursive "$(pretty_tree "$_dep" -b)" -- HEAD "$(pretty_tree "refs/heads/$_dep")" || retmerge="$?";
 
 		if test "x$retmerge" != "x0"; then
 			git rerere;
diff --git a/tg.sh b/tg.sh
index 650ee59..81cbf7d 100644
--- a/tg.sh
+++ b/tg.sh
@@ -42,6 +42,53 @@ cat_file()
 	esac
 }
 
+# get tree for the committed topic
+get_tree_()
+{
+	echo "$1"
+}
+
+# get tree for the base
+get_tree_b()
+{
+	echo "refs/top-bases/$1"
+}
+
+# get tree for the index
+get_tree_i()
+{
+	git write-tree
+}
+
+# get tree for the worktree
+get_tree_w()
+{
+	i_tree=$(git write-tree)
+	(
+		# the file for --index-output needs to sit next to the
+		# current index file
+		: ${GIT_INDEX_FILE:="$git_dir/index"}
+		TMP_INDEX="$(mktemp "${GIT_INDEX_FILE}-tg.XXXXXX")"
+		git read-tree -m $i_tree --index-output="$TMP_INDEX" &&
+		GIT_INDEX_FILE="$TMP_INDEX" &&
+		export GIT_INDEX_FILE &&
+		git diff --name-only -z HEAD |
+			git update-index -z --add --remove --stdin &&
+		git write-tree &&
+		rm -f "$TMP_INDEX"
+	)
+}
+
+# pretty_tree NAME [-b | -i | -w]
+# Output tree ID of a cleaned-up tree without tg's artifacts.
+# NAME will be ignored for -i and -w, but needs to be present
+pretty_tree()
+{
+	git ls-tree --full-tree "$(get_tree_${2#-} "$1")" |
+		awk -F '	' '$2 !~ /^.top/' |
+		git mktree
+}
+
 # setup_hook NAME
 setup_hook()
 {
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 04/12] branch_empty: use pretty_tree and therefore respect -i/-w

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 tg.sh |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Show changes to tg.sh +2 −2
diff --git a/tg.sh b/tg.sh
index 81cbf7d..949d2a4 100644
--- a/tg.sh
+++ b/tg.sh
@@ -282,10 +282,10 @@ needs_update()
 	recurse_deps branch_needs_update "$@"
 }
 
-# branch_empty NAME
+# branch_empty NAME [-i | -w]
 branch_empty()
 {
-	[ -z "$(git diff-tree "refs/top-bases/$1" "$1" -- | fgrep -v "	.top")" ]
+	[ "$(pretty_tree "$1" -b)" = "$(pretty_tree "$1" ${2-})" ]
 }
 
 # list_deps
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 05/12] tg-path: use pretty_tree and diff-tree to generate the patch

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 tg-patch.sh |   54 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 31 insertions(+), 23 deletions(-)
Show changes to tg-patch.sh +31 −23
diff --git a/tg-patch.sh b/tg-patch.sh
index 85346ec..9def6e5 100644
--- a/tg-patch.sh
+++ b/tg-patch.sh
@@ -6,8 +6,6 @@
 name=
 
 head_from=
-diff_opts=
-diff_committed_only=yes	# will be unset for index/worktree
 
 
 ## Parse options
@@ -15,15 +13,9 @@ diff_committed_only=yes	# will be unset for index/worktree
 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;;
@@ -49,20 +41,36 @@ fi
 
 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 '-- '
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 06/12] list_deps: accept -i/-w

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 tg.sh |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)
Show changes to tg.sh +9 −2
diff --git a/tg.sh b/tg.sh
index 949d2a4..4b6820b 100644
--- a/tg.sh
+++ b/tg.sh
@@ -288,9 +288,13 @@ branch_empty()
 	[ "$(pretty_tree "$1" -b)" = "$(pretty_tree "$1" ${2-})" ]
 }
 
-# list_deps
+# list_deps [-i | -w]
+# -i/-w apply only to HEAD
 list_deps()
 {
+	head="$(git symbolic-ref HEAD)"
+	head="${head#refs/heads/}"
+
 	git for-each-ref refs/top-bases |
 		while read rev type ref; do
 			name="${ref#refs/top-bases/}"
@@ -298,7 +302,10 @@ list_deps()
 				continue;
 			fi
 
-			git cat-file blob "$name:.topdeps" | while read dep; do
+			from=$head_from
+			[ "$name" = "$head" ] ||
+				from=
+			cat_file "$name:.topdeps" $from | while read dep; do
 				dep_is_tgish=true
 				ref_exists "refs/top-bases/$dep"  ||
 					dep_is_tgish=false
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 07/12] tg-summary: accept -i/-w

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 README                     |    4 ++++
 contrib/tg-completion.bash |    4 ++++
 tg-summary.sh              |   21 +++++++++++++++------
 3 files changed, 23 insertions(+), 6 deletions(-)
Show changes to 3 files +23 −6

README, contrib/tg-completion.bash, tg-summary.sh

diff --git a/README b/README
index 5ca0424..eea0d72 100644
--- a/README
+++ b/README
@@ -362,6 +362,10 @@ tg summary
 	branches in a machine-readable format.  Feed this to "tsort"
 	to get the output from --sort.
 
+	Options:
+	  -i		Use TopGit meta data from the index instead of branch
+	  -w		Use TopGit meta data from the working tree instead of branch
+
 	TODO: Speed up by an order of magnitude
 	TODO: Text graph view
 
diff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash
index ccf1a32..6a1e182 100755
--- a/contrib/tg-completion.bash
+++ b/contrib/tg-completion.bash
@@ -426,7 +426,11 @@ _tg_summary ()
 	*)
 		__tgcomp "
 			--graphviz
+			--sort
+			--deps
 			-t
+			-i
+			-w
 		"
 	esac
 }
diff --git a/tg-summary.sh b/tg-summary.sh
index 612bd27..1c99e22 100644
--- a/tg-summary.sh
+++ b/tg-summary.sh
@@ -7,13 +7,16 @@ terse=
 graphviz=
 sort=
 deps=
-
+head_from=
 
 ## Parse options
 
 while [ -n "$1" ]; do
 	arg="$1"; shift
 	case "$arg" in
+	-i|-w)
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from="$arg";;
 	-t)
 		terse=1;;
 	--graphviz)
@@ -23,7 +26,7 @@ while [ -n "$1" ]; do
 	--deps)
 		deps=1;;
 	*)
-		echo "Usage: tg [...] summary [-t | --sort | --deps | --graphviz]" >&2
+		echo "Usage: tg [...] summary [-t | --sort | --deps | --graphviz] [-i | -w]" >&2
 		exit 1;;
 	esac
 done
@@ -68,8 +71,11 @@ process_branch()
 
 	current=' '
 	[ "$name" != "$curname" ] || current='>'
+	from=$head_from
+	[ "$name" = "$curname" ] ||
+		from=
 	nonempty=' '
-	! branch_empty "$name" || nonempty='0'
+	! branch_empty "$name" $from || nonempty='0'
 	remote=' '
 	[ -z "$base_remote" ] || remote='l'
 	! has_remote "$name" || remote='r'
@@ -88,7 +94,7 @@ process_branch()
 	branch_contains "$name" "refs/top-bases/$name" || base_update='B'
 
 	if [ "$(git rev-parse "$name")" != "$rev" ]; then
-		subject="$(git cat-file blob "$name:.topmsg" | sed -n 's/^Subject: //p')"
+		subject="$(cat_file "$name:.topmsg" $from | sed -n 's/^Subject: //p')"
 	else
 		# No commits yet
 		subject="(No commits)"
@@ -99,7 +105,7 @@ process_branch()
 }
 
 if [ -n "$deps" ]; then
-	list_deps
+	list_deps $head_from
 	exit 0
 fi
 
@@ -113,7 +119,10 @@ git for-each-ref refs/top-bases |
 		if [ -n "$terse" ]; then
 			echo "$name"
 		elif [ -n "$graphviz$sort" ]; then
-			git cat-file blob "$name:.topdeps" | while read dep; do
+			from=$head_from
+			[ "$name" = "$curname" ] ||
+				from=
+			cat_file "$name:.topdeps" $from | while read dep; do
 				dep_is_tgish=true
 				ref_exists "refs/top-bases/$dep"  ||
 					dep_is_tgish=false
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 08/12] tg-mail: accept -i/-w

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 README                     |    4 ++++
 contrib/tg-completion.bash |    8 ++++++++
 tg-mail.sh                 |   12 +++++++++---
 3 files changed, 21 insertions(+), 3 deletions(-)
Show changes to 3 files +21 −3

README, contrib/tg-completion.bash, tg-mail.sh

diff --git a/README b/README
index eea0d72..538659a 100644
--- a/README
+++ b/README
@@ -315,6 +315,10 @@ tg mail
 
 	to let `git send-email` ask for confirmation before sending any mail.
 
+	Options:
+	  -i		base patch generation on index instead of branch
+	  -w		base patch generation on working tree instead of branch
+
 	TODO: 'tg mail patchfile' to mail an already exported patch
 	TODO: mailing patch series
 	TODO: specifying additional options and addresses on command
diff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash
index 6a1e182..b7051b8 100755
--- a/contrib/tg-completion.bash
+++ b/contrib/tg-completion.bash
@@ -359,6 +359,14 @@ _tg_mail ()
 	local cur="${COMP_WORDS[COMP_CWORD]}"
 
 	case "$cur" in
+	-*)
+		__tgcomp "
+			-i
+			-w
+			-s
+			-r
+		"
+		;;
 	*)
 		__tgcomp "$(__tg_topics)"
 	esac
diff --git a/tg-mail.sh b/tg-mail.sh
index dd4a95a..17ce02c 100644
--- a/tg-mail.sh
+++ b/tg-mail.sh
@@ -3,6 +3,7 @@
 # GPLv2
 
 name=
+head_from=
 send_email_args=
 in_reply_to=
 
@@ -12,12 +13,15 @@ in_reply_to=
 while [ -n "$1" ]; do
 	arg="$1"; shift
 	case "$arg" in
+	-i|-w)
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from="$arg";;
 	-s)
 		send_email_args="$1"; shift;;
 	-r)
 		in_reply_to="$1"; shift;;
 	-*)
-		echo "Usage: tg [...] mail [-s SEND_EMAIL_ARGS] [-r REFERENCE_MSGID] [NAME]" >&2
+		echo "Usage: tg [...] mail [-s SEND_EMAIL_ARGS] [-r REFERENCE_MSGID] [-i | -w] [NAME]" >&2
 		exit 1;;
 	*)
 		[ -z "$name" ] || die "name already specified ($name)"
@@ -25,7 +29,8 @@ while [ -n "$1" ]; do
 	esac
 done
 
-[ -n "$name" ] || name="$(git symbolic-ref HEAD | sed 's#^refs/heads/##')"
+head="$(git symbolic-ref HEAD | sed 's#^refs/heads/##')"
+[ -n "$name" ] || name="$head"
 base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" ||
 	die "not a TopGit-controlled branch"
 
@@ -36,7 +41,8 @@ fi
 
 patchfile="$(get_temp tg-mail)"
 
-$tg patch "$name" >"$patchfile"
+# let tg patch sort out whether $head_from makes sense for $name
+$tg patch "$name" $head_from >"$patchfile"
 
 header="$(sed -e '/^$/,$d' -e "s,','\\\\'',g" "$patchfile")"
 
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 09/12] tg-files: list files changed by the topic branch

this could also be a --name-only option to tg-patch. But I Like the similarity to 'quilt files'.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 .gitignore                 |    2 ++
 README                     |    8 ++++++++
 contrib/tg-completion.bash |    1 +
 tg-files.sh                |   43 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 54 insertions(+), 0 deletions(-)
 create mode 100644 tg-files.sh
Show changes to 4 files +54 −0

.gitignore, README, contrib/tg-completion.bash, tg-files.sh

diff --git a/.gitignore b/.gitignore
index 3298889..2a4d165 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,8 @@
 /tg-depend.txt
 /tg-export
 /tg-export.txt
+/tg-files
+/tg-files.txt
 /tg-import
 /tg-import.txt
 /tg-info
diff --git a/README b/README
index 538659a..c5a8ae0 100644
--- a/README
+++ b/README
@@ -533,6 +533,14 @@ tg log
 	repository, so you will not see work done by your
 	collaborators.
 
+tg files
+~~~~~~~~
+	List files changed by the current or specified topic branch.
+
+	Options:
+	  -i		list files based on index instead of branch
+	  -w		list files based on working tree instead of branch
+
 TODO: tg rename
 
 
diff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash
index b7051b8..ddc7655 100755
--- a/contrib/tg-completion.bash
+++ b/contrib/tg-completion.bash
@@ -494,6 +494,7 @@ _tg ()
 	delete)      _tg_delete ;;
 	depend)      _tg_depend ;;
 	export)      _tg_export ;;
+	files)       _tg_patch ;;
 	help)        _tg_help ;;
 	import)      _tg_import ;;
 	info)        _tg_info ;;
diff --git a/tg-files.sh b/tg-files.sh
new file mode 100644
index 0000000..ab97624
--- /dev/null
+++ b/tg-files.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+# TopGit - A different patch queue manager
+# (c) Petr Baudis <pasky@suse.cz>  2008
+# GPLv2
+
+name=
+head_from=
+
+
+## Parse options
+
+while [ -n "$1" ]; do
+	arg="$1"; shift
+	case "$arg" in
+	-i|-w)
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from="$arg";;
+	-*)
+		echo "Usage: tg [...] files [-i | -w] [NAME]" >&2
+		exit 1;;
+	*)
+		[ -z "$name" ] || die "name already specified ($name)"
+		name="$arg";;
+	esac
+done
+
+
+head="$(git symbolic-ref HEAD)"
+head="${head#refs/heads/}"
+
+[ -n "$name" ] ||
+	name="$head"
+base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" ||
+	die "not a TopGit-controlled branch"
+
+if [ -n "$head_from" ] && [ "$name" != "$head" ]; then
+	die "$head_from makes only sense for the current branch"
+fi
+
+b_tree=$(pretty_tree "$name" -b)
+t_tree=$(pretty_tree "$name" $head_from)
+
+git diff-tree --name-only -r $b_tree $t_tree
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit PATCH v3 10/12] tg-prev/tg-next: commands to explore dependencies

Two new commands to explore the dependencies of TopGit branches:
  a) tg prev [-i | -w] [NAME]
     outputs the dependencies of NAME
  b) tg next [-i | -w] [NAME]
     outputs branches which depends on NAME
Obviously, quilt next was the inspiration.
Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 .gitignore                 |    4 +++
 README                     |   18 ++++++++++++++++-
 contrib/tg-completion.bash |   34 +++++++++++++++++++++++++++++++++
 tg-next.sh                 |   45 ++++++++++++++++++++++++++++++++++++++++++++
 tg-prev.sh                 |   38 +++++++++++++++++++++++++++++++++++++
 5 files changed, 138 insertions(+), 1 deletions(-)
 create mode 100644 tg-next.sh
 create mode 100644 tg-prev.sh
Show changes to 5 files +138 −1

.gitignore, README, contrib/tg-completion.bash, tg-next.sh, tg-prev.sh

diff --git a/.gitignore b/.gitignore
index 2a4d165..6cfab6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,10 +30,14 @@
 /tg-info.txt
 /tg-mail
 /tg-mail.txt
+/tg-next
+/tg-next.txt
 /tg-log
 /tg-log.txt
 /tg-patch
 /tg-patch.txt
+/tg-prev
+/tg-prev.txt
 /tg-push
 /tg-push.txt
 /tg-remote
diff --git a/README b/README
index c5a8ae0..7760218 100644
--- a/README
+++ b/README
@@ -541,8 +541,24 @@ tg files
 	  -i		list files based on index instead of branch
 	  -w		list files based on working tree instead of branch
 
-TODO: tg rename
+tg prev
+~~~~~~~
+	Outputs the direct dependencies for the current or named patch.
 
+	Options:
+	  -i		show dependencies based on index instead of branch
+	  -w		show dependencies based on working tree instead of branch
+
+tg next
+~~~~~~~
+	Outputs all patches which directly depend on the current or
+	named patch.
+
+	Options:
+	  -i		show dependencies based on index instead of branch
+	  -w		show dependencies based on working tree instead of branch
+
+TODO: tg rename
 
 IMPLEMENTATION
 --------------
diff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash
index ddc7655..e34b66f 100755
--- a/contrib/tg-completion.bash
+++ b/contrib/tg-completion.bash
@@ -453,6 +453,38 @@ _tg_update ()
 	esac
 }
 
+_tg_next ()
+{
+	local cur="${COMP_WORDS[COMP_CWORD]}"
+
+	case "$cur" in
+	-*)
+		__tgcomp "
+			-i
+			-w
+		"
+		;;
+	*)
+		__tgcomp "$(__tg_heads)"
+	esac
+}
+
+_tg_prev ()
+{
+	local cur="${COMP_WORDS[COMP_CWORD]}"
+
+	case "$cur" in
+	-*)
+		__tgcomp "
+			-i
+			-w
+		"
+		;;
+	*)
+		__tgcomp "$(__tg_topics)"
+	esac
+}
+
 ### }}}
 ### {{{ tg completion
 
@@ -500,7 +532,9 @@ _tg ()
 	info)        _tg_info ;;
 	log)         _tg_log ;;
 	mail)        _tg_mail ;;
+	next)        _tg_next ;;
 	patch)       _tg_patch ;;
+	prev)        _tg_prev ;;
 	push)        _tg_push ;;
 	remote)      _tg_remote ;;
 	summary)     _tg_summary ;;
diff --git a/tg-next.sh b/tg-next.sh
new file mode 100644
index 0000000..93dd5b5
--- /dev/null
+++ b/tg-next.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# TopGit - A different patch queue manager
+# (c) Petr Baudis <pasky@suse.cz>  2008
+# (c) Bert Wesarg <Bert.Wesarg@googlemail.com>  2009
+# GPLv2
+
+name=
+head_from=
+
+
+## Parse options
+
+while [ -n "$1" ]; do
+	arg="$1"; shift
+	case "$arg" in
+	-i|-w)
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from="$arg";;
+	-*)
+		echo "Usage: tg next [-i | -w] [NAME]" >&2
+		exit 1;;
+	*)
+		[ -z "$name" ] || die "name already specified ($name)"
+		name="$arg";;
+	esac
+done
+
+head="$(git rev-parse --abbrev-ref=loose HEAD)"
+[ -n "$name" ] ||
+	name="$head"
+
+git for-each-ref --format='%(refname)' refs/top-bases |
+	while read ref; do
+		parent="${ref#refs/top-bases/}"
+
+		from=$head_from
+		# select .topdeps source for HEAD branch
+		[ "x$parent" = "x$head" ] ||
+			from=
+
+		cat_file "$parent:.topdeps" $from | fgrep -qx "$name" ||
+			continue
+
+		echo "$parent"
+	done
diff --git a/tg-prev.sh b/tg-prev.sh
new file mode 100644
index 0000000..1f1e0c1
--- /dev/null
+++ b/tg-prev.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# TopGit - A different patch queue manager
+# (c) Petr Baudis <pasky@suse.cz>  2008
+# (c) Bert Wesarg <Bert.Wesarg@googlemail.com>  2009
+# GPLv2
+
+name=
+head_from=
+
+
+## Parse options
+
+while [ -n "$1" ]; do
+	arg="$1"; shift
+	case "$arg" in
+	-i|-w)
+		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
+		head_from="$arg";;
+	-*)
+		echo "Usage: tg next [-i | -w] [NAME]" >&2
+		exit 1;;
+	*)
+		[ -z "$name" ] || die "name already specified ($name)"
+		name="$arg";;
+	esac
+done
+
+head="$(git rev-parse --abbrev-ref=loose HEAD)"
+[ -n "$name" ] ||
+	name="$head"
+base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" ||
+	die "not a TopGit-controlled branch"
+
+# select .topdeps source for HEAD branch
+[ "x$name" = "x$head" ] ||
+	head_from=
+
+cat_file "$name:.topdeps" $head_from
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit RFC/PATCH v3 11/12] tg-patch: use ui diff when pager is active

diff-tree should be used to generate patches meant for submission (or non-human consumption). But for pure human inspection some 'eye-candy' effects could take considerations. Like color, renames, mnemonicprefix, or noprefix. External diff driver or word-diff. All these are in effect by using the diff command, when configured in your git config file. diff-tree does not honor these configure options but its possible to give them as command line options too. Selecting the plumbing or ui diff driver is best done automatically, in my opinion. And an active pager is my best bet that a human will consume the output.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---

I will probably add an overwrite command switch (to enable ui mode even without an active pager shortly. Because I sometimes pipe the output for inspection into my editor.

 tg-patch.sh |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
Show changes to tg-patch.sh +6 −1
diff --git a/tg-patch.sh b/tg-patch.sh
index 9def6e5..dcce672 100644
--- a/tg-patch.sh
+++ b/tg-patch.sh
@@ -70,7 +70,12 @@ 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
+	# use the ui diff command when the pager is active
+	diff_command=diff
+	[ "x$GIT_PAGER_IN_USE" = "x1" ] ||
+		diff_command=diff-tree
+
+	git $diff_command -p --stat $b_tree $t_tree
 fi
 
 echo '-- '
-- 
1.7.3.1.1069.g89486
Bert Wesarg· Oct 20, 2010, 20:17 UTC · re: Bert Wesarg · lore

[TopGit RFC/PATCH v3 12/12] tg-patch: simulate mnemonic prefixes

b/ is for base, i/ and w/ correspond to -i/-w and t/ is the committed topic.

diff.mnemonicprefix needs to be set to true. See git-config(1) for more information.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---
 tg-patch.sh |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
Show changes to tg-patch.sh +6 −2
diff --git a/tg-patch.sh b/tg-patch.sh
index dcce672..c8ad723 100644
--- a/tg-patch.sh
+++ b/tg-patch.sh
@@ -6,7 +6,7 @@
 name=
 
 head_from=
-
+dst_prefix="t/"
 
 ## Parse options
 
@@ -15,7 +15,8 @@ while [ -n "$1" ]; do
 	case "$arg" in
 	-i|-w)
 		[ -z "$head_from" ] || die "-i and -w are mutually exclusive"
-		head_from="$arg";;
+		head_from="$arg"
+		dst_prefix="${arg#-}/";;
 	-*)
 		echo "Usage: tg [...] patch [-i | -w] [NAME]" >&2
 		exit 1;;
@@ -72,6 +73,9 @@ if [ $b_tree = $t_tree ]; then
 else
 	# use the ui diff command when the pager is active
 	diff_command=diff
+	if $(git config --bool diff.mnemonicprefix); then
+		diff_command="$diff_command --src-prefix=b/ --dst-prefix=$dst_prefix"
+	fi
 	[ "x$GIT_PAGER_IN_USE" = "x1" ] ||
 		diff_command=diff-tree
 
-- 
1.7.3.1.1069.g89486

← back to recent threads