{"thread":{"id":"17496","subject":"[PATCH 2/4] builtin-replace: teach \"git replace\" to actually replace","startedAt":"2009-02-02T05:12:53Z","lastAt":"2009-02-02T05:12:53Z","messageCount":1,"participants":["Christian Couder"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"102819","messageId":"20090202061253.14305fad.chriscool@tuxfamily.org","threadId":"17496","inReplyTo":null,"subject":"[PATCH 2/4] builtin-replace: teach \"git replace\" to actually replace","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-02-02T05:12:53Z","receivedAt":"2009-02-02T05:12:53Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Teach the syntax: \"git replace <object> <replacement>\", so that\n\"git replace\" can now create replace refs. These replace refs\nwill be used by read_sha1_file to substitute <object> with\n<replacement> for most of the commands.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin-replace.c  |   50 +++++++++++++++++++++++++++++++++++++++++++++++++-\n t/t6050-replace.sh |   10 ++++++++++\n 2 files changed, 59 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-replace.c b/builtin-replace.c\nindex b5c40aa..e3767b9 100644\n--- a/builtin-replace.c\n+++ b/builtin-replace.c\n@@ -14,6 +14,7 @@\n #include \"parse-options.h\"\n \n static const char * const git_replace_usage[] = {\n+\t\"git replace [-f] <object> <replacement>\",\n \t\"git replace -d <object>...\",\n \t\"git replace -l [<pattern>]\",\n \tNULL\n@@ -77,12 +78,46 @@ static int delete_replace_ref(const char *name, const char *ref,\n \treturn 0;\n }\n \n+static int replace_object(const char *object_ref, const char *replace_ref,\n+\t\t\t  int force)\n+{\n+\tunsigned char object[20], prev[20], repl[20];\n+\tchar ref[PATH_MAX];\n+\tstruct ref_lock *lock;\n+\n+\tif (get_sha1(object_ref, object))\n+\t\tdie(\"Failed to resolve '%s' as a valid ref.\", object_ref);\n+\tif (get_sha1(replace_ref, repl))\n+\t\tdie(\"Failed to resolve '%s' as a valid ref.\", replace_ref);\n+\n+\tif (snprintf(ref, sizeof(ref),\n+\t\t     \"refs/replace/%s\",\n+\t\t     sha1_to_hex(object)) > sizeof(ref) - 1)\n+\t\tdie(\"replace ref name too long: %.*s...\", 50, ref);\n+\tif (check_ref_format(ref))\n+\t\tdie(\"'%s' is not a valid ref name.\", ref);\n+\n+\tif (!resolve_ref(ref, prev, 1, NULL))\n+\t\thashclr(prev);\n+\telse if (!force)\n+\t\tdie(\"replace ref '%s' already exists\", ref);\n+\n+\tlock = lock_any_ref_for_update(ref, prev, 0);\n+\tif (!lock)\n+\t\tdie(\"%s: cannot lock the ref\", ref);\n+\tif (write_ref_sha1(lock, repl, NULL) < 0)\n+\t\tdie(\"%s: cannot update the ref\", ref);\n+\n+\treturn 0;\n+}\n+\n int cmd_replace(int argc, const char **argv, const char *prefix)\n {\n-\tint list = 0, delete = 0;\n+\tint list = 0, delete = 0, force = 0;\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN('l', NULL, &list, \"list replace refs\"),\n \t\tOPT_BOOLEAN('d', NULL, &delete, \"delete replace refs\"),\n+\t\tOPT_BOOLEAN('f', NULL, &force, \"replace the ref if it exists\"),\n \t\tOPT_END()\n \t};\n \n@@ -91,15 +126,28 @@ int cmd_replace(int argc, const char **argv, const char *prefix)\n \tif (list && delete)\n \t\tusage_with_options(git_replace_usage, options);\n \n+\tif (force && (list || delete))\n+\t\tusage_with_options(git_replace_usage, options);\n+\n+\t/* Delete refs */\n \tif (delete) {\n \t\tif (argc < 1)\n \t\t\tusage_with_options(git_replace_usage, options);\n \t\treturn for_each_replace_name(argv, delete_replace_ref);\n \t}\n \n+\t/* Replace object */\n+\tif (!list && argc) {\n+\t\tif (argc != 2)\n+\t\t\tusage_with_options(git_replace_usage, options);\n+\t\treturn replace_object(argv[0], argv[1], force);\n+\t}\n+\n \t/* List refs, even if \"list\" is not set */\n \tif (argc > 1)\n \t\tusage_with_options(git_replace_usage, options);\n+\tif (force)\n+\t\tusage_with_options(git_replace_usage, options);\n \n \treturn list_replace_refs(argv[0]);\n }\ndiff --git a/t/t6050-replace.sh b/t/t6050-replace.sh\nindex bf4c93f..448a19a 100755\n--- a/t/t6050-replace.sh\n+++ b/t/t6050-replace.sh\n@@ -114,9 +114,19 @@ test_expect_success '\"git replace\" listing and deleting' '\n      test_must_fail git replace -d &&\n      test_must_fail git replace -l -d $HASH2 &&\n      git replace -d $HASH2 &&\n+     git show $HASH2 | grep \"A U Thor\" &&\n      test -z \"$(git replace -l)\"\n '\n \n+test_expect_success '\"git replace\" replacing' '\n+     git replace $HASH2 $R &&\n+     git show $HASH2 | grep \"O Thor\" &&\n+     test_must_fail git replace $HASH2 $R &&\n+     git replace -f $HASH2 $R &&\n+     test_must_fail git replace -f &&\n+     test \"$HASH2\" = \"$(git replace)\"\n+'\n+\n #\n #\n test_done\n-- \n1.6.1.2.353.g99fdd.dirty\n"}]}