From: Linus Torvalds <torva...@linux-foundation.org>
Date: Thu, 2 Feb 2017 11:37:49 -0800
Subject: [PATCH] ls-remote: add "--diff" option to show only refs that differ

My main use of "git ls-remote" tends to be to check what the other end
has when some pull request goes wrong (they forgot to push, or they used
the wrong ref name or whatever), and it ends up being hard to see all
the relevant data from the noise of people just having the same basic
tags etc from upstream.

So this adds a "--diff" option that shows only the refs that are
different from the local repository.  So when somebody asks me to pull,
I can now just trivially look at what they have that isn't already my
basic branches and tags.

Note that "--diff" implies "--refs" (ie it also disables showing peeled
tags).

Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
---

This is not a big deal, but maybe others have the same issues I've had. 
And maybe nobody else ever uses "git ls-remote". I dunno.

Also, I considered adding this feature as a more generic flag to 
"check_ref_type()" (ie add a REF_NONLOCAL option to complete the existing 
REF_NORMAL/REF_HEAD/etc flags), but that would have been a more involved 
patch and I'm not convinced it makes much sense for any other use, so I 
made it a specific local hack to ls-remote instead.

Comments?

 builtin/ls-remote.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 66cdd45cc..23469c3a6 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -2,6 +2,7 @@
 #include "cache.h"
 #include "transport.h"
 #include "remote.h"
+#include "refs.h"
 
 static const char * const ls_remote_usage[] = {
        N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -31,6 +32,16 @@ static int tail_match(const char **pattern, const char *path)
        return 0;
 }
 
+static int has_ref_locally(const struct ref *ref)
+{
+       unsigned char sha1[20];
+
+       if (!resolve_ref_unsafe(ref->name, RESOLVE_REF_READING, sha1, NULL))
+               return 0;
+
+       return !hashcmp(ref->old_oid.hash, sha1);
+}
+
 int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 {
        const char *dest = NULL;
@@ -39,6 +50,7 @@ int cmd_ls_remote(int argc, const char **argv, const char 
*prefix)
        int quiet = 0;
        int status = 0;
        int show_symref_target = 0;
+       int diff = 0;
        const char *uploadpack = NULL;
        const char **pattern = NULL;
 
@@ -62,6 +74,8 @@ int cmd_ls_remote(int argc, const char **argv, const char 
*prefix)
                            N_("exit with exit code 2 if no matching refs are 
found"), 2),
                OPT_BOOL(0, "symref", &show_symref_target,
                         N_("show underlying ref in addition to the object 
pointed by it")),
+               OPT_BOOL(0, "diff", &diff,
+                        N_("show only refs that differ from local refs")),
                OPT_END()
        };
 
@@ -98,6 +112,8 @@ int cmd_ls_remote(int argc, const char **argv, const char 
*prefix)
        if (transport_disconnect(transport))
                return 1;
 
+       if (diff)
+               flags |= REF_NORMAL;
        if (!dest && !quiet)
                fprintf(stderr, "From %s\n", *remote->url);
        for ( ; ref; ref = ref->next) {
@@ -105,6 +121,8 @@ int cmd_ls_remote(int argc, const char **argv, const char 
*prefix)
                        continue;
                if (!tail_match(pattern, ref->name))
                        continue;
+               if (diff && has_ref_locally(ref))
+                       continue;
                if (show_symref_target && ref->symref)
                        printf("ref: %s\t%s\n", ref->symref, ref->name);
                printf("%s\t%s\n", oid_to_hex(&ref->old_oid), ref->name);

Reply via email to