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>
This commit is contained in:
Christian Couder 2013-12-11 08:46:10 +01:00 committed by Junio C Hamano
parent 1f7117ef7a
commit 44f9f850e8

View file

@ -16,27 +16,65 @@
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(pattern, refname, 0))
printf("%s\n", refname);
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 (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;
for_each_replace_ref(show_reference, (void *) 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 *) &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);
}