diff mbox series

[v2] builtin/stash: report failure to write to index

Message ID cb098cf88cbfcbf7c4872f8887856629b909cb91.1707197653.git.ps@pks.im (mailing list archive)
State Accepted
Commit d2058cb2f00ae4c174b44193b039790dc8015c40
Headers show
Series [v2] builtin/stash: report failure to write to index | expand

Commit Message

Patrick Steinhardt Feb. 6, 2024, 5:34 a.m. UTC
The git-stash(1) command needs to write to the index for many of its
operations. When the index is locked by a concurrent writer it will thus
fail to operate, which is expected. What is not expected though is that
we do not print any error message at all in this case. The user can thus
easily miss the fact that the command didn't do what they expected it to
do and would be left wondering why that is.

Fix this bug and report failures to write to the index. Add tests for
the subcommands which hit the respective code paths.

While at it, unify error messages when writing to the index fails. The
chosen error message is already used in "builtin/stash.c".

Reported-by: moti sd <motisd8@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
Range-diff against v1:
1:  f114688eac < -:  ---------- drop dot
2:  b13a5a10ac ! 1:  cb098cf88c builtin/stash: report failure to write to index
    @@ Commit message
         Fix this bug and report failures to write to the index. Add tests for
         the subcommands which hit the respective code paths.
     
    -    Note that the chosen error message ("Cannot write to the index") does
    -    not match our guidelines as it starts with a capitalized letter. This is
    -    intentional though and matches the style of all the other messages used
    -    in git-stash(1).
    +    While at it, unify error messages when writing to the index fails. The
    +    chosen error message is already used in "builtin/stash.c".
     
         Reported-by: moti sd <motisd8@gmail.com>
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
      ## builtin/stash.c ##
    +@@ builtin/stash.c: static void unstage_changes_unless_new(struct object_id *orig_tree)
    + 	repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
    + 	if (write_locked_index(&the_index, &lock,
    + 			       COMMIT_LOCK | SKIP_IF_UNCHANGED))
    +-		die(_("Unable to write index."));
    ++		die(_("could not write index"));
    + }
    + 
    + static int do_apply_stash(const char *prefix, struct stash_info *info,
     @@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info *info,
      	repo_read_index_preload(the_repository, NULL, 0);
      	if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
      					 NULL, NULL, NULL))
     -		return -1;
    -+		return error(_("Cannot write to the index"));
    ++		return error(_("could not write index"));
      
      	if (write_index_as_tree(&c_tree, &the_index, get_index_file(), 0,
      				NULL))
    @@ builtin/stash.c: static int do_create_stash(const struct pathspec *ps, struct st
      	if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
      					 NULL, NULL, NULL) < 0) {
     -		ret = -1;
    -+		ret = error(_("Cannot write to the index"));
    ++		ret = error(_("could not write index"));
      		goto done;
      	}
      
    @@ builtin/stash.c: static int do_push_stash(const struct pathspec *ps, const char
      	if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
      					 NULL, NULL, NULL)) {
     -		ret = -1;
    -+		ret = error(_("Cannot write to the index"));
    ++		ret = error(_("could not write index"));
      		goto done;
      	}
      
    @@ t/t3903-stash.sh: test_expect_success 'restore untracked files even when we hit
     +		touch .git/index.lock &&
     +
     +		cat >expect <<-EOF &&
    -+		error: Cannot write to the index
    ++		error: could not write index
     +		EOF
     +		test_must_fail git stash create 2>err &&
     +		test_cmp expect err
    @@ t/t3903-stash.sh: test_expect_success 'restore untracked files even when we hit
     +		touch .git/index.lock &&
     +
     +		cat >expect <<-EOF &&
    -+		error: Cannot write to the index
    ++		error: could not write index
     +		EOF
     +		test_must_fail git stash push 2>err &&
     +		test_cmp expect err
    @@ t/t3903-stash.sh: test_expect_success 'restore untracked files even when we hit
     +		touch .git/index.lock &&
     +
     +		cat >expect <<-EOF &&
    -+		error: Cannot write to the index
    ++		error: could not write index
     +		EOF
     +		test_must_fail git stash apply 2>err &&
     +		test_cmp expect err

 builtin/stash.c  |  8 ++++----
 t/t3903-stash.sh | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/builtin/stash.c b/builtin/stash.c
index 26489b76c0..d65cd20ee6 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -520,7 +520,7 @@  static void unstage_changes_unless_new(struct object_id *orig_tree)
 	repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
 	if (write_locked_index(&the_index, &lock,
 			       COMMIT_LOCK | SKIP_IF_UNCHANGED))
-		die(_("Unable to write index."));
+		die(_("could not write index"));
 }
 
 static int do_apply_stash(const char *prefix, struct stash_info *info,
@@ -537,7 +537,7 @@  static int do_apply_stash(const char *prefix, struct stash_info *info,
 	repo_read_index_preload(the_repository, NULL, 0);
 	if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
 					 NULL, NULL, NULL))
-		return -1;
+		return error(_("could not write index"));
 
 	if (write_index_as_tree(&c_tree, &the_index, get_index_file(), 0,
 				NULL))
@@ -1364,7 +1364,7 @@  static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
 	repo_read_index_preload(the_repository, NULL, 0);
 	if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
 					 NULL, NULL, NULL) < 0) {
-		ret = -1;
+		ret = error(_("could not write index"));
 		goto done;
 	}
 
@@ -1555,7 +1555,7 @@  static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
 
 	if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
 					 NULL, NULL, NULL)) {
-		ret = -1;
+		ret = error(_("could not write index"));
 		goto done;
 	}
 
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 3319240515..00db82fb24 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -1516,4 +1516,56 @@  test_expect_success 'restore untracked files even when we hit conflicts' '
 	)
 '
 
+test_expect_success 'stash create reports a locked index' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		test_commit A A.file &&
+		echo change >A.file &&
+		touch .git/index.lock &&
+
+		cat >expect <<-EOF &&
+		error: could not write index
+		EOF
+		test_must_fail git stash create 2>err &&
+		test_cmp expect err
+	)
+'
+
+test_expect_success 'stash push reports a locked index' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		test_commit A A.file &&
+		echo change >A.file &&
+		touch .git/index.lock &&
+
+		cat >expect <<-EOF &&
+		error: could not write index
+		EOF
+		test_must_fail git stash push 2>err &&
+		test_cmp expect err
+	)
+'
+
+test_expect_success 'stash apply reports a locked index' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		test_commit A A.file &&
+		echo change >A.file &&
+		git stash push &&
+		touch .git/index.lock &&
+
+		cat >expect <<-EOF &&
+		error: could not write index
+		EOF
+		test_must_fail git stash apply 2>err &&
+		test_cmp expect err
+	)
+'
+
 test_done