Merge branch 'dt/untracked-subdir'
[gitweb.git] / builtin / reflog.c
index 8182b648b9c9693ec6f23f6b2100e432bfa794ba..7ed0e8501c149312676c0bce6fa52372a11b6fff 100644 (file)
@@ -13,6 +13,8 @@ static const char reflog_expire_usage[] =
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] <refs>...";
 static const char reflog_delete_usage[] =
 "git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] <refs>...";
+static const char reflog_exists_usage[] =
+"git reflog exists <ref>";
 
 static unsigned long default_reflog_expire;
 static unsigned long default_reflog_expire_unreachable;
@@ -313,14 +315,14 @@ static int should_expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
        return 0;
 }
 
-static int push_tip_to_list(const char *refname, const unsigned char *sha1,
+static int push_tip_to_list(const char *refname, const struct object_id *oid,
                            int flags, void *cb_data)
 {
        struct commit_list **list = cb_data;
        struct commit *tip_commit;
        if (flags & REF_ISSYMREF)
                return 0;
-       tip_commit = lookup_commit_reference_gently(sha1, 1);
+       tip_commit = lookup_commit_reference_gently(oid->hash, 1);
        if (!tip_commit)
                return 0;
        commit_list_insert(tip_commit, list);
@@ -352,6 +354,7 @@ static void reflog_expiry_prepare(const char *refname,
        if (cb->unreachable_expire_kind != UE_ALWAYS) {
                if (cb->unreachable_expire_kind == UE_HEAD) {
                        struct commit_list *elem;
+
                        for_each_ref(push_tip_to_list, &cb->tips);
                        for (elem = cb->tips; elem; elem = elem->next)
                                commit_list_insert(elem->item, &cb->mark_list);
@@ -379,14 +382,14 @@ static void reflog_expiry_cleanup(void *cb_data)
        }
 }
 
-static int collect_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)
+static int collect_reflog(const char *ref, const struct object_id *oid, int unused, void *cb_data)
 {
        struct collected_reflog *e;
        struct collect_reflog_cb *cb = cb_data;
        size_t namelen = strlen(ref);
 
        e = xmalloc(sizeof(*e) + namelen + 1);
-       hashcpy(e->sha1, sha1);
+       hashcpy(e->sha1, oid->hash);
        memcpy(e->reflog, ref, namelen + 1);
        ALLOC_GROW(cb->e, cb->nr + 1, cb->alloc);
        cb->e[cb->nr++] = e;
@@ -698,12 +701,38 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
        return status;
 }
 
+static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)
+{
+       int i, start = 0;
+
+       for (i = 1; i < argc; i++) {
+               const char *arg = argv[i];
+               if (!strcmp(arg, "--")) {
+                       i++;
+                       break;
+               }
+               else if (arg[0] == '-')
+                       usage(reflog_exists_usage);
+               else
+                       break;
+       }
+
+       start = i;
+
+       if (argc - start != 1)
+               usage(reflog_exists_usage);
+
+       if (check_refname_format(argv[start], REFNAME_ALLOW_ONELEVEL))
+               die("invalid ref format: %s", argv[start]);
+       return !reflog_exists(argv[start]);
+}
+
 /*
  * main "reflog"
  */
 
 static const char reflog_usage[] =
-"git reflog [ show | expire | delete ]";
+"git reflog [ show | expire | delete | exists ]";
 
 int cmd_reflog(int argc, const char **argv, const char *prefix)
 {
@@ -723,5 +752,8 @@ int cmd_reflog(int argc, const char **argv, const char *prefix)
        if (!strcmp(argv[1], "delete"))
                return cmd_reflog_delete(argc - 1, argv + 1, prefix);
 
+       if (!strcmp(argv[1], "exists"))
+               return cmd_reflog_exists(argc - 1, argv + 1, prefix);
+
        return cmd_log_reflog(argc, argv, prefix);
 }