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=<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>

Christian Couder committed Dec 11, 2013 at 08:46 UTC 44f9f850e8ee6e2824ceb1855d836d484340edf7
1 file changed +54 -7
builtin/replace.c
+54 -7
@@ -16,27 +16,65 @@
16 static const char * const git_replace_usage[] = {
17 N_("git replace [-f] <object> <replacement>"),
18 N_("git replace -d <object>..."),
19 - N_("git replace -l [<pattern>]"),
19 + N_("git replace [--format=<format>] [-l [<pattern>]]"),
20 NULL
21 };
22
23 +enum repl_fmt { SHORT, MEDIUM, FULL };
24 +
25 +struct show_data {
26 + const char *pattern;
27 + enum repl_fmt fmt;
28 +};
29 +
30 static int show_reference(const char *refname, const unsigned char *sha1,
31 int flag, void *cb_data)
32 {
26 - const char *pattern = cb_data;
33 + struct show_data *data = cb_data;
34 +
35 + if (!fnmatch(data->pattern, refname, 0)) {
36 + if (data->fmt == SHORT)
37 + printf("%s\n", refname);
38 + else if (data->fmt == MEDIUM)
39 + printf("%s -> %s\n", refname, sha1_to_hex(sha1));
40 + else { /* data->fmt == FULL */
41 + unsigned char object[20];
42 + enum object_type obj_type, repl_type;
43
28 - if (!fnmatch(pattern, refname, 0))
29 - printf("%s\n", refname);
44 + if (get_sha1(refname, object))
45 + return error("Failed to resolve '%s' as a valid ref.", refname);
46 +
47 + obj_type = sha1_object_info(object, NULL);
48 + repl_type = sha1_object_info(sha1, NULL);
49 +
50 + printf("%s (%s) -> %s (%s)\n", refname, typename(obj_type),
51 + sha1_to_hex(sha1), typename(repl_type));
52 + }
53 + }
54
55 return 0;
56 }
57
34 -static int list_replace_refs(const char *pattern)
58 +static int list_replace_refs(const char *pattern, const char *format)
59 {
60 + struct show_data data;
61 +
62 if (pattern == NULL)
63 pattern = "*";
64 + data.pattern = pattern;
65 +
66 + if (format == NULL || *format == '\0' || !strcmp(format, "short"))
67 + data.fmt = SHORT;
68 + else if (!strcmp(format, "medium"))
69 + data.fmt = MEDIUM;
70 + else if (!strcmp(format, "full"))
71 + data.fmt = FULL;
72 + else
73 + die("invalid replace format '%s'\n"
74 + "valid formats are 'short', 'medium' and 'full'\n",
75 + format);
76
39 - for_each_replace_ref(show_reference, (void *) pattern);
77 + for_each_replace_ref(show_reference, (void *) &data);
78
79 return 0;
80 }
@@ -127,10 +165,12 @@ static int replace_object(const char *object_ref, const char *replace_ref,
165 int cmd_replace(int argc, const char **argv, const char *prefix)
166 {
167 int list = 0, delete = 0, force = 0;
168 + const char *format = NULL;
169 struct option options[] = {
170 OPT_BOOL('l', "list", &list, N_("list replace refs")),
171 OPT_BOOL('d', "delete", &delete, N_("delete replace refs")),
172 OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")),
173 + OPT_STRING(0, "format", &format, N_("format"), N_("use this format")),
174 OPT_END()
175 };
176
@@ -140,6 +180,10 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
180 usage_msg_opt("-l and -d cannot be used together",
181 git_replace_usage, options);
182
183 + if (format && delete)
184 + usage_msg_opt("--format and -d cannot be used together",
185 + git_replace_usage, options);
186 +
187 if (force && (list || delete))
188 usage_msg_opt("-f cannot be used with -d or -l",
189 git_replace_usage, options);
@@ -157,6 +201,9 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
201 if (argc != 2)
202 usage_msg_opt("bad number of arguments",
203 git_replace_usage, options);
204 + if (format)
205 + usage_msg_opt("--format cannot be used when not listing",
206 + git_replace_usage, options);
207 return replace_object(argv[0], argv[1], force);
208 }
209
@@ -168,5 +215,5 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
215 usage_msg_opt("-f needs some arguments",
216 git_replace_usage, options);
217
171 - return list_replace_refs(argv[0]);
218 + return list_replace_refs(argv[0], format);
219 }