diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-06-13 22:29:44 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-06-13 22:29:44 +0300 |
commit | 6d2a88c7289b56999426354f44b536255b57c5c8 (patch) | |
tree | 0dadd5518aea1ce4df5dbc9bcb3827e38645bfb8 | |
parent | fe86abd7511a9a6862d5706c6fa1d9b57a63ba09 (diff) | |
parent | 08c12ec1d0444c9ea7cf24b7157aa158f3f641f4 (diff) |
Merge branch 'kh/keep-tag-editmsg-upon-failure'
"git tag" learned to leave the "$GIT_DIR/TAG_EDITMSG" file when the
command failed, so that the user can salvage what they typed.
* kh/keep-tag-editmsg-upon-failure:
tag: keep the message file in case ref transaction fails
t/t7004-tag: add regression test for successful tag creation
doc: tag: document `TAG_EDITMSG`
-rw-r--r-- | Documentation/git-tag.txt | 10 | ||||
-rw-r--r-- | builtin/tag.c | 24 | ||||
-rwxr-xr-x | t/t7004-tag.sh | 19 |
3 files changed, 44 insertions, 9 deletions
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 7f61c1edb3..d42efb3112 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -381,6 +381,16 @@ $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1 include::date-formats.txt[] +FILES +----- + +`$GIT_DIR/TAG_EDITMSG`:: + This file contains the message of an in-progress annotated + tag. If `git tag` exits due to an error before creating an + annotated tag then the tag message that has been provided by the + user in an editor session will be available in this file, but + may be overwritten by the next invocation of `git tag`. + NOTES ----- diff --git a/builtin/tag.c b/builtin/tag.c index 1850a6a6fd..49b64c7a28 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -271,11 +271,10 @@ static const char message_advice_nested_tag[] = static void create_tag(const struct object_id *object, const char *object_ref, const char *tag, struct strbuf *buf, struct create_tag_options *opt, - struct object_id *prev, struct object_id *result) + struct object_id *prev, struct object_id *result, char *path) { enum object_type type; struct strbuf header = STRBUF_INIT; - char *path = NULL; type = oid_object_info(the_repository, object, NULL); if (type <= OBJ_NONE) @@ -299,7 +298,6 @@ static void create_tag(const struct object_id *object, const char *object_ref, int fd; /* write the template message before editing: */ - path = git_pathdup("TAG_EDITMSG"); fd = xopen(path, O_CREAT | O_TRUNC | O_WRONLY, 0600); if (opt->message_given) { @@ -341,10 +339,6 @@ static void create_tag(const struct object_id *object, const char *object_ref, path); exit(128); } - if (path) { - unlink_or_warn(path); - free(path); - } } static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb) @@ -495,6 +489,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) }; int ret = 0; const char *only_in_list = NULL; + char *path = NULL; setup_ref_filter_porcelain_msg(); @@ -629,7 +624,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix) if (create_tag_object) { if (force_sign_annotate && !annotate) opt.sign = 1; - create_tag(&object, object_ref, tag, &buf, &opt, &prev, &object); + path = git_pathdup("TAG_EDITMSG"); + create_tag(&object, object_ref, tag, &buf, &opt, &prev, &object, + path); } transaction = ref_transaction_begin(&err); @@ -637,8 +634,17 @@ int cmd_tag(int argc, const char **argv, const char *prefix) ref_transaction_update(transaction, ref.buf, &object, &prev, create_reflog ? REF_FORCE_CREATE_REFLOG : 0, reflog_msg.buf, &err) || - ref_transaction_commit(transaction, &err)) + ref_transaction_commit(transaction, &err)) { + if (path) + fprintf(stderr, + _("The tag message has been left in %s\n"), + path); die("%s", err.buf); + } + if (path) { + unlink_or_warn(path); + free(path); + } ref_transaction_free(transaction); if (force && !is_null_oid(&prev) && !oideq(&prev, &object)) printf(_("Updated tag '%s' (was %s)\n"), tag, diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 0fe6ba93a2..e689db4292 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -2188,4 +2188,23 @@ test_expect_success 'Does --[no-]contains stop at commits? Yes!' ' test_cmp expected actual ' +test_expect_success 'If tag is created then tag message file is unlinked' ' + test_when_finished "git tag -d foo" && + write_script fakeeditor <<-\EOF && + echo Message >.git/TAG_EDITMSG + EOF + GIT_EDITOR=./fakeeditor git tag -a foo && + test_path_is_missing .git/TAG_EDITMSG +' + +test_expect_success 'If tag cannot be created then tag message file is not unlinked' ' + test_when_finished "git tag -d foo/bar && rm .git/TAG_EDITMSG" && + write_script fakeeditor <<-\EOF && + echo Message >.git/TAG_EDITMSG + EOF + git tag foo/bar && + test_must_fail env GIT_EDITOR=./fakeeditor git tag -a foo && + test_path_exists .git/TAG_EDITMSG +' + test_done |