git branch -vv will show "gone" next to a remote tracking branch if it
does not exist. for-each-ref is suitable for parsing but had no way of
showing this information.

This introduces "%(upstream:gone)" to display "gone" in the formatted
output if the ref does not exist or an empty string otherwise, analogous
to git branch -vv.

Signed-off-by: Øystein Walle <oys...@gmail.com>
---
 Documentation/git-for-each-ref.txt |  5 +++--
 ref-filter.c                       | 10 +++++++++-
 t/t6300-for-each-ref.sh            | 12 ++++++++++++
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-for-each-ref.txt 
b/Documentation/git-for-each-ref.txt
index f57e69b..039a86b 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -114,8 +114,9 @@ upstream::
        `refname` above.  Additionally respects `:track` to show
        "[ahead N, behind M]" and `:trackshort` to show the terse
        version: ">" (ahead), "<" (behind), "<>" (ahead and behind),
-       or "=" (in sync).  Has no effect if the ref does not have
-       tracking information associated with it.
+       or "=" (in sync) and `:gone` to show "gone" if the remote ref
+       does not exist, or an empty string if it does. Has no effect if
+       the ref does not have tracking information associated with it.
 
 push::
        The name of a local ref which represents the `@{push}` location
diff --git a/ref-filter.c b/ref-filter.c
index bc551a7..5402052 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -37,7 +37,7 @@ static struct used_atom {
        union {
                char color[COLOR_MAXLEN];
                struct align align;
-               enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT }
+               enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT, RR_GONE }
                        remote_ref;
                struct {
                        enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, 
C_SUB } option;
@@ -67,6 +67,8 @@ static void remote_ref_atom_parser(struct used_atom *atom, 
const char *arg)
                atom->u.remote_ref = RR_TRACK;
        else if (!strcmp(arg, "trackshort"))
                atom->u.remote_ref = RR_TRACKSHORT;
+       else if (!strcmp(arg, "gone"))
+               atom->u.remote_ref = RR_GONE;
        else
                die(_("unrecognized format: %%(%s)"), atom->name);
 }
@@ -923,6 +925,12 @@ static void fill_remote_ref_details(struct used_atom 
*atom, const char *refname,
                        *s = ">";
                else
                        *s = "<>";
+       } else if (atom->u.remote_ref == RR_GONE) {
+               const char *upstream;
+               if (stat_tracking_info(branch, &num_ours, &num_theirs, 
&upstream) < 0)
+                       *s = "gone";
+               else
+                       *s = "";
        } else /* RR_NORMAL */
                *s = refname;
 }
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 19a2823..1fc5d1d 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -383,6 +383,18 @@ test_expect_success 'Check that :track[short] works when 
upstream is invalid' '
        test_cmp expected actual
 '
 
+test_expect_success 'Check that :gone produces expected results' '
+       cat >expected <<-\EOF &&
+gone
+       EOF
+       test_when_finished "git config branch.master.merge refs/heads/master" &&
+       git config branch.master.merge refs/heads/does-not-exist &&
+       git for-each-ref \
+               --format="%(upstream:gone)" \
+               refs/heads >actual &&
+       test_cmp expected actual
+'
+
 test_expect_success 'Check for invalid refname format' '
        test_must_fail git for-each-ref --format="%(refname:INVALID)"
 '
-- 
2.9.2

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to