From 44f9f850e8ee6e2824ceb1855d836d484340edf7 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Wed, 11 Dec 2013 08:46:10 +0100 Subject: [PATCH] builtin/replace: teach listing using short, medium or full formats 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= option where 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 Signed-off-by: Junio C Hamano --- builtin/replace.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/builtin/replace.c b/builtin/replace.c index b1bd3ef994..9f3619a1bf 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -16,27 +16,65 @@ static const char * const git_replace_usage[] = { N_("git replace [-f] "), N_("git replace -d ..."), - N_("git replace -l []"), + N_("git replace [--format=] [-l []]"), 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); } -- 2.11.4.GIT