summaryrefslogtreecommitdiff
path: root/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'remote.c')
-rw-r--r--remote.c74
1 files changed, 50 insertions, 24 deletions
diff --git a/remote.c b/remote.c
index 9cc3b07..e50f760 100644
--- a/remote.c
+++ b/remote.c
@@ -820,11 +820,11 @@ struct ref *copy_ref_list(const struct ref *ref)
return ret;
}
-static void free_ref(struct ref *ref)
+void free_one_ref(struct ref *ref)
{
if (!ref)
return;
- free_ref(ref->peer_ref);
+ free_one_ref(ref->peer_ref);
free(ref->remote_status);
free(ref->symref);
free(ref);
@@ -835,7 +835,7 @@ void free_refs(struct ref *ref)
struct ref *next;
while (ref) {
next = ref->next;
- free_ref(ref);
+ free_one_ref(ref);
ref = next;
}
}
@@ -1880,37 +1880,27 @@ int resolve_remote_symref(struct ref *ref, struct ref *list)
}
/*
- * Lookup the upstream branch for the given branch and if present, optionally
- * compute the commit ahead/behind values for the pair.
+ * Compute the commit ahead/behind values for the pair branch_name, base.
*
* If abf is AHEAD_BEHIND_FULL, compute the full ahead/behind and return the
* counts in *num_ours and *num_theirs. If abf is AHEAD_BEHIND_QUICK, skip
* the (potentially expensive) a/b computation (*num_ours and *num_theirs are
* set to zero).
*
- * The name of the upstream branch (or NULL if no upstream is defined) is
- * returned via *upstream_name, if it is not itself NULL.
- *
- * Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
- * upstream defined, or ref does not exist). Returns 0 if the commits are
- * identical. Returns 1 if commits are different.
+ * Returns -1 if num_ours and num_theirs could not be filled in (e.g., ref
+ * does not exist). Returns 0 if the commits are identical. Returns 1 if
+ * commits are different.
*/
-int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
- const char **upstream_name, enum ahead_behind_flags abf)
+
+static int stat_branch_pair(const char *branch_name, const char *base,
+ int *num_ours, int *num_theirs,
+ enum ahead_behind_flags abf)
{
struct object_id oid;
struct commit *ours, *theirs;
struct rev_info revs;
- const char *base;
struct argv_array argv = ARGV_ARRAY_INIT;
- /* 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 -1;
-
/* Cannot stat if what we used to build on no longer exists */
if (read_ref(base, &oid))
return -1;
@@ -1918,7 +1908,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
if (!theirs)
return -1;
- if (read_ref(branch->refname, &oid))
+ if (read_ref(branch_name, &oid))
return -1;
ours = lookup_commit_reference(the_repository, &oid);
if (!ours)
@@ -1932,7 +1922,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
if (abf == AHEAD_BEHIND_QUICK)
return 1;
if (abf != AHEAD_BEHIND_FULL)
- BUG("stat_tracking_info: invalid abf '%d'", abf);
+ BUG("stat_branch_pair: invalid abf '%d'", abf);
/* Run "rev-list --left-right ours...theirs" internally... */
argv_array_push(&argv, ""); /* ignored */
@@ -1967,6 +1957,42 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
}
/*
+ * Lookup the tracking branch for the given branch and if present, optionally
+ * compute the commit ahead/behind values for the pair.
+ *
+ * If for_push is true, the tracking branch refers to the push branch,
+ * otherwise it refers to the upstream branch.
+ *
+ * The name of the tracking branch (or NULL if it is not defined) is
+ * returned via *tracking_name, if it is not itself NULL.
+ *
+ * If abf is AHEAD_BEHIND_FULL, compute the full ahead/behind and return the
+ * counts in *num_ours and *num_theirs. If abf is AHEAD_BEHIND_QUICK, skip
+ * the (potentially expensive) a/b computation (*num_ours and *num_theirs are
+ * set to zero).
+ *
+ * Returns -1 if num_ours and num_theirs could not be filled in (e.g., no
+ * upstream defined, or ref does not exist). Returns 0 if the commits are
+ * identical. Returns 1 if commits are different.
+ */
+int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
+ const char **tracking_name, int for_push,
+ enum ahead_behind_flags abf)
+{
+ const char *base;
+
+ /* Cannot stat unless we are marked to build on top of somebody else. */
+ base = for_push ? branch_get_push(branch, NULL) :
+ branch_get_upstream(branch, NULL);
+ if (tracking_name)
+ *tracking_name = base;
+ if (!base)
+ return -1;
+
+ return stat_branch_pair(branch->refname, base, num_ours, num_theirs, abf);
+}
+
+/*
* Return true when there is anything to report, otherwise false.
*/
int format_tracking_info(struct branch *branch, struct strbuf *sb,
@@ -1977,7 +2003,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb,
char *base;
int upstream_is_gone = 0;
- sti = stat_tracking_info(branch, &ours, &theirs, &full_base, abf);
+ sti = stat_tracking_info(branch, &ours, &theirs, &full_base, 0, abf);
if (sti < 0) {
if (!full_base)
return 0;