{"thread":{"id":"25489","subject":"[TopGit PATCH v3 02/12] cat_file: take -i/-w parameters","startedAt":"2010-10-20T20:17:46Z","lastAt":"2010-10-20T20:17:57Z","messageCount":12,"participants":["Bert Wesarg"],"isPatch":true,"patchVersion":3,"patchTotal":12},"messages":[{"id":"153891","messageId":"52df5d1de969f474d93c4dce320edc657bb866dc.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":null,"subject":"[TopGit PATCH v3 01/12] provide a global temporary directory","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:46Z","receivedAt":"2010-10-20T20:17:46Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"The standard procedure 'tmp=mktemp; trap \"rm $tmp\" 0' was broken with the\nintroduction of the pager. Which overwrites the trap itself to close and\nremove the pager fifo.\n\nNow tg provides a temp playground and all other temp files should be created\ninside this directory and only this directory will be removed with the exit\ntrap. setup_pager still overwrites the trap, but keeps the rm command from\nthe global temp directory. To simplify this the new function get_temp() is\nprovided.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n hooks/pre-commit.sh |    3 +--\n tg-export.sh        |    3 +--\n tg-info.sh          |    3 +--\n tg-mail.sh          |    4 +---\n tg-patch.sh         |    3 +--\n tg-push.sh          |    3 +--\n tg-summary.sh       |    3 +--\n tg-update.sh        |    3 +--\n tg.sh               |   27 +++++++++++++++++++--------\n 9 files changed, 27 insertions(+), 25 deletions(-)\n\ndiff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh\nindex 4f2f16f..c52a268 100644\n--- a/hooks/pre-commit.sh\n+++ b/hooks/pre-commit.sh\n@@ -95,9 +95,8 @@ BEGIN      { in_hunk = 0; }\n \tdone\n \n # check for repetitions of deps\n-depdir=\"$(mktemp -t -d tg-depdir.XXXXXX)\" ||\n+depdir=\"$(get_temp tg-depdir -d)\" ||\n \tdie \"Can't check for multiple occurrences of deps\"\n-trap \"rm -rf '$depdir'\" 0\n cat_file \"(i):.topdeps\" |\n \twhile read dep; do\n \t\t[ ! -d \"$depdir/$dep\" ] ||\ndiff --git a/tg-export.sh b/tg-export.sh\nindex 6d82d55..921e933 100644\n--- a/tg-export.sh\n+++ b/tg-export.sh\n@@ -57,8 +57,7 @@ if [ -z \"$branches\" ]; then\n fi\n \n \n-playground=\"$(mktemp -d -t tg-export.XXXXXX)\"\n-trap 'rm -rf \"$playground\"' EXIT\n+playground=\"$(get_temp tg-export -d)\"\n \n \n ## Collapse driver\ndiff --git a/tg-info.sh b/tg-info.sh\nindex 7d6a34c..10e257e 100644\n--- a/tg-info.sh\n+++ b/tg-info.sh\n@@ -51,7 +51,7 @@ fi\n git cat-file blob \"$name:.topdeps\" |\n \tsed '1{ s/^/Depends: /; n; }; s/^/         /;'\n \n-depcheck=\"$(mktemp -t tg-depcheck.XXXXXX)\"\n+depcheck=\"$(get_temp tg-depcheck)\"\n missing_deps=\n needs_update \"$name\" >\"$depcheck\" || :\n if [ -n \"$missing_deps\" ]; then\n@@ -72,6 +72,5 @@ if [ -s \"$depcheck\" ]; then\n else\n \techo \"Up-to-date.\"\n fi\n-rm \"$depcheck\"\n \n # vim:noet\ndiff --git a/tg-mail.sh b/tg-mail.sh\nindex 8167ade..dd4a95a 100644\n--- a/tg-mail.sh\n+++ b/tg-mail.sh\n@@ -34,7 +34,7 @@ if [ -n \"$in_reply_to\" ]; then\n fi\n \n \n-patchfile=\"$(mktemp -t tg-mail.XXXXXX)\"\n+patchfile=\"$(get_temp tg-mail)\"\n \n $tg patch \"$name\" >\"$patchfile\"\n \n@@ -54,6 +54,4 @@ people=\n # NOTE: git-send-email handles cc itself\n eval git send-email $send_email_args \"$people\" \"$patchfile\"\n \n-rm \"$patchfile\"\n-\n # vim:noet\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex 7bafdfe..68efcf0 100644\n--- a/tg-patch.sh\n+++ b/tg-patch.sh\n@@ -51,7 +51,7 @@ echo\n [ -n \"$(git grep $diff_opts '^[-]--' ${diff_committed_only:+\"$name\"} -- \".topmsg\")\" ] || echo '---'\n \n # Evil obnoxious hack to work around the lack of git diff --exclude\n-git_is_stupid=\"$(mktemp -t tg-patch-changes.XXXXXX)\"\n+git_is_stupid=\"$(get_temp tg-patch-changes)\"\n git diff --name-only $diff_opts \"$base_rev\" ${diff_committed_only:+\"$name\"} -- |\n \tfgrep -vx \".topdeps\" |\n \tfgrep -vx \".topmsg\" >\"$git_is_stupid\" || : # fgrep likes to fail randomly?\n@@ -61,7 +61,6 @@ if [ -s \"$git_is_stupid\" ]; then\n else\n \techo \"No changes.\"\n fi\n-rm \"$git_is_stupid\"\n \n echo '-- '\n echo \"tg: ($base_rev..) $name (depends on: $(cat_file \"$topic:.topdeps\" | paste -s -d' '))\"\ndiff --git a/tg-push.sh b/tg-push.sh\nindex 199d738..a928fba 100644\n--- a/tg-push.sh\n+++ b/tg-push.sh\n@@ -45,8 +45,7 @@ for name in $branches; do\n \tref_exists \"$name\" || die \"detached HEAD? Can't push $name\"\n done\n \n-_listfile=\"$(mktemp -t tg-push-listfile.XXXXXX)\"\n-trap \"rm -f \\\"$_listfile\\\"\" 0\n+_listfile=\"$(get_temp tg-push-listfile)\"\n \n push_branch()\n {\ndiff --git a/tg-summary.sh b/tg-summary.sh\nindex af16888..612bd27 100644\n--- a/tg-summary.sh\n+++ b/tg-summary.sh\n@@ -55,10 +55,9 @@ EOT\n fi\n \n if [ -n \"$sort\" ]; then\n-\ttsort_input=`mktemp`\n+\ttsort_input=\"$(get_temp tg-summary-sort)\"\n \texec 4>$tsort_input\n \texec 5<$tsort_input\n-\trm $tsort_input\n fi\n \n ## List branches\ndiff --git a/tg-update.sh b/tg-update.sh\nindex b256c7c..5162c52 100644\n--- a/tg-update.sh\n+++ b/tg-update.sh\n@@ -27,7 +27,7 @@ base_rev=\"$(git rev-parse --short --verify \"refs/top-bases/$name\" 2>/dev/null)\"\n \n ## First, take care of our base\n \n-depcheck=\"$(mktemp -t tg-depcheck.XXXXXX)\"\n+depcheck=\"$(get_temp tg-depcheck)\"\n missing_deps=\n needs_update \"$name\" >\"$depcheck\" || :\n [ -z \"$missing_deps\" ] || die \"some dependencies are missing: $missing_deps\"\n@@ -96,7 +96,6 @@ if [ -s \"$depcheck\" ]; then\n else\n \tinfo \"The base is up-to-date.\"\n fi\n-rm \"$depcheck\"\n \n # Home, sweet home...\n # (We want to always switch back, in case we were on the base from failed\ndiff --git a/tg.sh b/tg.sh\nindex 8264a3b..3805eeb 100644\n--- a/tg.sh\n+++ b/tg.sh\n@@ -150,7 +150,7 @@ recurse_deps()\n \t_name=\"$1\"; # no shift\n \t_depchain=\"$*\"\n \n-\t_depsfile=\"$(mktemp -t tg-depsfile.XXXXXX)\"\n+\t_depsfile=\"$(get_temp tg-depsfile)\"\n \t# If no_remotes is unset check also our base against remote base.\n \t# Checking our head against remote head has to be done in the helper.\n \tif test -z \"$no_remotes\" && has_remote \"top-bases/$_name\"; then\n@@ -183,7 +183,6 @@ recurse_deps()\n \t\teval \"$_cmd\"\n \tdone <\"$_depsfile\"\n \tmissing_deps=\"${missing_deps# }\"\n-\trm \"$_depsfile\"\n \treturn $_ret\n }\n \n@@ -334,19 +333,28 @@ setup_pager()\n \t# now spawn pager\n \texport LESS=\"${LESS:-FRSX}\"\t# as in pager.c:pager_preexec()\n \n-\t_pager_fifo_dir=\"$(mktemp -t -d tg-pager-fifo.XXXXXX)\"\n-\t_pager_fifo=\"$_pager_fifo_dir/0\"\n-\tmkfifo -m 600 \"$_pager_fifo\"\n+\t# setup_pager should be called only once per command\n+\tpager_fifo=\"$tg_tmp_dir/pager\"\n+\tmkfifo -m 600 \"$pager_fifo\"\n \n-\t\"$TG_PAGER\" < \"$_pager_fifo\" &\n-\texec > \"$_pager_fifo\"\t\t# dup2(pager_fifo.in, 1)\n+\t\"$TG_PAGER\" < \"$pager_fifo\" &\n+\texec > \"$pager_fifo\"\t\t# dup2(pager_fifo.in, 1)\n \n \t# this is needed so e.g. `git diff` will still colorize it's output if\n \t# requested in ~/.gitconfig with color.diff=auto\n \texport GIT_PAGER_IN_USE=1\n \n \t# atexit(close(1); wait pager)\n-\ttrap \"exec >&-; rm \\\"$_pager_fifo\\\"; rmdir \\\"$_pager_fifo_dir\\\"; wait\" EXIT\n+\t# deliberately overwrites the global EXIT trap\n+\ttrap \"exec >&-; rm -rf \\\"$tg_tmp_dir\\\"; wait\" EXIT\n+}\n+\n+# get_temp NAME [-d]\n+# creates a new temporary file (or directory with -d) in the global\n+# temporary directory $tg_tmp_dir with pattern prefix NAME\n+get_temp()\n+{\n+\tmktemp ${2-} \"$tg_tmp_dir/$1.XXXXXX\"\n }\n \n ## Startup\n@@ -366,6 +374,9 @@ tg=\"tg\"\n # make sure merging the .top* files will always behave sanely\n setup_ours\n setup_hook \"pre-commit\"\n+# create global temporary directories, inside GIT_DIR\n+tg_tmp_dir=\"$(mktemp -d \"$git_dir/tg-tmp.XXXXXX\")\"\n+trap \"rm -rf \\\"$tg_tmp_dir\\\"\" EXIT\n \n ## Dispatch\n \n-- \n1.7.3.1.1069.g89486\n"},{"id":"153883","messageId":"38d2d7e3ba54cea256bc111f50bcb8d35e7d520d.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"52df5d1de969f474d93c4dce320edc657bb866dc.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 02/12] cat_file: take -i/-w parameters","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:47Z","receivedAt":"2010-10-20T20:17:47Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"This changes the way how cat_file selects the source of the file. It\naccepts an optional parameter which is either -i or -w and will react on this\ninstead of the branch name. tg-patch is updated accordingly and can now\naccepts the current branch name as argument with -i or -w given.\n\ncat_file was also broken for the worktree case when we are not in the top level.\n\nAlso, tg-patch allowed to be on the top-base branch, but -i and -w doesn't\nmake sense there too.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n\n---\n hooks/pre-commit.sh |    2 +-\n tg-patch.sh         |   25 ++++++++++++++-----------\n tg.sh               |   23 ++++++++++++++---------\n 3 files changed, 29 insertions(+), 21 deletions(-)\n\ndiff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh\nindex c52a268..9519560 100644\n--- a/hooks/pre-commit.sh\n+++ b/hooks/pre-commit.sh\n@@ -97,7 +97,7 @@ BEGIN      { in_hunk = 0; }\n # check for repetitions of deps\n depdir=\"$(get_temp tg-depdir -d)\" ||\n \tdie \"Can't check for multiple occurrences of deps\"\n-cat_file \"(i):.topdeps\" |\n+cat_file \"$head_:.topdeps\" -i |\n \twhile read dep; do\n \t\t[ ! -d \"$depdir/$dep\" ] ||\n \t\t\tdie \"Multiple occurrences of the same dep: $dep\"\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex 68efcf0..85346ec 100644\n--- a/tg-patch.sh\n+++ b/tg-patch.sh\n@@ -5,7 +5,7 @@\n \n name=\n \n-topic=\n+head_from=\n diff_opts=\n diff_committed_only=yes\t# will be unset for index/worktree\n \n@@ -16,11 +16,13 @@ while [ -n \"$1\" ]; do\n \targ=\"$1\"; shift\n \tcase \"$arg\" in\n \t-i)\n-\t\ttopic='(i)'\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=-i\n \t\tdiff_opts=\"$diff_opts --cached\";\n \t\tdiff_committed_only=;;\n \t-w)\n-\t\ttopic='(w)'\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=-w\n \t\tdiff_committed_only=;;\n \t-*)\n \t\techo \"Usage: tg [...] patch [-i | -w] [NAME]\" >&2\n@@ -31,22 +33,23 @@ while [ -n \"$1\" ]; do\n \tesac\n done\n \n+head=\"$(git symbolic-ref HEAD)\"\n+head=\"${head#refs/heads/}\"\n \n-[ -n \"$name\"  -a  -z \"$diff_committed_only\" ]  &&\n-\tdie \"-i/-w are mutually exclusive with NAME\"\n-\n-[ -n \"$name\" ] || name=\"$(git symbolic-ref HEAD | sed 's#^refs/\\(heads\\|top-bases\\)/##')\"\n+[ -n \"$name\" ] ||\n+\tname=\"$head\"\n base_rev=\"$(git rev-parse --short --verify \"refs/top-bases/$name\" 2>/dev/null)\" ||\n \tdie \"not a TopGit-controlled branch\"\n \n-# if not index/worktree, topic is current branch\n-[ -z \"$topic\" ] && topic=\"$name\"\n+if [ -n \"$head_from\" ] && [ \"$name\" != \"$head\" ]; then\n+\tdie \"$head_from makes only sense for the current branch\"\n+fi\n \n \n \n setup_pager\n \n-cat_file \"$topic:.topmsg\"\n+cat_file \"$name:.topmsg\" $head_from\n echo\n [ -n \"$(git grep $diff_opts '^[-]--' ${diff_committed_only:+\"$name\"} -- \".topmsg\")\" ] || echo '---'\n \n@@ -63,7 +66,7 @@ else\n fi\n \n echo '-- '\n-echo \"tg: ($base_rev..) $name (depends on: $(cat_file \"$topic:.topdeps\" | paste -s -d' '))\"\n+echo \"tg: ($base_rev..) $name (depends on: $(cat_file \"$name:.topdeps\" $head_from | paste -s -d' '))\"\n branch_contains \"$name\" \"$base_rev\" ||\n \techo \"tg: The patch is out-of-date wrt. the base! Run \\`$tg update\\`.\"\n \ndiff --git a/tg.sh b/tg.sh\nindex 3805eeb..650ee59 100644\n--- a/tg.sh\n+++ b/tg.sh\n@@ -18,21 +18,26 @@ die()\n \texit 1\n }\n \n-# cat_file \"topic:file\"\n-# Like `git cat-file blob $1`, but topics '(i)' and '(w)' means index and worktree\n+# cat_file TOPIC:PATH [FROM]\n+# cat the file PATH from branch TOPIC when FROM is empty.\n+# FROM can be -i or -w, than the file will be from the index or worktree,\n+# respectively. The caller should than ensure that HEAD is TOPIC, to make sense.\n cat_file()\n {\n-\targ=\"$1\"\n-\tcase \"$arg\" in\n-\t'(w):'*)\n-\t\tcat \"${arg#(w):}\"\n+\tpath=\"$1\"\n+\tcase \"${2-}\" in\n+\t-w)\n+\t\tcat \"$root_dir/${path#*:}\"\n \t\t;;\n-\t'(i):'*)\n+\t-i)\n \t\t# ':file' means cat from index\n-\t\tgit cat-file blob \"${arg#(i)}\"\n+\t\tgit cat-file blob \":${path#*:}\"\n+\t\t;;\n+\t'')\n+\t\tgit cat-file blob \"$path\"\n \t\t;;\n \t*)\n-\t\tgit cat-file blob \"$arg\"\n+\t\tdie \"Wrong argument to cat_file: '$2'\"\n \t\t;;\n \tesac\n }\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153885","messageId":"b00fdc4e3060b7cf9f1ed25caff16799df09e414.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"38d2d7e3ba54cea256bc111f50bcb8d35e7d520d.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 03/12] pretty_tree: globalize and respect -i/-w options","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:48Z","receivedAt":"2010-10-20T20:17:48Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n tg-export.sh |   13 ++-----------\n tg.sh        |   47 +++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 49 insertions(+), 11 deletions(-)\n\ndiff --git a/tg-export.sh b/tg-export.sh\nindex 921e933..486ec94 100644\n--- a/tg-export.sh\n+++ b/tg-export.sh\n@@ -62,15 +62,6 @@ playground=\"$(get_temp tg-export -d)\"\n \n ## Collapse driver\n \n-# pretty_tree NAME\n-# Output tree ID of a cleaned-up tree without tg's artifacts.\n-pretty_tree()\n-{\n-\tgit ls-tree --full-tree \"$1\" \\\n-\t| awk -F '\t' '$2 !~ /^.top/' \\\n-\t| git mktree\n-}\n-\n create_tg_commit()\n {\n \tname=\"$1\"\n@@ -111,7 +102,7 @@ collapsed_commit()\n \t\t\techo \"TopGit-driven merge of branches:\"\n \t\t\techo\n \t\t\tcut -f 2 \"$playground/$name^parents\"\n-\t\t} | git commit-tree \"$(pretty_tree \"refs/top-bases/$name\")\" \\\n+\t\t} | git commit-tree \"$(pretty_tree \"$name\" -b)\" \\\n \t\t\t$(for p in $parent; do echo -p $p; done))\"\n \tfi\n \n@@ -226,7 +217,7 @@ linearize()\n \telse\n \t\tretmerge=0;\n \n-\t\tgit merge-recursive \"$(pretty_tree \"refs/top-bases/$_dep\")\" -- HEAD \"$(pretty_tree \"refs/heads/$_dep\")\" || retmerge=\"$?\";\n+\t\tgit merge-recursive \"$(pretty_tree \"$_dep\" -b)\" -- HEAD \"$(pretty_tree \"refs/heads/$_dep\")\" || retmerge=\"$?\";\n \n \t\tif test \"x$retmerge\" != \"x0\"; then\n \t\t\tgit rerere;\ndiff --git a/tg.sh b/tg.sh\nindex 650ee59..81cbf7d 100644\n--- a/tg.sh\n+++ b/tg.sh\n@@ -42,6 +42,53 @@ cat_file()\n \tesac\n }\n \n+# get tree for the committed topic\n+get_tree_()\n+{\n+\techo \"$1\"\n+}\n+\n+# get tree for the base\n+get_tree_b()\n+{\n+\techo \"refs/top-bases/$1\"\n+}\n+\n+# get tree for the index\n+get_tree_i()\n+{\n+\tgit write-tree\n+}\n+\n+# get tree for the worktree\n+get_tree_w()\n+{\n+\ti_tree=$(git write-tree)\n+\t(\n+\t\t# the file for --index-output needs to sit next to the\n+\t\t# current index file\n+\t\t: ${GIT_INDEX_FILE:=\"$git_dir/index\"}\n+\t\tTMP_INDEX=\"$(mktemp \"${GIT_INDEX_FILE}-tg.XXXXXX\")\"\n+\t\tgit read-tree -m $i_tree --index-output=\"$TMP_INDEX\" &&\n+\t\tGIT_INDEX_FILE=\"$TMP_INDEX\" &&\n+\t\texport GIT_INDEX_FILE &&\n+\t\tgit diff --name-only -z HEAD |\n+\t\t\tgit update-index -z --add --remove --stdin &&\n+\t\tgit write-tree &&\n+\t\trm -f \"$TMP_INDEX\"\n+\t)\n+}\n+\n+# pretty_tree NAME [-b | -i | -w]\n+# Output tree ID of a cleaned-up tree without tg's artifacts.\n+# NAME will be ignored for -i and -w, but needs to be present\n+pretty_tree()\n+{\n+\tgit ls-tree --full-tree \"$(get_tree_${2#-} \"$1\")\" |\n+\t\tawk -F '\t' '$2 !~ /^.top/' |\n+\t\tgit mktree\n+}\n+\n # setup_hook NAME\n setup_hook()\n {\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153884","messageId":"d9fc8653e6e4c7eb7197a0fb92cd3b8c6e058187.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"b00fdc4e3060b7cf9f1ed25caff16799df09e414.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 04/12] branch_empty: use pretty_tree and therefore respect -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:49Z","receivedAt":"2010-10-20T20:17:49Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n tg.sh |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/tg.sh b/tg.sh\nindex 81cbf7d..949d2a4 100644\n--- a/tg.sh\n+++ b/tg.sh\n@@ -282,10 +282,10 @@ needs_update()\n \trecurse_deps branch_needs_update \"$@\"\n }\n \n-# branch_empty NAME\n+# branch_empty NAME [-i | -w]\n branch_empty()\n {\n-\t[ -z \"$(git diff-tree \"refs/top-bases/$1\" \"$1\" -- | fgrep -v \"\t.top\")\" ]\n+\t[ \"$(pretty_tree \"$1\" -b)\" = \"$(pretty_tree \"$1\" ${2-})\" ]\n }\n \n # list_deps\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153890","messageId":"d1c407c33f446a6e5c7329ba521871732a136fa6.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"d9fc8653e6e4c7eb7197a0fb92cd3b8c6e058187.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 05/12] tg-path: use pretty_tree and diff-tree to generate the patch","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:50Z","receivedAt":"2010-10-20T20:17:50Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n tg-patch.sh |   54 +++++++++++++++++++++++++++++++-----------------------\n 1 files changed, 31 insertions(+), 23 deletions(-)\n\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex 85346ec..9def6e5 100644\n--- a/tg-patch.sh\n+++ b/tg-patch.sh\n@@ -6,8 +6,6 @@\n name=\n \n head_from=\n-diff_opts=\n-diff_committed_only=yes\t# will be unset for index/worktree\n \n \n ## Parse options\n@@ -15,15 +13,9 @@ diff_committed_only=yes\t# will be unset for index/worktree\n while [ -n \"$1\" ]; do\n \targ=\"$1\"; shift\n \tcase \"$arg\" in\n-\t-i)\n+\t-i|-w)\n \t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n-\t\thead_from=-i\n-\t\tdiff_opts=\"$diff_opts --cached\";\n-\t\tdiff_committed_only=;;\n-\t-w)\n-\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n-\t\thead_from=-w\n-\t\tdiff_committed_only=;;\n+\t\thead_from=\"$arg\";;\n \t-*)\n \t\techo \"Usage: tg [...] patch [-i | -w] [NAME]\" >&2\n \t\texit 1;;\n@@ -49,20 +41,36 @@ fi\n \n setup_pager\n \n-cat_file \"$name:.topmsg\" $head_from\n-echo\n-[ -n \"$(git grep $diff_opts '^[-]--' ${diff_committed_only:+\"$name\"} -- \".topmsg\")\" ] || echo '---'\n-\n-# Evil obnoxious hack to work around the lack of git diff --exclude\n-git_is_stupid=\"$(get_temp tg-patch-changes)\"\n-git diff --name-only $diff_opts \"$base_rev\" ${diff_committed_only:+\"$name\"} -- |\n-\tfgrep -vx \".topdeps\" |\n-\tfgrep -vx \".topmsg\" >\"$git_is_stupid\" || : # fgrep likes to fail randomly?\n-if [ -s \"$git_is_stupid\" ]; then\n-\tcd \"$root_dir\"\n-\tcat \"$git_is_stupid\" | xargs git diff -a --patch-with-stat $diff_opts \"$base_rev\" ${diff_committed_only:+\"$name\"} --\n-else\n+\n+# put out the commit message\n+# and put an empty line out, if the last one in the message was not an empty line\n+# and put out \"---\" if the commit message does not have one yet\n+cat_file \"$name:.topmsg\" $head_from |\n+\tawk '\n+/^---/ {\n+    has_3dash=1;\n+}\n+       {\n+    need_empty = 1;\n+    if ($0 == \"\")\n+        need_empty = 0;\n+    print;\n+}\n+END    {\n+    if (need_empty)\n+        print \"\";\n+    if (!has_3dash)\n+        print \"---\";\n+}\n+'\n+\n+b_tree=$(pretty_tree \"$name\" -b)\n+t_tree=$(pretty_tree \"$name\" $head_from)\n+\n+if [ $b_tree = $t_tree ]; then\n \techo \"No changes.\"\n+else\n+\tgit diff-tree -p --stat $b_tree $t_tree\n fi\n \n echo '-- '\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153886","messageId":"e3ce8e49edc363c62c6135ffe94dd1e5990cce6a.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"d1c407c33f446a6e5c7329ba521871732a136fa6.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 06/12] list_deps: accept -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:51Z","receivedAt":"2010-10-20T20:17:51Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n tg.sh |   11 +++++++++--\n 1 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/tg.sh b/tg.sh\nindex 949d2a4..4b6820b 100644\n--- a/tg.sh\n+++ b/tg.sh\n@@ -288,9 +288,13 @@ branch_empty()\n \t[ \"$(pretty_tree \"$1\" -b)\" = \"$(pretty_tree \"$1\" ${2-})\" ]\n }\n \n-# list_deps\n+# list_deps [-i | -w]\n+# -i/-w apply only to HEAD\n list_deps()\n {\n+\thead=\"$(git symbolic-ref HEAD)\"\n+\thead=\"${head#refs/heads/}\"\n+\n \tgit for-each-ref refs/top-bases |\n \t\twhile read rev type ref; do\n \t\t\tname=\"${ref#refs/top-bases/}\"\n@@ -298,7 +302,10 @@ list_deps()\n \t\t\t\tcontinue;\n \t\t\tfi\n \n-\t\t\tgit cat-file blob \"$name:.topdeps\" | while read dep; do\n+\t\t\tfrom=$head_from\n+\t\t\t[ \"$name\" = \"$head\" ] ||\n+\t\t\t\tfrom=\n+\t\t\tcat_file \"$name:.topdeps\" $from | while read dep; do\n \t\t\t\tdep_is_tgish=true\n \t\t\t\tref_exists \"refs/top-bases/$dep\"  ||\n \t\t\t\t\tdep_is_tgish=false\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153888","messageId":"2af535ba26e4879ef1e420900effb95f71a9e531.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"e3ce8e49edc363c62c6135ffe94dd1e5990cce6a.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 07/12] tg-summary: accept -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:52Z","receivedAt":"2010-10-20T20:17:52Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n README                     |    4 ++++\n contrib/tg-completion.bash |    4 ++++\n tg-summary.sh              |   21 +++++++++++++++------\n 3 files changed, 23 insertions(+), 6 deletions(-)\n\ndiff --git a/README b/README\nindex 5ca0424..eea0d72 100644\n--- a/README\n+++ b/README\n@@ -362,6 +362,10 @@ tg summary\n \tbranches in a machine-readable format.  Feed this to \"tsort\"\n \tto get the output from --sort.\n \n+\tOptions:\n+\t  -i\t\tUse TopGit meta data from the index instead of branch\n+\t  -w\t\tUse TopGit meta data from the working tree instead of branch\n+\n \tTODO: Speed up by an order of magnitude\n \tTODO: Text graph view\n \ndiff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash\nindex ccf1a32..6a1e182 100755\n--- a/contrib/tg-completion.bash\n+++ b/contrib/tg-completion.bash\n@@ -426,7 +426,11 @@ _tg_summary ()\n \t*)\n \t\t__tgcomp \"\n \t\t\t--graphviz\n+\t\t\t--sort\n+\t\t\t--deps\n \t\t\t-t\n+\t\t\t-i\n+\t\t\t-w\n \t\t\"\n \tesac\n }\ndiff --git a/tg-summary.sh b/tg-summary.sh\nindex 612bd27..1c99e22 100644\n--- a/tg-summary.sh\n+++ b/tg-summary.sh\n@@ -7,13 +7,16 @@ terse=\n graphviz=\n sort=\n deps=\n-\n+head_from=\n \n ## Parse options\n \n while [ -n \"$1\" ]; do\n \targ=\"$1\"; shift\n \tcase \"$arg\" in\n+\t-i|-w)\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=\"$arg\";;\n \t-t)\n \t\tterse=1;;\n \t--graphviz)\n@@ -23,7 +26,7 @@ while [ -n \"$1\" ]; do\n \t--deps)\n \t\tdeps=1;;\n \t*)\n-\t\techo \"Usage: tg [...] summary [-t | --sort | --deps | --graphviz]\" >&2\n+\t\techo \"Usage: tg [...] summary [-t | --sort | --deps | --graphviz] [-i | -w]\" >&2\n \t\texit 1;;\n \tesac\n done\n@@ -68,8 +71,11 @@ process_branch()\n \n \tcurrent=' '\n \t[ \"$name\" != \"$curname\" ] || current='>'\n+\tfrom=$head_from\n+\t[ \"$name\" = \"$curname\" ] ||\n+\t\tfrom=\n \tnonempty=' '\n-\t! branch_empty \"$name\" || nonempty='0'\n+\t! branch_empty \"$name\" $from || nonempty='0'\n \tremote=' '\n \t[ -z \"$base_remote\" ] || remote='l'\n \t! has_remote \"$name\" || remote='r'\n@@ -88,7 +94,7 @@ process_branch()\n \tbranch_contains \"$name\" \"refs/top-bases/$name\" || base_update='B'\n \n \tif [ \"$(git rev-parse \"$name\")\" != \"$rev\" ]; then\n-\t\tsubject=\"$(git cat-file blob \"$name:.topmsg\" | sed -n 's/^Subject: //p')\"\n+\t\tsubject=\"$(cat_file \"$name:.topmsg\" $from | sed -n 's/^Subject: //p')\"\n \telse\n \t\t# No commits yet\n \t\tsubject=\"(No commits)\"\n@@ -99,7 +105,7 @@ process_branch()\n }\n \n if [ -n \"$deps\" ]; then\n-\tlist_deps\n+\tlist_deps $head_from\n \texit 0\n fi\n \n@@ -113,7 +119,10 @@ git for-each-ref refs/top-bases |\n \t\tif [ -n \"$terse\" ]; then\n \t\t\techo \"$name\"\n \t\telif [ -n \"$graphviz$sort\" ]; then\n-\t\t\tgit cat-file blob \"$name:.topdeps\" | while read dep; do\n+\t\t\tfrom=$head_from\n+\t\t\t[ \"$name\" = \"$curname\" ] ||\n+\t\t\t\tfrom=\n+\t\t\tcat_file \"$name:.topdeps\" $from | while read dep; do\n \t\t\t\tdep_is_tgish=true\n \t\t\t\tref_exists \"refs/top-bases/$dep\"  ||\n \t\t\t\t\tdep_is_tgish=false\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153893","messageId":"3d4e3b72d48a5227fc7a22c0e55581114a75f1b0.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"2af535ba26e4879ef1e420900effb95f71a9e531.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 08/12] tg-mail: accept -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:53Z","receivedAt":"2010-10-20T20:17:53Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n README                     |    4 ++++\n contrib/tg-completion.bash |    8 ++++++++\n tg-mail.sh                 |   12 +++++++++---\n 3 files changed, 21 insertions(+), 3 deletions(-)\n\ndiff --git a/README b/README\nindex eea0d72..538659a 100644\n--- a/README\n+++ b/README\n@@ -315,6 +315,10 @@ tg mail\n \n \tto let `git send-email` ask for confirmation before sending any mail.\n \n+\tOptions:\n+\t  -i\t\tbase patch generation on index instead of branch\n+\t  -w\t\tbase patch generation on working tree instead of branch\n+\n \tTODO: 'tg mail patchfile' to mail an already exported patch\n \tTODO: mailing patch series\n \tTODO: specifying additional options and addresses on command\ndiff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash\nindex 6a1e182..b7051b8 100755\n--- a/contrib/tg-completion.bash\n+++ b/contrib/tg-completion.bash\n@@ -359,6 +359,14 @@ _tg_mail ()\n \tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n \n \tcase \"$cur\" in\n+\t-*)\n+\t\t__tgcomp \"\n+\t\t\t-i\n+\t\t\t-w\n+\t\t\t-s\n+\t\t\t-r\n+\t\t\"\n+\t\t;;\n \t*)\n \t\t__tgcomp \"$(__tg_topics)\"\n \tesac\ndiff --git a/tg-mail.sh b/tg-mail.sh\nindex dd4a95a..17ce02c 100644\n--- a/tg-mail.sh\n+++ b/tg-mail.sh\n@@ -3,6 +3,7 @@\n # GPLv2\n \n name=\n+head_from=\n send_email_args=\n in_reply_to=\n \n@@ -12,12 +13,15 @@ in_reply_to=\n while [ -n \"$1\" ]; do\n \targ=\"$1\"; shift\n \tcase \"$arg\" in\n+\t-i|-w)\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=\"$arg\";;\n \t-s)\n \t\tsend_email_args=\"$1\"; shift;;\n \t-r)\n \t\tin_reply_to=\"$1\"; shift;;\n \t-*)\n-\t\techo \"Usage: tg [...] mail [-s SEND_EMAIL_ARGS] [-r REFERENCE_MSGID] [NAME]\" >&2\n+\t\techo \"Usage: tg [...] mail [-s SEND_EMAIL_ARGS] [-r REFERENCE_MSGID] [-i | -w] [NAME]\" >&2\n \t\texit 1;;\n \t*)\n \t\t[ -z \"$name\" ] || die \"name already specified ($name)\"\n@@ -25,7 +29,8 @@ while [ -n \"$1\" ]; do\n \tesac\n done\n \n-[ -n \"$name\" ] || name=\"$(git symbolic-ref HEAD | sed 's#^refs/heads/##')\"\n+head=\"$(git symbolic-ref HEAD | sed 's#^refs/heads/##')\"\n+[ -n \"$name\" ] || name=\"$head\"\n base_rev=\"$(git rev-parse --short --verify \"refs/top-bases/$name\" 2>/dev/null)\" ||\n \tdie \"not a TopGit-controlled branch\"\n \n@@ -36,7 +41,8 @@ fi\n \n patchfile=\"$(get_temp tg-mail)\"\n \n-$tg patch \"$name\" >\"$patchfile\"\n+# let tg patch sort out whether $head_from makes sense for $name\n+$tg patch \"$name\" $head_from >\"$patchfile\"\n \n header=\"$(sed -e '/^$/,$d' -e \"s,','\\\\\\\\'',g\" \"$patchfile\")\"\n \n-- \n1.7.3.1.1069.g89486\n"},{"id":"153889","messageId":"1bf3b3656a23c2de123c749524fcd6df09d9bf87.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"3d4e3b72d48a5227fc7a22c0e55581114a75f1b0.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 09/12] tg-files: list files changed by the topic branch","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:54Z","receivedAt":"2010-10-20T20:17:54Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"this could also be a --name-only option to tg-patch. But I Like the\nsimilarity to 'quilt files'.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n .gitignore                 |    2 ++\n README                     |    8 ++++++++\n contrib/tg-completion.bash |    1 +\n tg-files.sh                |   43 +++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 54 insertions(+), 0 deletions(-)\n create mode 100644 tg-files.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 3298889..2a4d165 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -22,6 +22,8 @@\n /tg-depend.txt\n /tg-export\n /tg-export.txt\n+/tg-files\n+/tg-files.txt\n /tg-import\n /tg-import.txt\n /tg-info\ndiff --git a/README b/README\nindex 538659a..c5a8ae0 100644\n--- a/README\n+++ b/README\n@@ -533,6 +533,14 @@ tg log\n \trepository, so you will not see work done by your\n \tcollaborators.\n \n+tg files\n+~~~~~~~~\n+\tList files changed by the current or specified topic branch.\n+\n+\tOptions:\n+\t  -i\t\tlist files based on index instead of branch\n+\t  -w\t\tlist files based on working tree instead of branch\n+\n TODO: tg rename\n \n \ndiff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash\nindex b7051b8..ddc7655 100755\n--- a/contrib/tg-completion.bash\n+++ b/contrib/tg-completion.bash\n@@ -494,6 +494,7 @@ _tg ()\n \tdelete)      _tg_delete ;;\n \tdepend)      _tg_depend ;;\n \texport)      _tg_export ;;\n+\tfiles)       _tg_patch ;;\n \thelp)        _tg_help ;;\n \timport)      _tg_import ;;\n \tinfo)        _tg_info ;;\ndiff --git a/tg-files.sh b/tg-files.sh\nnew file mode 100644\nindex 0000000..ab97624\n--- /dev/null\n+++ b/tg-files.sh\n@@ -0,0 +1,43 @@\n+#!/bin/sh\n+# TopGit - A different patch queue manager\n+# (c) Petr Baudis <pasky@suse.cz>  2008\n+# GPLv2\n+\n+name=\n+head_from=\n+\n+\n+## Parse options\n+\n+while [ -n \"$1\" ]; do\n+\targ=\"$1\"; shift\n+\tcase \"$arg\" in\n+\t-i|-w)\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=\"$arg\";;\n+\t-*)\n+\t\techo \"Usage: tg [...] files [-i | -w] [NAME]\" >&2\n+\t\texit 1;;\n+\t*)\n+\t\t[ -z \"$name\" ] || die \"name already specified ($name)\"\n+\t\tname=\"$arg\";;\n+\tesac\n+done\n+\n+\n+head=\"$(git symbolic-ref HEAD)\"\n+head=\"${head#refs/heads/}\"\n+\n+[ -n \"$name\" ] ||\n+\tname=\"$head\"\n+base_rev=\"$(git rev-parse --short --verify \"refs/top-bases/$name\" 2>/dev/null)\" ||\n+\tdie \"not a TopGit-controlled branch\"\n+\n+if [ -n \"$head_from\" ] && [ \"$name\" != \"$head\" ]; then\n+\tdie \"$head_from makes only sense for the current branch\"\n+fi\n+\n+b_tree=$(pretty_tree \"$name\" -b)\n+t_tree=$(pretty_tree \"$name\" $head_from)\n+\n+git diff-tree --name-only -r $b_tree $t_tree\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153892","messageId":"8bd4da13a1c992ece87b4c742d75dad3b6776acf.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"1bf3b3656a23c2de123c749524fcd6df09d9bf87.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH v3 10/12] tg-prev/tg-next: commands to explore dependencies","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:55Z","receivedAt":"2010-10-20T20:17:55Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Two new commands to explore the dependencies of TopGit branches:\n\n  a) tg prev [-i | -w] [NAME]\n     outputs the dependencies of NAME\n\n  b) tg next [-i | -w] [NAME]\n     outputs branches which depends on NAME\n\nObviously, quilt next was the inspiration.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n .gitignore                 |    4 +++\n README                     |   18 ++++++++++++++++-\n contrib/tg-completion.bash |   34 +++++++++++++++++++++++++++++++++\n tg-next.sh                 |   45 ++++++++++++++++++++++++++++++++++++++++++++\n tg-prev.sh                 |   38 +++++++++++++++++++++++++++++++++++++\n 5 files changed, 138 insertions(+), 1 deletions(-)\n create mode 100644 tg-next.sh\n create mode 100644 tg-prev.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 2a4d165..6cfab6e 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -30,10 +30,14 @@\n /tg-info.txt\n /tg-mail\n /tg-mail.txt\n+/tg-next\n+/tg-next.txt\n /tg-log\n /tg-log.txt\n /tg-patch\n /tg-patch.txt\n+/tg-prev\n+/tg-prev.txt\n /tg-push\n /tg-push.txt\n /tg-remote\ndiff --git a/README b/README\nindex c5a8ae0..7760218 100644\n--- a/README\n+++ b/README\n@@ -541,8 +541,24 @@ tg files\n \t  -i\t\tlist files based on index instead of branch\n \t  -w\t\tlist files based on working tree instead of branch\n \n-TODO: tg rename\n+tg prev\n+~~~~~~~\n+\tOutputs the direct dependencies for the current or named patch.\n \n+\tOptions:\n+\t  -i\t\tshow dependencies based on index instead of branch\n+\t  -w\t\tshow dependencies based on working tree instead of branch\n+\n+tg next\n+~~~~~~~\n+\tOutputs all patches which directly depend on the current or\n+\tnamed patch.\n+\n+\tOptions:\n+\t  -i\t\tshow dependencies based on index instead of branch\n+\t  -w\t\tshow dependencies based on working tree instead of branch\n+\n+TODO: tg rename\n \n IMPLEMENTATION\n --------------\ndiff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash\nindex ddc7655..e34b66f 100755\n--- a/contrib/tg-completion.bash\n+++ b/contrib/tg-completion.bash\n@@ -453,6 +453,38 @@ _tg_update ()\n \tesac\n }\n \n+_tg_next ()\n+{\n+\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\n+\tcase \"$cur\" in\n+\t-*)\n+\t\t__tgcomp \"\n+\t\t\t-i\n+\t\t\t-w\n+\t\t\"\n+\t\t;;\n+\t*)\n+\t\t__tgcomp \"$(__tg_heads)\"\n+\tesac\n+}\n+\n+_tg_prev ()\n+{\n+\tlocal cur=\"${COMP_WORDS[COMP_CWORD]}\"\n+\n+\tcase \"$cur\" in\n+\t-*)\n+\t\t__tgcomp \"\n+\t\t\t-i\n+\t\t\t-w\n+\t\t\"\n+\t\t;;\n+\t*)\n+\t\t__tgcomp \"$(__tg_topics)\"\n+\tesac\n+}\n+\n ### }}}\n ### {{{ tg completion\n \n@@ -500,7 +532,9 @@ _tg ()\n \tinfo)        _tg_info ;;\n \tlog)         _tg_log ;;\n \tmail)        _tg_mail ;;\n+\tnext)        _tg_next ;;\n \tpatch)       _tg_patch ;;\n+\tprev)        _tg_prev ;;\n \tpush)        _tg_push ;;\n \tremote)      _tg_remote ;;\n \tsummary)     _tg_summary ;;\ndiff --git a/tg-next.sh b/tg-next.sh\nnew file mode 100644\nindex 0000000..93dd5b5\n--- /dev/null\n+++ b/tg-next.sh\n@@ -0,0 +1,45 @@\n+#!/bin/sh\n+# TopGit - A different patch queue manager\n+# (c) Petr Baudis <pasky@suse.cz>  2008\n+# (c) Bert Wesarg <Bert.Wesarg@googlemail.com>  2009\n+# GPLv2\n+\n+name=\n+head_from=\n+\n+\n+## Parse options\n+\n+while [ -n \"$1\" ]; do\n+\targ=\"$1\"; shift\n+\tcase \"$arg\" in\n+\t-i|-w)\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=\"$arg\";;\n+\t-*)\n+\t\techo \"Usage: tg next [-i | -w] [NAME]\" >&2\n+\t\texit 1;;\n+\t*)\n+\t\t[ -z \"$name\" ] || die \"name already specified ($name)\"\n+\t\tname=\"$arg\";;\n+\tesac\n+done\n+\n+head=\"$(git rev-parse --abbrev-ref=loose HEAD)\"\n+[ -n \"$name\" ] ||\n+\tname=\"$head\"\n+\n+git for-each-ref --format='%(refname)' refs/top-bases |\n+\twhile read ref; do\n+\t\tparent=\"${ref#refs/top-bases/}\"\n+\n+\t\tfrom=$head_from\n+\t\t# select .topdeps source for HEAD branch\n+\t\t[ \"x$parent\" = \"x$head\" ] ||\n+\t\t\tfrom=\n+\n+\t\tcat_file \"$parent:.topdeps\" $from | fgrep -qx \"$name\" ||\n+\t\t\tcontinue\n+\n+\t\techo \"$parent\"\n+\tdone\ndiff --git a/tg-prev.sh b/tg-prev.sh\nnew file mode 100644\nindex 0000000..1f1e0c1\n--- /dev/null\n+++ b/tg-prev.sh\n@@ -0,0 +1,38 @@\n+#!/bin/sh\n+# TopGit - A different patch queue manager\n+# (c) Petr Baudis <pasky@suse.cz>  2008\n+# (c) Bert Wesarg <Bert.Wesarg@googlemail.com>  2009\n+# GPLv2\n+\n+name=\n+head_from=\n+\n+\n+## Parse options\n+\n+while [ -n \"$1\" ]; do\n+\targ=\"$1\"; shift\n+\tcase \"$arg\" in\n+\t-i|-w)\n+\t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n+\t\thead_from=\"$arg\";;\n+\t-*)\n+\t\techo \"Usage: tg next [-i | -w] [NAME]\" >&2\n+\t\texit 1;;\n+\t*)\n+\t\t[ -z \"$name\" ] || die \"name already specified ($name)\"\n+\t\tname=\"$arg\";;\n+\tesac\n+done\n+\n+head=\"$(git rev-parse --abbrev-ref=loose HEAD)\"\n+[ -n \"$name\" ] ||\n+\tname=\"$head\"\n+base_rev=\"$(git rev-parse --short --verify \"refs/top-bases/$name\" 2>/dev/null)\" ||\n+\tdie \"not a TopGit-controlled branch\"\n+\n+# select .topdeps source for HEAD branch\n+[ \"x$name\" = \"x$head\" ] ||\n+\thead_from=\n+\n+cat_file \"$name:.topdeps\" $head_from\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153894","messageId":"cb28181bc3cc0cfbf19926aa9dabf3d1d1f643b0.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"8bd4da13a1c992ece87b4c742d75dad3b6776acf.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit RFC/PATCH v3 11/12] tg-patch: use ui diff when pager is active","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:56Z","receivedAt":"2010-10-20T20:17:56Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"diff-tree should be used to generate patches meant for submission\n(or non-human consumption). But for pure human inspection some 'eye-candy'\neffects could take considerations. Like color, renames, mnemonicprefix,\nor noprefix. External diff driver or word-diff. All these are in effect\nby using the diff command, when configured in your git config file.\ndiff-tree does not honor these configure options but its possible to give\nthem as command line options too. Selecting the plumbing or ui diff driver\nis best done automatically, in my opinion. And an active pager is my best\nbet that a human will consume the output.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n\n---\n\nI will probably add an overwrite command switch (to enable ui mode even\nwithout an active pager shortly. Because I sometimes pipe the output for\ninspection into my editor.\n\n tg-patch.sh |    7 ++++++-\n 1 files changed, 6 insertions(+), 1 deletions(-)\n\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex 9def6e5..dcce672 100644\n--- a/tg-patch.sh\n+++ b/tg-patch.sh\n@@ -70,7 +70,12 @@ t_tree=$(pretty_tree \"$name\" $head_from)\n if [ $b_tree = $t_tree ]; then\n \techo \"No changes.\"\n else\n-\tgit diff-tree -p --stat $b_tree $t_tree\n+\t# use the ui diff command when the pager is active\n+\tdiff_command=diff\n+\t[ \"x$GIT_PAGER_IN_USE\" = \"x1\" ] ||\n+\t\tdiff_command=diff-tree\n+\n+\tgit $diff_command -p --stat $b_tree $t_tree\n fi\n \n echo '-- '\n-- \n1.7.3.1.1069.g89486\n"},{"id":"153887","messageId":"24183272016f41b5351f25e5143043a9f3327a78.1287605587.git.bert.wesarg@googlemail.com","threadId":"25489","inReplyTo":"cb28181bc3cc0cfbf19926aa9dabf3d1d1f643b0.1287605587.git.bert.wesarg@googlemail.com","subject":"[TopGit RFC/PATCH v3 12/12] tg-patch: simulate mnemonic prefixes","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-20T20:17:57Z","receivedAt":"2010-10-20T20:17:57Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"b/ is for base, i/ and w/ correspond to -i/-w and t/ is the committed\ntopic.\n\ndiff.mnemonicprefix needs to be set to true. See git-config(1) for more\ninformation.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n---\n tg-patch.sh |    8 ++++++--\n 1 files changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex dcce672..c8ad723 100644\n--- a/tg-patch.sh\n+++ b/tg-patch.sh\n@@ -6,7 +6,7 @@\n name=\n \n head_from=\n-\n+dst_prefix=\"t/\"\n \n ## Parse options\n \n@@ -15,7 +15,8 @@ while [ -n \"$1\" ]; do\n \tcase \"$arg\" in\n \t-i|-w)\n \t\t[ -z \"$head_from\" ] || die \"-i and -w are mutually exclusive\"\n-\t\thead_from=\"$arg\";;\n+\t\thead_from=\"$arg\"\n+\t\tdst_prefix=\"${arg#-}/\";;\n \t-*)\n \t\techo \"Usage: tg [...] patch [-i | -w] [NAME]\" >&2\n \t\texit 1;;\n@@ -72,6 +73,9 @@ if [ $b_tree = $t_tree ]; then\n else\n \t# use the ui diff command when the pager is active\n \tdiff_command=diff\n+\tif $(git config --bool diff.mnemonicprefix); then\n+\t\tdiff_command=\"$diff_command --src-prefix=b/ --dst-prefix=$dst_prefix\"\n+\tfi\n \t[ \"x$GIT_PAGER_IN_USE\" = \"x1\" ] ||\n \t\tdiff_command=diff-tree\n \n-- \n1.7.3.1.1069.g89486\n"}]}