]> Pileus Git - ~andy/git/commitdiff
builtin/replace: teach listing using short, medium or full formats
authorChristian Couder <chriscool@tuxfamily.org>
Wed, 11 Dec 2013 07:46:10 +0000 (08:46 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 12 Dec 2013 19:53:49 +0000 (11:53 -0800)
By default when listing replace refs, only the sha1 of the
replaced objects are shown.

In many cases, it is much nicer to be able to list all the
sha1 of the replaced objects along with the sha1 of the
replacment objects.

And in other cases it might be interesting to also show the
types of the replaced and replacement objects.

This patch introduce a new --format=<fmt> option where
<fmt> can be any of the following:

'short': this is the same as when no --format
option is used, that is only the sha1 of
the replaced objects are shown
'medium': this also lists the sha1 of the
replacement objects
'full': this shows the sha1 and the type of both
the replaced and the replacement objects

Some documentation and some tests will follow.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/replace.c

index b1bd3ef9946761b146a38d5977a7378175cda047..9f3619a1bfdcd05494d531acad516720868f9e4f 100644 (file)
 static const char * const git_replace_usage[] = {
        N_("git replace [-f] <object> <replacement>"),
        N_("git replace -d <object>..."),
-       N_("git replace -l [<pattern>]"),
+       N_("git replace [--format=<format>] [-l [<pattern>]]"),
        NULL
 };
 
+enum repl_fmt { SHORT, MEDIUM, FULL };
+
+struct show_data {
+       const char *pattern;
+       enum repl_fmt fmt;
+};
+
 static int show_reference(const char *refname, const unsigned char *sha1,
                          int flag, void *cb_data)
 {
-       const char *pattern = cb_data;
+       struct show_data *data = cb_data;
+
+       if (!fnmatch(data->pattern, refname, 0)) {
+               if (data->fmt == SHORT)
+                       printf("%s\n", refname);
+               else if (data->fmt == MEDIUM)
+                       printf("%s -> %s\n", refname, sha1_to_hex(sha1));
+               else { /* data->fmt == FULL */
+                       unsigned char object[20];
+                       enum object_type obj_type, repl_type;
 
-       if (!fnmatch(pattern, refname, 0))
-               printf("%s\n", refname);
+                       if (get_sha1(refname, object))
+                               return error("Failed to resolve '%s' as a valid ref.", refname);
+
+                       obj_type = sha1_object_info(object, NULL);
+                       repl_type = sha1_object_info(sha1, NULL);
+
+                       printf("%s (%s) -> %s (%s)\n", refname, typename(obj_type),
+                              sha1_to_hex(sha1), typename(repl_type));
+               }
+       }
 
        return 0;
 }
 
-static int list_replace_refs(const char *pattern)
+static int list_replace_refs(const char *pattern, const char *format)
 {
+       struct show_data data;
+
        if (pattern == NULL)
                pattern = "*";
+       data.pattern = pattern;
+
+       if (format == NULL || *format == '\0' || !strcmp(format, "short"))
+               data.fmt = SHORT;
+       else if (!strcmp(format, "medium"))
+               data.fmt = MEDIUM;
+       else if (!strcmp(format, "full"))
+               data.fmt = FULL;
+       else
+               die("invalid replace format '%s'\n"
+                   "valid formats are 'short', 'medium' and 'full'\n",
+                   format);
 
-       for_each_replace_ref(show_reference, (void *) pattern);
+       for_each_replace_ref(show_reference, (void *) &data);
 
        return 0;
 }
@@ -127,10 +165,12 @@ static int replace_object(const char *object_ref, const char *replace_ref,
 int cmd_replace(int argc, const char **argv, const char *prefix)
 {
        int list = 0, delete = 0, force = 0;
+       const char *format = NULL;
        struct option options[] = {
                OPT_BOOL('l', "list", &list, N_("list replace refs")),
                OPT_BOOL('d', "delete", &delete, N_("delete replace refs")),
                OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")),
+               OPT_STRING(0, "format", &format, N_("format"), N_("use this format")),
                OPT_END()
        };
 
@@ -140,6 +180,10 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                usage_msg_opt("-l and -d cannot be used together",
                              git_replace_usage, options);
 
+       if (format && delete)
+               usage_msg_opt("--format and -d cannot be used together",
+                             git_replace_usage, options);
+
        if (force && (list || delete))
                usage_msg_opt("-f cannot be used with -d or -l",
                              git_replace_usage, options);
@@ -157,6 +201,9 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                if (argc != 2)
                        usage_msg_opt("bad number of arguments",
                                      git_replace_usage, options);
+               if (format)
+                       usage_msg_opt("--format cannot be used when not listing",
+                                     git_replace_usage, options);
                return replace_object(argv[0], argv[1], force);
        }
 
@@ -168,5 +215,5 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                usage_msg_opt("-f needs some arguments",
                              git_replace_usage, options);
 
-       return list_replace_refs(argv[0]);
+       return list_replace_refs(argv[0], format);
 }