int ours, theirs;
char *ref = NULL;
struct branch *branch = branch_get(branch_name);
+ const char *upstream;
struct strbuf fancy = STRBUF_INIT;
int upstream_is_gone = 0;
int added_decoration = 1;
- switch (stat_tracking_info(branch, &ours, &theirs)) {
- case 0:
- /* no base */
- return;
- case -1:
- /* with "gone" base */
+ if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) {
+ if (!upstream)
+ return;
upstream_is_gone = 1;
- break;
- default:
- /* with base */
- break;
}
if (show_upstream_ref) {
- ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
+ ref = shorten_unambiguous_ref(upstream, 0);
if (want_color(branch_use_color))
strbuf_addf(&fancy, "%s%s%s",
branch_get_color(BRANCH_COLOR_UPSTREAM),
char buf[40];
if (stat_tracking_info(branch, &num_ours,
- &num_theirs) != 1)
+ &num_theirs, NULL))
continue;
if (!num_ours && !num_theirs)
assert(branch);
if (stat_tracking_info(branch, &num_ours,
- &num_theirs) != 1)
+ &num_theirs, NULL))
continue;
if (!num_ours && !num_theirs)
/*
* Compare a branch with its upstream, and save their differences (number
- * of commits) in *num_ours and *num_theirs.
+ * of commits) in *num_ours and *num_theirs. The name of the upstream branch
+ * (or NULL if no upstream is defined) is returned via *upstream_name, if it
+ * is not itself NULL.
*
- * Return 0 if branch has no upstream (no base), -1 if upstream is missing
- * (with "gone" base), otherwise 1 (with base).
+ * Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
+ * upstream defined, or ref does not exist), 0 otherwise.
*/
-int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
+int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
+ const char **upstream_name)
{
unsigned char sha1[20];
struct commit *ours, *theirs;
/* Cannot stat unless we are marked to build on top of somebody else. */
base = branch_get_upstream(branch, NULL);
+ if (upstream_name)
+ *upstream_name = base;
if (!base)
- return 0;
+ return -1;
/* Cannot stat if what we used to build on no longer exists */
if (read_ref(base, sha1))
/* are we the same? */
if (theirs == ours) {
*num_theirs = *num_ours = 0;
- return 1;
+ return 0;
}
/* Run "rev-list --left-right ours...theirs" internally... */
/* clear object flags smudged by the above traversal */
clear_commit_marks(ours, ALL_REV_FLAGS);
clear_commit_marks(theirs, ALL_REV_FLAGS);
- return 1;
+ return 0;
}
/*
int format_tracking_info(struct branch *branch, struct strbuf *sb)
{
int ours, theirs;
+ const char *full_base;
char *base;
int upstream_is_gone = 0;
- switch (stat_tracking_info(branch, &ours, &theirs)) {
- case 0:
- /* no base */
- return 0;
- case -1:
- /* with "gone" base */
+ if (stat_tracking_info(branch, &ours, &theirs, &full_base) < 0) {
+ if (!full_base)
+ return 0;
upstream_is_gone = 1;
- break;
- default:
- /* with base */
- break;
}
- base = shorten_unambiguous_ref(branch->merge[0]->dst, 0);
+ base = shorten_unambiguous_ref(full_base, 0);
if (upstream_is_gone) {
strbuf_addf(sb,
_("Your branch is based on '%s', but the upstream is gone.\n"),
};
/* Reporting of tracking info */
-int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs);
+int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
+ const char **upstream_name);
int format_tracking_info(struct branch *branch, struct strbuf *sb);
struct ref *get_local_heads(void);
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
- switch (stat_tracking_info(branch, &num_ours, &num_theirs)) {
- case 0:
- /* no base */
- fputc(s->null_termination ? '\0' : '\n', s->fp);
- return;
- case -1:
- /* with "gone" base */
+ if (stat_tracking_info(branch, &num_ours, &num_theirs, &base) < 0) {
+ if (!base) {
+ fputc(s->null_termination ? '\0' : '\n', s->fp);
+ return;
+ }
+
upstream_is_gone = 1;
- break;
- default:
- /* with base */
- break;
}
- base = branch->merge[0]->dst;
base = shorten_unambiguous_ref(base, 0);
color_fprintf(s->fp, header_color, "...");
color_fprintf(s->fp, branch_color_remote, "%s", base);