replace: introduce --convert-graft-file

This option is intended to help with the transition away from the now-deprecated graft file. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Apr 29, 2018 at 00:44 UTC fb40429109723c0d8ec77ba81421f508ac2532a0
2 files changed +51 -4
Documentation/git-replace.txt
+8 -3
@@ -11,6 +11,7 @@ SYNOPSIS
11 'git replace' [-f] <object> <replacement>
12 'git replace' [-f] --edit <object>
13 'git replace' [-f] --graft <commit> [<parent>...]
14 +'git replace' [-f] --convert-graft-file
15 'git replace' -d <object>...
16 'git replace' [--format=<format>] [-l [<pattern>]]
17
@@ -87,9 +88,13 @@ OPTIONS
88 content as <commit> except that its parents will be
89 [<parent>...] instead of <commit>'s parents. A replacement ref
90 is then created to replace <commit> with the newly created
90 - commit. See contrib/convert-grafts-to-replace-refs.sh for an
91 - example script based on this option that can convert grafts to
92 - replace refs.
91 + commit. Use `--convert-graft-file` to convert a
92 + `$GIT_DIR/info/grafts` file and use replace refs instead.
93 +
94 +--convert-graft-file::
95 + Creates graft commits for all entries in `$GIT_DIR/info/grafts`
96 + and deletes that file upon success. The purpose is to help users
97 + with transitioning off of the now-deprecated graft file.
98
99 -l <pattern>::
100 --list <pattern>::
builtin/replace.c
+43 -1
@@ -20,6 +20,7 @@ static const char * const git_replace_usage[] = {
20 N_("git replace [-f] <object> <replacement>"),
21 N_("git replace [-f] --edit <object>"),
22 N_("git replace [-f] --graft <commit> [<parent>...]"),
23 + N_("git replace [-f] --convert-graft-file"),
24 N_("git replace -d <object>..."),
25 N_("git replace [--format=<format>] [-l [<pattern>]]"),
26 NULL
@@ -481,6 +482,38 @@ static int create_graft(int argc, const char **argv, int force, int gentle)
482 return replace_object_oid(old_ref, &old_oid, "replacement", &new_oid, force);
483 }
484
485 +static int convert_graft_file(int force)
486 +{
487 + const char *graft_file = get_graft_file();
488 + FILE *fp = fopen_or_warn(graft_file, "r");
489 + struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT;
490 + struct argv_array args = ARGV_ARRAY_INIT;
491 +
492 + if (!fp)
493 + return -1;
494 +
495 + while (strbuf_getline(&buf, fp) != EOF) {
496 + if (*buf.buf == '#')
497 + continue;
498 +
499 + argv_array_split(&args, buf.buf);
500 + if (args.argc && create_graft(args.argc, args.argv, force, 1))
501 + strbuf_addf(&err, "\n\t%s", buf.buf);
502 + argv_array_clear(&args);
503 + }
504 + fclose(fp);
505 +
506 + strbuf_release(&buf);
507 +
508 + if (!err.len)
509 + return unlink_or_warn(graft_file);
510 +
511 + warning(_("could not convert the following graft(s):\n%s"), err.buf);
512 + strbuf_release(&err);
513 +
514 + return -1;
515 +}
516 +
517 int cmd_replace(int argc, const char **argv, const char *prefix)
518 {
519 int force = 0;
@@ -492,6 +525,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
525 MODE_DELETE,
526 MODE_EDIT,
527 MODE_GRAFT,
528 + MODE_CONVERT_GRAFT_FILE,
529 MODE_REPLACE
530 } cmdmode = MODE_UNSPECIFIED;
531 struct option options[] = {
@@ -499,6 +533,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
533 OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
534 OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
535 OPT_CMDMODE('g', "graft", &cmdmode, N_("change a commit's parents"), MODE_GRAFT),
536 + OPT_CMDMODE(0, "convert-graft-file", &cmdmode, N_("convert existing graft file"), MODE_CONVERT_GRAFT_FILE),
537 OPT_BOOL_F('f', "force", &force, N_("replace the ref if it exists"),
538 PARSE_OPT_NOCOMPLETE),
539 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)
556 if (force &&
557 cmdmode != MODE_REPLACE &&
558 cmdmode != MODE_EDIT &&
524 - cmdmode != MODE_GRAFT)
559 + cmdmode != MODE_GRAFT &&
560 + cmdmode != MODE_CONVERT_GRAFT_FILE)
561 usage_msg_opt("-f only makes sense when writing a replacement",
562 git_replace_usage, options);
563
@@ -554,6 +590,12 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
590 git_replace_usage, options);
591 return create_graft(argc, argv, force, 0);
592
593 + case MODE_CONVERT_GRAFT_FILE:
594 + if (argc != 0)
595 + usage_msg_opt("--convert-graft-file takes no argument",
596 + git_replace_usage, options);
597 + return !!convert_graft_file(force);
598 +
599 case MODE_LIST:
600 if (argc > 1)
601 usage_msg_opt("only one pattern can be given with -l",