builtin/stash: report failure to write to index

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> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Feb 6, 2024 at 06:34 UTC d2058cb2f00ae4c174b44193b039790dc8015c40
2 files changed +56 -4
builtin/stash.c
+4 -4
@@ -521,7 +521,7 @@ static void unstage_changes_unless_new(struct object_id *orig_tree)
521 repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
522 if (write_locked_index(&the_index, &lock,
523 COMMIT_LOCK | SKIP_IF_UNCHANGED))
524 - die(_("Unable to write index."));
524 + die(_("could not write index"));
525 }
526
527 static int do_apply_stash(const char *prefix, struct stash_info *info,
@@ -538,7 +538,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
538 repo_read_index_preload(the_repository, NULL, 0);
539 if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
540 NULL, NULL, NULL))
541 - return -1;
541 + return error(_("could not write index"));
542
543 if (write_index_as_tree(&c_tree, &the_index, get_index_file(), 0,
544 NULL))
@@ -1365,7 +1365,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
1365 repo_read_index_preload(the_repository, NULL, 0);
1366 if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
1367 NULL, NULL, NULL) < 0) {
1368 - ret = -1;
1368 + ret = error(_("could not write index"));
1369 goto done;
1370 }
1371
@@ -1556,7 +1556,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
1556
1557 if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
1558 NULL, NULL, NULL)) {
1559 - ret = -1;
1559 + ret = error(_("could not write index"));
1560 goto done;
1561 }
1562
t/t3903-stash.sh
+52
@@ -1516,4 +1516,56 @@ test_expect_success 'restore untracked files even when we hit conflicts' '
1516 )
1517 '
1518
1519 +test_expect_success 'stash create reports a locked index' '
1520 + test_when_finished "rm -rf repo" &&
1521 + git init repo &&
1522 + (
1523 + cd repo &&
1524 + test_commit A A.file &&
1525 + echo change >A.file &&
1526 + touch .git/index.lock &&
1527 +
1528 + cat >expect <<-EOF &&
1529 + error: could not write index
1530 + EOF
1531 + test_must_fail git stash create 2>err &&
1532 + test_cmp expect err
1533 + )
1534 +'
1535 +
1536 +test_expect_success 'stash push reports a locked index' '
1537 + test_when_finished "rm -rf repo" &&
1538 + git init repo &&
1539 + (
1540 + cd repo &&
1541 + test_commit A A.file &&
1542 + echo change >A.file &&
1543 + touch .git/index.lock &&
1544 +
1545 + cat >expect <<-EOF &&
1546 + error: could not write index
1547 + EOF
1548 + test_must_fail git stash push 2>err &&
1549 + test_cmp expect err
1550 + )
1551 +'
1552 +
1553 +test_expect_success 'stash apply reports a locked index' '
1554 + test_when_finished "rm -rf repo" &&
1555 + git init repo &&
1556 + (
1557 + cd repo &&
1558 + test_commit A A.file &&
1559 + echo change >A.file &&
1560 + git stash push &&
1561 + touch .git/index.lock &&
1562 +
1563 + cat >expect <<-EOF &&
1564 + error: could not write index
1565 + EOF
1566 + test_must_fail git stash apply 2>err &&
1567 + test_cmp expect err
1568 + )
1569 +'
1570 +
1571 test_done