{"thread":{"id":"38546","subject":"[PATCH] show-branch --upstream: add upstream branches to the list of branches to display","startedAt":"2015-02-11T01:16:14Z","lastAt":"2015-02-11T01:16:14Z","messageCount":1,"participants":["Mike Hommey"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"255920","messageId":"1423617374-31408-1-git-send-email-mh@glandium.org","threadId":"38546","inReplyTo":null,"subject":"[PATCH] show-branch --upstream: add upstream branches to the list of branches to display","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2015-02-11T01:16:14Z","receivedAt":"2015-02-11T01:16:14Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"`git show-branch` is a useful tool to display topics, but when you have\nseveral local topic branches based on different upstream branches, it\ncan get cumbersome to use the right upstream branch with the right set\nof topic branches.\n\nThe --upstream flag automatically adds the upstream branch for every\ntopic branch given, such that:\n\n`git show-branch --upstream` is equivalent to `git show-branch\n$(git for-each-ref refs/heads --format '%(refname:short)')\n$(git for-each-ref refs/heads --format '%(upstream:short)')`\n\n`git show-branch --upstream foo bar` is equivalent to `git show-branch\nfoo bar $(git for-each-ref refs/heads/foo refs/heads/bar\n--format '%(upstream:short)')`\n\nFurthermore, the --topics argument only takes one \"upstream\" ref. However,\nwhen combined with --upstream, all the upstream branches are considered,\nand show-branch only shows commits that are NOT on ANY of those upstream\nbranches.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\nRefreshed against current \"next\".\n\n\n Documentation/git-show-branch.txt |  6 ++++++\n builtin/show-branch.c             | 44 ++++++++++++++++++++++++++++++++++++---\n 2 files changed, 47 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt\nindex b91d4e5..fd29c8d 100644\n--- a/Documentation/git-show-branch.txt\n+++ b/Documentation/git-show-branch.txt\n@@ -53,6 +53,10 @@ OPTIONS\n \tbranch to the list of revs to be shown when it is not\n \tgiven on the command line.\n \n+--upstream::\n+\tWith this option, the command includes the upstream\n+\tbranch of each rev to be shown.\n+\n --topo-order::\n         By default, the branches and their commits are shown in\n         reverse chronological order.  This option makes them\n@@ -102,6 +106,8 @@ OPTIONS\n \n --topics::\n \tShows only commits that are NOT on the first branch given.\n+\tWhen used with `--upstream`, shows only commits that are NOT\n+\ton any upstream branch.\n \tThis helps track topic branches by hiding any commit that\n \tis already in the main line of development.  When given\n \t\"git show-branch --topics master topic1 topic2\", this\ndiff --git a/builtin/show-branch.c b/builtin/show-branch.c\nindex f3fb5fb..140e88c 100644\n--- a/builtin/show-branch.c\n+++ b/builtin/show-branch.c\n@@ -4,11 +4,12 @@\n #include \"builtin.h\"\n #include \"color.h\"\n #include \"parse-options.h\"\n+#include \"remote.h\"\n \n static const char* show_branch_usage[] = {\n     N_(\"git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\\n\"\n-       \"\t\t[--current] [--color[=<when>] | --no-color] [--sparse]\\n\"\n-       \"\t\t[--more=<n> | --list | --independent | --merge-base]\\n\"\n+       \"\t\t[--current] [--upstream] [--color[=<when>] | --no-color]\\n\"\n+       \"\t\t[--sparse] [--more=<n> | --list | --independent | --merge-base]\\n\"\n        \"\t\t[--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]\"),\n     N_(\"git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]\"),\n     NULL\n@@ -643,6 +644,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \tint sha1_name = 0;\n \tint shown_merge_point = 0;\n \tint with_current_branch = 0;\n+\tint with_upstream_branches = 0;\n \tint head_at = -1;\n \tint topics = 0;\n \tint dense = 1;\n@@ -661,6 +663,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tOPT_BOOL(0, \"no-name\", &no_name, N_(\"suppress naming strings\")),\n \t\tOPT_BOOL(0, \"current\", &with_current_branch,\n \t\t\t N_(\"include the current branch\")),\n+\t\tOPT_BOOL(0, \"upstream\", &with_upstream_branches,\n+\t\t\t N_(\"include upstream branches\")),\n \t\tOPT_BOOL(0, \"sha1-name\", &sha1_name,\n \t\t\t N_(\"name commits with their object names\")),\n \t\tOPT_BOOL(0, \"merge-base\", &merge_base,\n@@ -851,7 +855,41 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\tif (commit->object.flags == flag)\n \t\t\tcommit_list_insert_by_date(commit, &list);\n \t\trev[num_rev] = commit;\n+\n+\t\tif (with_upstream_branches) {\n+\t\t\tunsigned char branch_sha1[20];\n+\t\t\tstruct branch *branch;\n+\t\t\tint current_ref_name_cnt = ref_name_cnt;\n+\n+\t\t\t/* If this ref is already marked as an upstream, skip */\n+\t\t\tif (topics & flag)\n+\t\t\t\tcontinue;\n+\n+\t\t\tbranch = branch_get(ref_name[num_rev]);\n+\n+\t\t\tif (!branch || !branch->merge || !branch->merge[0] ||\n+\t\t\t    !branch->merge[0]->dst)\n+\t\t\t\tcontinue;\n+\t\t\tif (get_sha1(branch->merge[0]->dst, branch_sha1))\n+\t\t\t\tcontinue;\n+\t\t\tappend_remote_ref(branch->merge[0]->dst, branch_sha1, 0, 0);\n+\t\t\t/* If append_remote_ref didn't add a ref, it's either\n+\t\t\t * because it's an upstream of a previous ref, or because\n+\t\t\t * it was given on the command line. In neither case we\n+\t\t\t * want the bit being set. */\n+\t\t\tif (topics && current_ref_name_cnt != ref_name_cnt)\n+\t\t\t\ttopics |= 1u << (ref_name_cnt + REV_SHIFT - 1);\n+\t\t} else if (topics && num_rev == 0) {\n+\t\t\ttopics |= flag;\n+\t\t}\n \t}\n+\t/* topics is filled above with a mask of refs corresponding to\n+\t * upstream branches, or the first given ref. It also still contains\n+\t * the original bool value, which may match some bookkeeping flags,\n+\t * so filter that out.\n+\t */\n+\ttopics &= ~0u << REV_SHIFT;\n+\n \tfor (i = 0; i < num_rev; i++)\n \t\trev_mask[i] = rev[i]->object.flags;\n \n@@ -928,7 +966,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)\n \t\t\t\t\t  commit->parents->next);\n \t\t\tif (topics &&\n \t\t\t    !is_merge_point &&\n-\t\t\t    (this_flag & (1u << REV_SHIFT)))\n+\t\t\t    (this_flag & topics))\n \t\t\t\tcontinue;\n \t\t\tif (dense && is_merge &&\n \t\t\t    omit_in_dense(commit, rev, num_rev))\n-- \n2.3.0.2.g4d8711e\n"}]}