branch: do not fail a no-op --edit-desc

Imagine running "git branch --edit-description" while on a branch without the branch description, and then exit the editor after emptying the edit buffer, which is the way to tell the command that you changed your mind and you do not want the description after all. The command should just happily oblige, adding no branch description for the current branch, and exit successfully. But it fails to do so: $ git init -b main $ git commit --allow-empty -m commit $ GIT_EDITOR=: git branch --edit-description fatal: could not unset 'branch.main.description' The end result is OK in that the configuration variable does not exist in the resulting repository, but we should do better. If we know we didn't have a description, and if we are asked not to have a description by the editor, we can just return doing nothing. This of course introduces TOCTOU. If you add a branch description to the same branch from another window, while you had the editor open to edit the description, and then exit the editor without writing anything there, we'd end up not removing the description you added in the other window. But you are fooling yourself in your own repository at that point, and if it hurts, you'd be better off not doing so ;-). Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Sep 30, 2022 at 11:06 UTC e288b3de35eaaf3febe07cd56565d8e8af17fb1e
2 files changed +7 -2
builtin/branch.c
+4 -2
@@ -576,10 +576,11 @@ static GIT_PATH_FUNC(edit_description, "EDIT_DESCRIPTION")
576
577 static int edit_branch_description(const char *branch_name)
578 {
579 + int exists;
580 struct strbuf buf = STRBUF_INIT;
581 struct strbuf name = STRBUF_INIT;
582
582 - read_branch_desc(&buf, branch_name);
583 + exists = !read_branch_desc(&buf, branch_name);
584 if (!buf.len || buf.buf[buf.len-1] != '\n')
585 strbuf_addch(&buf, '\n');
586 strbuf_commented_addf(&buf,
@@ -596,7 +597,8 @@ static int edit_branch_description(const char *branch_name)
597 strbuf_stripspace(&buf, 1);
598
599 strbuf_addf(&name, "branch.%s.description", branch_name);
599 - git_config_set(name.buf, buf.len ? buf.buf : NULL);
600 + if (buf.len || exists)
601 + git_config_set(name.buf, buf.len ? buf.buf : NULL);
602 strbuf_release(&name);
603 strbuf_release(&buf);
604
t/t3200-branch.sh
+3
@@ -1268,6 +1268,9 @@ test_expect_success 'attempt to delete a branch merged to its base' '
1268 '
1269
1270 test_expect_success 'use --edit-description' '
1271 + EDITOR=: git branch --edit-description &&
1272 + test_must_fail git config branch.main.description &&
1273 +
1274 write_script editor <<-\EOF &&
1275 echo "New contents" >"$1"
1276 EOF