{"thread":{"id":"25404","subject":"[TopGit PATCH 01/11] cat_file: take -i/-w parameters","startedAt":"2010-10-09T20:56:52Z","lastAt":"2010-10-09T20:57:02Z","messageCount":11,"participants":["Bert Wesarg"],"isPatch":true,"patchVersion":1,"patchTotal":11},"messages":[{"id":"153083","messageId":"e72a55b5f6ca2b805892fd6e214a4f72bf865124.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":null,"subject":"[TopGit PATCH 01/11] cat_file: take -i/-w parameters","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:52Z","receivedAt":"2010-10-09T20:56:52Z","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\nI will probably never understand why TopGit accepts to be on a top-base branch.\nI will probably never understand why TopGit not changes the cwd to the top level.\nI will probably never understand why TopGit does not use the git-sh-setup.sh.\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 4f2f16f..f740997 100644 hooks/pre-commit.sh\n--- a/hooks/pre-commit.sh\n+++ b/hooks/pre-commit.sh\n@@ -98,7 +98,7 @@ BEGIN      { in_hunk = 0; }\n depdir=\"$(mktemp -t -d tg-depdir.XXXXXX)\" ||\n \tdie \"Can't check for multiple occurrences of deps\"\n trap \"rm -rf '$depdir'\" 0\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 7bafdfe..5b7386a 100644 tg-patch.sh\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@@ -64,7 +67,7 @@ fi\n rm \"$git_is_stupid\"\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 8264a3b..4d7d4ef 100644 tg.sh\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.1.1067.g5aeb7\n"},{"id":"153084","messageId":"456834d2977615d5f5c41ca3947fb45cd82bfd87.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"e72a55b5f6ca2b805892fd6e214a4f72bf865124.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 02/11] pretty_tree: globalize and respect -i/-w options","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:53Z","receivedAt":"2010-10-09T20:56: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 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 6d82d55..5c707ce 100644 tg-export.sh\n--- a/tg-export.sh\n+++ b/tg-export.sh\n@@ -63,15 +63,6 @@ trap 'rm -rf \"$playground\"' EXIT\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@@ -112,7 +103,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@@ -227,7 +218,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 4d7d4ef..308ed28 100644 tg.sh\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.1.1067.g5aeb7\n"},{"id":"153085","messageId":"6e000c8cf21fac6cd4cf8608c8dc021b039e6f83.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"456834d2977615d5f5c41ca3947fb45cd82bfd87.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 03/11] branch_empty: use pretty_tree and therefore respect -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:54Z","receivedAt":"2010-10-09T20:56:54Z","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 308ed28..a166a70 100644 tg.sh\n--- a/tg.sh\n+++ b/tg.sh\n@@ -283,10 +283,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.1.1067.g5aeb7\n"},{"id":"153086","messageId":"ec70ec8e15013f663bba7f62885abe6881a1512a.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"6e000c8cf21fac6cd4cf8608c8dc021b039e6f83.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 04/11] tg-path: use pretty_tree and diff-tree to generate the patch","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:55Z","receivedAt":"2010-10-09T20:56:55Z","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 |   55 +++++++++++++++++++++++++++++++------------------------\n 1 files changed, 31 insertions(+), 24 deletions(-)\n\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex 5b7386a..9def6e5 100644 tg-patch.sh\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,22 +41,37 @@ 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=\"$(mktemp -t tg-patch-changes.XXXXXX)\"\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-rm \"$git_is_stupid\"\n \n echo '-- '\n echo \"tg: ($base_rev..) $name (depends on: $(cat_file \"$name:.topdeps\" $head_from | paste -s -d' '))\"\n-- \n1.7.1.1067.g5aeb7\n"},{"id":"153087","messageId":"b765e0da80781182bf6c3af8f28d9496ed49cc1b.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"ec70ec8e15013f663bba7f62885abe6881a1512a.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 05/11] list_deps: accept -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:56Z","receivedAt":"2010-10-09T20:56:56Z","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 a166a70..72ee9f5 100644 tg.sh\n--- a/tg.sh\n+++ b/tg.sh\n@@ -289,9 +289,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@@ -299,7 +303,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.1.1067.g5aeb7\n"},{"id":"153088","messageId":"62e3424559a93dc0f7c3ed55aafce738f2b0f6d3.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"b765e0da80781182bf6c3af8f28d9496ed49cc1b.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 06/11] tg-summary: accept -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:57Z","receivedAt":"2010-10-09T20:56:57Z","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 README\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 contrib/tg-completion.bash\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 af16888..113efc2 100644 tg-summary.sh\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@@ -69,8 +72,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@@ -89,7 +95,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@@ -100,7 +106,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@@ -114,7 +120,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.1.1067.g5aeb7\n"},{"id":"153089","messageId":"65565f00635372ad3677c0187c33da4d3ceb4b73.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"62e3424559a93dc0f7c3ed55aafce738f2b0f6d3.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 07/11] tg-mail: accept -i/-w","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:58Z","receivedAt":"2010-10-09T20:56:58Z","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 README\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 contrib/tg-completion.bash\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 8167ade..6ddcf08 100644 tg-mail.sh\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=\"$(mktemp -t tg-mail.XXXXXX)\"\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.1.1067.g5aeb7\n"},{"id":"153090","messageId":"3f39e999ea8aeca5c7125e8981aeffb8cd92d472.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"65565f00635372ad3677c0187c33da4d3ceb4b73.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 08/11] tg-files: list files changed by the topic branch","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:56:59Z","receivedAt":"2010-10-09T20:56:59Z","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 .gitignore\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 README\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 contrib/tg-completion.bash\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 tg-files.sh\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.1.1067.g5aeb7\n"},{"id":"153091","messageId":"320cfcab44939419b5700daa6c356648becc2004.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"3f39e999ea8aeca5c7125e8981aeffb8cd92d472.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 09/11] tg-prev/tg-next: commands to explore dependencies","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:57:00Z","receivedAt":"2010-10-09T20:57:00Z","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 .gitignore\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 README\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 contrib/tg-completion.bash\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 tg-next.sh\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 tg-prev.sh\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.1.1067.g5aeb7\n"},{"id":"153092","messageId":"58dbd71af776b1fb088080129a65c623b1dea926.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"320cfcab44939419b5700daa6c356648becc2004.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 10/11] [RFC] tg-patch: use ui diff when pager is active","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:57:01Z","receivedAt":"2010-10-09T20:57:01Z","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 |    7 ++++++-\n 1 files changed, 6 insertions(+), 1 deletions(-)\n\ndiff --git a/tg-patch.sh b/tg-patch.sh\nindex 9def6e5..dcce672 100644 tg-patch.sh\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.1.1067.g5aeb7\n"},{"id":"153093","messageId":"d9801fe5759b2d40d7bc7497d37545e15293041f.1286657607.git.bert.wesarg@googlemail.com","threadId":"25404","inReplyTo":"58dbd71af776b1fb088080129a65c623b1dea926.1286657607.git.bert.wesarg@googlemail.com","subject":"[TopGit PATCH 11/11] [RFC] tg-patch: simulate mnemonic prefixes","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2010-10-09T20:57:02Z","receivedAt":"2010-10-09T20:57:02Z","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\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 tg-patch.sh\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.1.1067.g5aeb7\n"}]}