Merge branch 'dr/ref-filter-push-track-fix'
authorJunio C Hamano <gitster@pobox.com>
Wed, 8 May 2019 15:37:26 +0000 (00:37 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 May 2019 15:37:26 +0000 (00:37 +0900)
%(push:track) token used in the --format option to "git
for-each-ref" and friends was not showing the right branch, which
has been fixed.

* dr/ref-filter-push-track-fix:
ref-filter: use correct branch for %(push:track)

1  2 
ref-filter.c
remote.c
remote.h
wt-status.c
diff --combined ref-filter.c
index 8d11a94cbd40d89302ec8b03245744f00bc02abf,cadafec28345136d31bf5f690ad7e0dfabcb20fe..8500671bc60957432568443de42b548612106f3c
@@@ -485,10 -485,6 +485,10 @@@ static struct 
        { "if", SOURCE_NONE, FIELD_STR, if_atom_parser },
        { "then", SOURCE_NONE },
        { "else", SOURCE_NONE },
 +      /*
 +       * Please update $__git_ref_fieldlist in git-completion.bash
 +       * when you add new atoms
 +       */
  };
  
  #define REF_FORMATTING_STATE_INIT  { 0, NULL }
@@@ -917,7 -913,7 +917,7 @@@ static void grab_common_values(struct a
  }
  
  /* See grab_values */
 -static void grab_tag_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 +static void grab_tag_values(struct atom_value *val, int deref, struct object *obj)
  {
        int i;
        struct tag *tag = (struct tag *) obj;
  }
  
  /* See grab_values */
 -static void grab_commit_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 +static void grab_commit_values(struct atom_value *val, int deref, struct object *obj)
  {
        int i;
        struct commit *commit = (struct commit *) obj;
        }
  }
  
 -static const char *find_wholine(const char *who, int wholen, const char *buf, unsigned long sz)
 +static const char *find_wholine(const char *who, int wholen, const char *buf)
  {
        const char *eol;
        while (*buf) {
@@@ -1068,7 -1064,7 +1068,7 @@@ static void grab_date(const char *buf, 
  }
  
  /* See grab_values */
 -static void grab_person(const char *who, struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 +static void grab_person(const char *who, struct atom_value *val, int deref, void *buf)
  {
        int i;
        int wholen = strlen(who);
                    !starts_with(name + wholen, "date"))
                        continue;
                if (!wholine)
 -                      wholine = find_wholine(who, wholen, buf, sz);
 +                      wholine = find_wholine(who, wholen, buf);
                if (!wholine)
                        return; /* no point looking for it */
                if (name[wholen] == 0)
        if (strcmp(who, "tagger") && strcmp(who, "committer"))
                return; /* "author" for commit object is not wanted */
        if (!wholine)
 -              wholine = find_wholine(who, wholen, buf, sz);
 +              wholine = find_wholine(who, wholen, buf);
        if (!wholine)
                return;
        for (i = 0; i < used_atom_cnt; i++) {
        }
  }
  
 -static void find_subpos(const char *buf, unsigned long sz,
 +static void find_subpos(const char *buf,
                        const char **sub, unsigned long *sublen,
                        const char **body, unsigned long *bodylen,
                        unsigned long *nonsiglen,
@@@ -1196,7 -1192,7 +1196,7 @@@ static void append_lines(struct strbuf 
  }
  
  /* See grab_values */
 -static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 +static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf)
  {
        int i;
        const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL;
                    !starts_with(name, "contents"))
                        continue;
                if (!subpos)
 -                      find_subpos(buf, sz,
 +                      find_subpos(buf,
                                    &subpos, &sublen,
                                    &bodypos, &bodylen, &nonsiglen,
                                    &sigpos, &siglen);
@@@ -1269,19 -1265,19 +1269,19 @@@ static void fill_missing_values(struct 
   * pointed at by the ref itself; otherwise it is the object the
   * ref (which is a tag) refers to.
   */
 -static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 +static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf)
  {
        switch (obj->type) {
        case OBJ_TAG:
 -              grab_tag_values(val, deref, obj, buf, sz);
 -              grab_sub_body_contents(val, deref, obj, buf, sz);
 -              grab_person("tagger", val, deref, obj, buf, sz);
 +              grab_tag_values(val, deref, obj);
 +              grab_sub_body_contents(val, deref, buf);
 +              grab_person("tagger", val, deref, buf);
                break;
        case OBJ_COMMIT:
 -              grab_commit_values(val, deref, obj, buf, sz);
 -              grab_sub_body_contents(val, deref, obj, buf, sz);
 -              grab_person("author", val, deref, obj, buf, sz);
 -              grab_person("committer", val, deref, obj, buf, sz);
 +              grab_commit_values(val, deref, obj);
 +              grab_sub_body_contents(val, deref, buf);
 +              grab_person("author", val, deref, buf);
 +              grab_person("committer", val, deref, buf);
                break;
        case OBJ_TREE:
                /* grab_tree_values(val, deref, obj, buf, sz); */
@@@ -1392,7 -1388,8 +1392,8 @@@ static void fill_remote_ref_details(str
                *s = show_ref(&atom->u.remote_ref.refname, refname);
        else if (atom->u.remote_ref.option == RR_TRACK) {
                if (stat_tracking_info(branch, &num_ours, &num_theirs,
-                                      NULL, AHEAD_BEHIND_FULL) < 0) {
+                                      NULL, atom->u.remote_ref.push,
+                                      AHEAD_BEHIND_FULL) < 0) {
                        *s = xstrdup(msgs.gone);
                } else if (!num_ours && !num_theirs)
                        *s = xstrdup("");
                }
        } else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
                if (stat_tracking_info(branch, &num_ours, &num_theirs,
-                                      NULL, AHEAD_BEHIND_FULL) < 0) {
+                                      NULL, atom->u.remote_ref.push,
+                                      AHEAD_BEHIND_FULL) < 0) {
                        *s = xstrdup("");
                        return;
                }
@@@ -1520,7 -1518,7 +1522,7 @@@ static int get_object(struct ref_array_
                        return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
                                               oid_to_hex(&oi->oid), ref->refname);
                }
 -              grab_values(ref->value, deref, *obj, oi->content, oi->size);
 +              grab_values(ref->value, deref, *obj, oi->content);
        }
  
        grab_common_values(ref->value, deref, oi);
@@@ -2337,13 -2335,8 +2339,13 @@@ void parse_ref_sorting(struct ref_sorti
  
  int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset)
  {
 -      if (!arg) /* should --no-sort void the list ? */
 -              return -1;
 +      /*
 +       * NEEDSWORK: We should probably clear the list in this case, but we've
 +       * already munged the global used_atoms list, which would need to be
 +       * undone.
 +       */
 +      BUG_ON_OPT_NEG(unset);
 +
        parse_ref_sorting(opt->value, arg);
        return 0;
  }
diff --combined remote.c
index 3fe34eae853851f16271e0500b827ef855c30f14,0761d1ab21f57ccdc46528d022a2d365e85b0b71..e50f7602eda56e0fb9deeedcd9d3d4e0a800a822
+++ b/remote.c
@@@ -820,11 -820,11 +820,11 @@@ struct ref *copy_ref_list(const struct 
        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 +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 +1880,27 @@@ int resolve_remote_symref(struct ref *r
  }
  
  /*
-  * 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;
        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)
        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 */
        return 1;
  }
  
+ /*
+  * 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.
   */
@@@ -1977,7 -2003,7 +2003,7 @@@ int format_tracking_info(struct branch 
        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;
diff --combined remote.h
index f58332a27e96ee9e3ec7bea53e7889d62a0140a2,0138b3fb989ec825bf370b6e1f3a459a6a7f1d5d..6a1795947e6f3ff3265a406b2bc43c87842a0833
+++ b/remote.h
@@@ -131,10 -131,8 +131,10 @@@ int ref_compare_name(const void *, cons
  int check_ref_type(const struct ref *ref, int flags);
  
  /*
 - * Frees the entire list and peers of elements.
 + * Free a single ref and its peer, or an entire list of refs and their peers,
 + * respectively.
   */
 +void free_one_ref(struct ref *ref);
  void free_refs(struct ref *ref);
  
  struct oid_array;
@@@ -255,7 -253,8 +255,8 @@@ enum ahead_behind_flags 
  
  /* Reporting of tracking info */
  int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
-                      const char **upstream_name, enum ahead_behind_flags abf);
+                      const char **upstream_name, int for_push,
+                      enum ahead_behind_flags abf);
  int format_tracking_info(struct branch *branch, struct strbuf *sb,
                         enum ahead_behind_flags abf);
  
diff --combined wt-status.c
index b81fcd428de0d694308cb1a86439005701194a97,dcd9c005b9aab9391745c4f5b115f5ca1a9b47b9..f4fa98263857015b3d86e05df42e59591e74109a
@@@ -748,23 -748,12 +748,23 @@@ static int has_unmerged(struct wt_statu
  
  void wt_status_collect(struct wt_status *s)
  {
 +      trace2_region_enter("status", "worktrees", s->repo);
        wt_status_collect_changes_worktree(s);
 -      if (s->is_initial)
 +      trace2_region_leave("status", "worktrees", s->repo);
 +
 +      if (s->is_initial) {
 +              trace2_region_enter("status", "initial", s->repo);
                wt_status_collect_changes_initial(s);
 -      else
 +              trace2_region_leave("status", "initial", s->repo);
 +      } else {
 +              trace2_region_enter("status", "index", s->repo);
                wt_status_collect_changes_index(s);
 +              trace2_region_leave("status", "index", s->repo);
 +      }
 +
 +      trace2_region_enter("status", "untracked", s->repo);
        wt_status_collect_untracked(s);
 +      trace2_region_leave("status", "untracked", s->repo);
  
        wt_status_get_state(s->repo, &s->state, s->branch && !strcmp(s->branch, "HEAD"));
        if (s->state.merge_in_progress && !has_unmerged(s))
@@@ -1006,19 -995,13 +1006,19 @@@ size_t wt_status_locate_end(const char 
        return len;
  }
  
 -void wt_status_add_cut_line(FILE *fp)
 +void wt_status_append_cut_line(struct strbuf *buf)
  {
        const char *explanation = _("Do not modify or remove the line above.\nEverything below it will be ignored.");
 +
 +      strbuf_commented_addf(buf, "%s", cut_line);
 +      strbuf_add_commented_lines(buf, explanation, strlen(explanation));
 +}
 +
 +void wt_status_add_cut_line(FILE *fp)
 +{
        struct strbuf buf = STRBUF_INIT;
  
 -      fprintf(fp, "%c %s", comment_line_char, cut_line);
 -      strbuf_add_commented_lines(&buf, explanation, strlen(explanation));
 +      wt_status_append_cut_line(&buf);
        fputs(buf.buf, fp);
        strbuf_release(&buf);
  }
@@@ -1857,7 -1840,7 +1857,7 @@@ static void wt_shortstatus_print_tracki
        color_fprintf(s->fp, branch_color_local, "%s", branch_name);
  
        sti = stat_tracking_info(branch, &num_ours, &num_theirs, &base,
-                                s->ahead_behind_flags);
+                                0, s->ahead_behind_flags);
        if (sti < 0) {
                if (!base)
                        goto conclude;
@@@ -1996,7 -1979,7 +1996,7 @@@ static void wt_porcelain_v2_print_track
                branch = branch_get(branch_name);
                base = NULL;
                ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind,
-                                            &base, s->ahead_behind_flags);
+                                            &base, 0, s->ahead_behind_flags);
                if (base) {
                        base = shorten_unambiguous_ref(base, 0);
                        fprintf(s->fp, "# branch.upstream %s%c", base, eol);
@@@ -2308,13 -2291,6 +2308,13 @@@ static void wt_porcelain_v2_print(struc
  
  void wt_status_print(struct wt_status *s)
  {
 +      trace2_data_intmax("status", s->repo, "count/changed", s->change.nr);
 +      trace2_data_intmax("status", s->repo, "count/untracked",
 +                         s->untracked.nr);
 +      trace2_data_intmax("status", s->repo, "count/ignored", s->ignored.nr);
 +
 +      trace2_region_enter("status", "print", s->repo);
 +
        switch (s->status_format) {
        case STATUS_FORMAT_SHORT:
                wt_shortstatus_print(s);
                wt_longstatus_print(s);
                break;
        }
 +
 +      trace2_region_leave("status", "print", s->repo);
  }
  
  /**