remote.c: return upstream name from stat_tracking_info

After calling stat_tracking_info, callers often want to print the name of the upstream branch (in addition to the tracking count). To do this, they have to access branch->merge->dst[0] themselves. This is not wrong, as the return value from stat_tracking_info tells us whether we have an upstream branch or not. But it is a bit leaky, as we make an assumption about how it calculated the upstream name. Instead, let's add an out-parameter that lets the caller know the upstream name we found. As a bonus, we can get rid of the unusual tri-state return from the function. We no longer need to use it to differentiate between "no tracking config" and "tracking ref does not exist" (since you can check the upstream_name for that), so we can just use the usual 0/-1 convention for success/error. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed May 21, 2015 at 20:49 UTC 979cb245e29b35812d2d71a04069ba7a4580981f
5 files changed +32 -44
builtin/branch.c
+5 -11
@@ -425,25 +425,19 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
425 int ours, theirs;
426 char *ref = NULL;
427 struct branch *branch = branch_get(branch_name);
428 + const char *upstream;
429 struct strbuf fancy = STRBUF_INIT;
430 int upstream_is_gone = 0;
431 int added_decoration = 1;
432
432 - switch (stat_tracking_info(branch, &ours, &theirs)) {
433 - case 0:
434 - /* no base */
435 - return;
436 - case -1:
437 - /* with "gone" base */
433 + if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) {
434 + if (!upstream)
435 + return;
436 upstream_is_gone = 1;
439 - break;
440 - default:
441 - /* with base */
442 - break;
437 }
438
439 if (show_upstream_ref) {
446 - ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
440 + ref = shorten_unambiguous_ref(upstream, 0);
441 if (want_color(branch_use_color))
442 strbuf_addf(&fancy, "%s%s%s",
443 branch_get_color(BRANCH_COLOR_UPSTREAM),
builtin/for-each-ref.c
+2 -2
@@ -716,7 +716,7 @@ static void populate_value(struct refinfo *ref)
716 char buf[40];
717
718 if (stat_tracking_info(branch, &num_ours,
719 - &num_theirs) != 1)
719 + &num_theirs, NULL))
720 continue;
721
722 if (!num_ours && !num_theirs)
@@ -738,7 +738,7 @@ static void populate_value(struct refinfo *ref)
738 assert(branch);
739
740 if (stat_tracking_info(branch, &num_ours,
741 - &num_theirs) != 1)
741 + &num_theirs, NULL))
742 continue;
743
744 if (!num_ours && !num_theirs)
remote.c
+17 -18
@@ -1938,12 +1938,15 @@ int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1)
1938
1939 /*
1940 * Compare a branch with its upstream, and save their differences (number
1941 - * of commits) in *num_ours and *num_theirs.
1941 + * of commits) in *num_ours and *num_theirs. The name of the upstream branch
1942 + * (or NULL if no upstream is defined) is returned via *upstream_name, if it
1943 + * is not itself NULL.
1944 *
1943 - * Return 0 if branch has no upstream (no base), -1 if upstream is missing
1944 - * (with "gone" base), otherwise 1 (with base).
1945 + * Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
1946 + * upstream defined, or ref does not exist), 0 otherwise.
1947 */
1946 -int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
1948 +int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
1949 + const char **upstream_name)
1950 {
1951 unsigned char sha1[20];
1952 struct commit *ours, *theirs;
@@ -1954,8 +1957,10 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
1957
1958 /* Cannot stat unless we are marked to build on top of somebody else. */
1959 base = branch_get_upstream(branch, NULL);
1960 + if (upstream_name)
1961 + *upstream_name = base;
1962 if (!base)
1958 - return 0;
1963 + return -1;
1964
1965 /* Cannot stat if what we used to build on no longer exists */
1966 if (read_ref(base, sha1))
@@ -1973,7 +1978,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
1978 /* are we the same? */
1979 if (theirs == ours) {
1980 *num_theirs = *num_ours = 0;
1976 - return 1;
1981 + return 0;
1982 }
1983
1984 /* Run "rev-list --left-right ours...theirs" internally... */
@@ -2009,7 +2014,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
2014 /* clear object flags smudged by the above traversal */
2015 clear_commit_marks(ours, ALL_REV_FLAGS);
2016 clear_commit_marks(theirs, ALL_REV_FLAGS);
2012 - return 1;
2017 + return 0;
2018 }
2019
2020 /*
@@ -2018,23 +2023,17 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
2023 int format_tracking_info(struct branch *branch, struct strbuf *sb)
2024 {
2025 int ours, theirs;
2026 + const char *full_base;
2027 char *base;
2028 int upstream_is_gone = 0;
2029
2024 - switch (stat_tracking_info(branch, &ours, &theirs)) {
2025 - case 0:
2026 - /* no base */
2027 - return 0;
2028 - case -1:
2029 - /* with "gone" base */
2030 + if (stat_tracking_info(branch, &ours, &theirs, &full_base) < 0) {
2031 + if (!full_base)
2032 + return 0;
2033 upstream_is_gone = 1;
2031 - break;
2032 - default:
2033 - /* with base */
2034 - break;
2034 }
2035
2037 - base = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
2036 + base = shorten_unambiguous_ref(full_base, 0);
2037 if (upstream_is_gone) {
2038 strbuf_addf(sb,
2039 _("Your branch is based on '%s', but the upstream is gone.\n"),
remote.h
+2 -1
@@ -239,7 +239,8 @@ enum match_refs_flags {
239 };
240
241 /* Reporting of tracking info */
242 -int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs);
242 +int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
243 + const char **upstream_name);
244 int format_tracking_info(struct branch *branch, struct strbuf *sb);
245
246 struct ref *get_local_heads(void);
wt-status.c
+6 -12
@@ -1532,21 +1532,15 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
1532
1533 color_fprintf(s->fp, branch_color_local, "%s", branch_name);
1534
1535 - switch (stat_tracking_info(branch, &num_ours, &num_theirs)) {
1536 - case 0:
1537 - /* no base */
1538 - fputc(s->null_termination ? '\0' : '\n', s->fp);
1539 - return;
1540 - case -1:
1541 - /* with "gone" base */
1535 + if (stat_tracking_info(branch, &num_ours, &num_theirs, &base) < 0) {
1536 + if (!base) {
1537 + fputc(s->null_termination ? '\0' : '\n', s->fp);
1538 + return;
1539 + }
1540 +
1541 upstream_is_gone = 1;
1543 - break;
1544 - default:
1545 - /* with base */
1546 - break;
1542 }
1543
1549 - base = branch->merge[0]->dst;
1544 base = shorten_unambiguous_ref(base, 0);
1545 color_fprintf(s->fp, header_color, "...");
1546 color_fprintf(s->fp, branch_color_remote, "%s", base);