{"thread":{"id":"16645","subject":"get upstream branch","startedAt":"2008-12-09T04:52:03Z","lastAt":"2008-12-09T15:51:02Z","messageCount":7,"participants":["Jeff Whiteside","Junio C Hamano","Jeff King","Sverre Rabbelier","Peter Harris","Santi Béjar"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"97397","messageId":"3ab397d0812082052j6a45d05dr1c863aa260826f4@mail.gmail.com","threadId":"16645","inReplyTo":null,"subject":"get upstream branch","fromName":"Jeff Whiteside","fromEmail":"jeff.m.whiteside@gmail.com","sentAt":"2008-12-09T04:52:03Z","receivedAt":"2008-12-09T04:52:03Z","isPatch":false,"sender":{"key":"jeff.m.whiteside@gmail.com","avatar":null},"body":"Hi,\n\nDoes anyone know how to programmatically get the upstream/parent\nbranch of a branch?  I'm trying to write a gui, but looking at gitk's\ntcl code isn't helping me much.\n\nThanks,\n\nWhiteside\n"},{"id":"97398","messageId":"7vljup6hdf.fsf@gitster.siamese.dyndns.org","threadId":"16645","inReplyTo":"3ab397d0812082052j6a45d05dr1c863aa260826f4@mail.gmail.com","subject":"Re: get upstream branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-12-09T05:35:08Z","receivedAt":"2008-12-09T05:35:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jeff Whiteside\" <jeff.m.whiteside@gmail.com> writes:\n\n> Does anyone know how to programmatically get the upstream/parent\n> branch of a branch?\n\nI do not think there is any plumbing facility to get that information, as\nsuch \"upstream/parent\" concept did not exist back then when building the\nwhole Porcelain by scripting was the norm.\n\nThis should give \"git branch -v -v it\" to show the remote tracking\nbranch that is merged when \"git pull\" without any other parameters is\nissued while on branch \"it\".\n\nObviously untested.\n\n builtin-branch.c |   26 +++++++++++++++-----------\n 1 files changed, 15 insertions(+), 11 deletions(-)\n\ndiff --git c/builtin-branch.c w/builtin-branch.c\nindex 494cbac..565d99c 100644\n--- c/builtin-branch.c\n+++ w/builtin-branch.c\n@@ -279,11 +279,15 @@ static int ref_cmp(const void *r1, const void *r2)\n \treturn strcmp(c1->name, c2->name);\n }\n \n-static void fill_tracking_info(struct strbuf *stat, const char *branch_name)\n+static void fill_tracking_info(struct strbuf *stat, const char *branch_name,\n+\t\t\t       int verbosity)\n {\n \tint ours, theirs;\n \tstruct branch *branch = branch_get(branch_name);\n \n+\tif (verbosity > 1 && branch->merge[0]->dst)\n+\t\tstrbuf_addf(stat, \"(follows %s) \", branch->merge[0]->dst);\n+\n \tif (!stat_tracking_info(branch, &ours, &theirs) || (!ours && !theirs))\n \t\treturn;\n \tif (!ours)\n@@ -305,7 +309,7 @@ static int matches_merge_filter(struct commit *commit)\n \treturn (is_merged == (merge_filter == SHOW_MERGED));\n }\n \n-static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n+static void print_ref_item(struct ref_item *item, int maxwidth, int verbosity,\n \t\t\t   int abbrev, int current)\n {\n \tchar c;\n@@ -333,7 +337,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n \t\tcolor = COLOR_BRANCH_CURRENT;\n \t}\n \n-\tif (verbose) {\n+\tif (verbosity > 0) {\n \t\tstruct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT;\n \t\tconst char *sub = \" **** invalid ref ****\";\n \n@@ -345,7 +349,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n \t\t}\n \n \t\tif (item->kind == REF_LOCAL_BRANCH)\n-\t\t\tfill_tracking_info(&stat, item->name);\n+\t\t\tfill_tracking_info(&stat, item->name, verbosity);\n \n \t\tprintf(\"%c %s%-*s%s %s %s%s\\n\", c, branch_get_color(color),\n \t\t       maxwidth, item->name,\n@@ -373,7 +377,7 @@ static int calc_maxwidth(struct ref_list *refs)\n \treturn w;\n }\n \n-static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)\n+static void print_ref_list(int kinds, int detached, int verbosity, int abbrev, struct commit_list *with_commit)\n {\n \tint i;\n \tstruct ref_list ref_list;\n@@ -393,7 +397,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str\n \t\t\t\t   (struct object *) filter, \"\");\n \t\tref_list.revs.limited = 1;\n \t\tprepare_revision_walk(&ref_list.revs);\n-\t\tif (verbose)\n+\t\tif (verbosity > 0)\n \t\t\tref_list.maxwidth = calc_maxwidth(&ref_list);\n \t}\n \n@@ -407,7 +411,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str\n \t\titem.commit = head_commit;\n \t\tif (strlen(item.name) > ref_list.maxwidth)\n \t\t\tref_list.maxwidth = strlen(item.name);\n-\t\tprint_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);\n+\t\tprint_ref_item(&item, ref_list.maxwidth, verbosity, abbrev, 1);\n \t\tfree(item.name);\n \t}\n \n@@ -415,7 +419,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str\n \t\tint current = !detached &&\n \t\t\t(ref_list.list[i].kind == REF_LOCAL_BRANCH) &&\n \t\t\t!strcmp(ref_list.list[i].name, head);\n-\t\tprint_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose,\n+\t\tprint_ref_item(&ref_list.list[i], ref_list.maxwidth, verbosity,\n \t\t\t       abbrev, current);\n \t}\n \n@@ -498,7 +502,7 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int\n int cmd_branch(int argc, const char **argv, const char *prefix)\n {\n \tint delete = 0, rename = 0, force_create = 0;\n-\tint verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n+\tint verbosity = 0, abbrev = DEFAULT_ABBREV, detached = 0;\n \tint reflog = 0;\n \tenum branch_track track;\n \tint kinds = REF_LOCAL_BRANCH;\n@@ -506,7 +510,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \n \tstruct option options[] = {\n \t\tOPT_GROUP(\"Generic options\"),\n-\t\tOPT__VERBOSE(&verbose),\n+\t\tOPT__VERBOSITY(&verbosity),\n \t\tOPT_SET_INT( 0 , \"track\",  &track, \"set up tracking mode (see git-pull(1))\",\n \t\t\tBRANCH_TRACK_EXPLICIT),\n \t\tOPT_BOOLEAN( 0 , \"color\",  &branch_use_color, \"use colored output\"),\n@@ -577,7 +581,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \tif (delete)\n \t\treturn delete_branches(argc, argv, delete > 1, kinds);\n \telse if (argc == 0)\n-\t\tprint_ref_list(kinds, detached, verbose, abbrev, with_commit);\n+\t\tprint_ref_list(kinds, detached, verbosity, abbrev, with_commit);\n \telse if (rename && (argc == 1))\n \t\trename_branch(head, argv[0], rename > 1);\n \telse if (rename && (argc == 2))\n"},{"id":"97400","messageId":"20081209055629.GB2972@coredump.intra.peff.net","threadId":"16645","inReplyTo":"7vljup6hdf.fsf@gitster.siamese.dyndns.org","subject":"Re: get upstream branch","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-12-09T05:56:29Z","receivedAt":"2008-12-09T05:56:29Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Dec 08, 2008 at 09:35:08PM -0800, Junio C Hamano wrote:\n\n> I do not think there is any plumbing facility to get that information, as\n> such \"upstream/parent\" concept did not exist back then when building the\n> whole Porcelain by scripting was the norm.\n\nIn one of my scripts I do something like this (actually this is not\nstraight from my script, as the operation there is \"find all pairs of\nlocal/remote branches\" and this is \"find the current upstream\"):\n\n  ref=`git symbolic-ref HEAD`\n  head=${ref#refs/heads/}\n  remote=`git config branch.$head.remote`\n  branch=`git config branch.$head.merge`\n  echo refs/remote/$remote/${branch#refs/heads/}\n\nAnd obviously this is missing error checking for the detached HEAD\n(symbolic-ref should fail) and no tracking branch ($remote and/or $branch\nwill be empty) cases.\n\n-Peff\n"},{"id":"97403","messageId":"7v8wqp6e89.fsf@gitster.siamese.dyndns.org","threadId":"16645","inReplyTo":"20081209055629.GB2972@coredump.intra.peff.net","subject":"Re: get upstream branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-12-09T06:43:02Z","receivedAt":"2008-12-09T06:43:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> In one of my scripts I do something like this (actually this is not\n> straight from my script, as the operation there is \"find all pairs of\n> local/remote branches\" and this is \"find the current upstream\"):\n>\n>   ref=`git symbolic-ref HEAD`\n>   head=${ref#refs/heads/}\n>   remote=`git config branch.$head.remote`\n>   branch=`git config branch.$head.merge`\n>   echo refs/remote/$remote/${branch#refs/heads/}\n>\n> And obviously this is missing error checking for the detached HEAD\n> (symbolic-ref should fail) and no tracking branch ($remote and/or $branch\n> will be empty) cases.\n\nYeah, add any nonstandard layout to that set of things that are missing,\nbut in practice it should not matter.\n"},{"id":"97404","messageId":"bd6139dc0812082246u59164cf6tb20f8c98ede7b666@mail.gmail.com","threadId":"16645","inReplyTo":"7vljup6hdf.fsf@gitster.siamese.dyndns.org","subject":"Re: get upstream branch","fromName":"Sverre Rabbelier","fromEmail":"alturin@gmail.com","sentAt":"2008-12-09T06:46:25Z","receivedAt":"2008-12-09T06:46:25Z","isPatch":false,"sender":{"key":"alturin@gmail.com","avatar":null},"body":"On Tue, Dec 9, 2008 at 06:35, Junio C Hamano <gitster@pobox.com> wrote:\n> This should give \"git branch -v -v it\" to show the remote tracking\n> branch that is merged when \"git pull\" without any other parameters is\n> issued while on branch \"it\".\n\nBut won't that leave Jeff Whiteside in the same position he was\nalready? As he is writing a GUI having the functionality in 'git\nbranch' is not useful, what with it being porcelain and all.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"97435","messageId":"eaa105840812090725p6158697au2177e0de3d4e5966@mail.gmail.com","threadId":"16645","inReplyTo":"3ab397d0812082052j6a45d05dr1c863aa260826f4@mail.gmail.com","subject":"Re: get upstream branch","fromName":"Peter Harris","fromEmail":"git@peter.is-a-geek.org","sentAt":"2008-12-09T15:25:09Z","receivedAt":"2008-12-09T15:25:09Z","isPatch":false,"sender":{"key":"git@peter.is-a-geek.org","avatar":null},"body":"On Mon, Dec 8, 2008 at 11:52 PM, Jeff Whiteside wrote:\n>\n> Does anyone know how to programmatically get the upstream/parent\n> branch of a branch?  I'm trying to write a gui, but looking at gitk's\n> tcl code isn't helping me much.\n\nWould C++ code be a better help?\n\nqgit is somewhat similar to gitk:\nhttp://digilander.libero.it/mcostalba/\ngit://git.kernel.org/pub/scm/qgit/qgit.git\ngit://git.kernel.org/pub/scm/qgit/qgit4.git\n\nPeter Harris\n"},{"id":"97438","messageId":"adf1fd3d0812090751r5d5a1c49k199e5e92316e0f9d@mail.gmail.com","threadId":"16645","inReplyTo":"7v8wqp6e89.fsf@gitster.siamese.dyndns.org","subject":"Re: get upstream branch","fromName":"Santi Béjar","fromEmail":"santi@agolina.net","sentAt":"2008-12-09T15:51:02Z","receivedAt":"2008-12-09T15:51:02Z","isPatch":false,"sender":{"key":"santi@agolina.net","avatar":null},"body":"2008/12/9 Junio C Hamano <gitster@pobox.com>:\n> Jeff King <peff@peff.net> writes:\n>\n>> In one of my scripts I do something like this (actually this is not\n>> straight from my script, as the operation there is \"find all pairs of\n>> local/remote branches\" and this is \"find the current upstream\"):\n>>\n>>   ref=`git symbolic-ref HEAD`\n>>   head=${ref#refs/heads/}\n>>   remote=`git config branch.$head.remote`\n>>   branch=`git config branch.$head.merge`\n>>   echo refs/remote/$remote/${branch#refs/heads/}\n>>\n>> And obviously this is missing error checking for the detached HEAD\n>> (symbolic-ref should fail) and no tracking branch ($remote and/or $branch\n>> will be empty) cases.\n>\n> Yeah, add any nonstandard layout to that set of things that are missing,\n> but in practice it should not matter.\n\nIn \"git pull --rebase\" this is used to know the hash of the tracking branch:\n\n        . git-parse-remote &&\n        origin=\"$1\"\n        test -z \"$origin\" && origin=$(get_default_remote)\n        reflist=\"$(get_remote_refs_for_fetch \"$@\" 2>/dev/null |\n                sed \"s|refs/heads/\\(.*\\):|\\1|\")\" &&\n        oldremoteref=\"$(git rev-parse -q --verify \\\n                \"refs/remotes/$origin/$reflist\")\"\n\nSanti\n"}]}