@ -20,6 +20,7 @@ static const char * const git_replace_usage[] = {
N_("git replace [-f] <object> <replacement>"),
N_("git replace [-f] <object> <replacement>"),
N_("git replace [-f] --edit <object>"),
N_("git replace [-f] --edit <object>"),
N_("git replace [-f] --graft <commit> [<parent>...]"),
N_("git replace [-f] --graft <commit> [<parent>...]"),
N_("git replace [-f] --convert-graft-file"),
N_("git replace -d <object>..."),
N_("git replace -d <object>..."),
N_("git replace [--format=<format>] [-l [<pattern>]]"),
N_("git replace [--format=<format>] [-l [<pattern>]]"),
NULL
NULL
@ -481,6 +482,38 @@ static int create_graft(int argc, const char **argv, int force, int gentle)
return replace_object_oid(old_ref, &old_oid, "replacement", &new_oid, force);
return replace_object_oid(old_ref, &old_oid, "replacement", &new_oid, force);
}
}
static int convert_graft_file(int force)
{
const char *graft_file = get_graft_file();
FILE *fp = fopen_or_warn(graft_file, "r");
struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT;
struct argv_array args = ARGV_ARRAY_INIT;
if (!fp)
return -1;
while (strbuf_getline(&buf, fp) != EOF) {
if (*buf.buf == '#')
continue;
argv_array_split(&args, buf.buf);
if (args.argc && create_graft(args.argc, args.argv, force, 1))
strbuf_addf(&err, "\n\t%s", buf.buf);
argv_array_clear(&args);
}
fclose(fp);
strbuf_release(&buf);
if (!err.len)
return unlink_or_warn(graft_file);
warning(_("could not convert the following graft(s):\n%s"), err.buf);
strbuf_release(&err);
return -1;
}
int cmd_replace(int argc, const char **argv, const char *prefix)
int cmd_replace(int argc, const char **argv, const char *prefix)
{
{
int force = 0;
int force = 0;
@ -492,6 +525,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
MODE_DELETE,
MODE_DELETE,
MODE_EDIT,
MODE_EDIT,
MODE_GRAFT,
MODE_GRAFT,
MODE_CONVERT_GRAFT_FILE,
MODE_REPLACE
MODE_REPLACE
} cmdmode = MODE_UNSPECIFIED;
} cmdmode = MODE_UNSPECIFIED;
struct option options[] = {
struct option options[] = {
@ -499,6 +533,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
OPT_CMDMODE('g', "graft", &cmdmode, N_("change a commit's parents"), MODE_GRAFT),
OPT_CMDMODE('g', "graft", &cmdmode, N_("change a commit's parents"), MODE_GRAFT),
OPT_CMDMODE(0, "convert-graft-file", &cmdmode, N_("convert existing graft file"), MODE_CONVERT_GRAFT_FILE),
OPT_BOOL_F('f', "force", &force, N_("replace the ref if it exists"),
OPT_BOOL_F('f', "force", &force, N_("replace the ref if it exists"),
PARSE_OPT_NOCOMPLETE),
PARSE_OPT_NOCOMPLETE),
OPT_BOOL(0, "raw", &raw, N_("do not pretty-print contents for --edit")),
OPT_BOOL(0, "raw", &raw, N_("do not pretty-print contents for --edit")),
@ -521,7 +556,8 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
if (force &&
if (force &&
cmdmode != MODE_REPLACE &&
cmdmode != MODE_REPLACE &&
cmdmode != MODE_EDIT &&
cmdmode != MODE_EDIT &&
cmdmode != MODE_GRAFT)
cmdmode != MODE_GRAFT &&
cmdmode != MODE_CONVERT_GRAFT_FILE)
usage_msg_opt("-f only makes sense when writing a replacement",
usage_msg_opt("-f only makes sense when writing a replacement",
git_replace_usage, options);
git_replace_usage, options);
@ -554,6 +590,12 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
git_replace_usage, options);
git_replace_usage, options);
return create_graft(argc, argv, force, 0);
return create_graft(argc, argv, force, 0);
case MODE_CONVERT_GRAFT_FILE:
if (argc != 0)
usage_msg_opt("--convert-graft-file takes no argument",
git_replace_usage, options);
return !!convert_graft_file(force);
case MODE_LIST:
case MODE_LIST:
if (argc > 1)
if (argc > 1)
usage_msg_opt("only one pattern can be given with -l",
usage_msg_opt("only one pattern can be given with -l",