From: Victoria Dye <vdye@xxxxxxxxxx> Add 'refresh_cache_entry()' after moving the index entry in 'rename_index_entry_at()'. Internally, 'git mv' uses 'rename_index_entry_at()' to move the source index entry to the destination, overwriting the old entry if '-f' is specified. However, it does not refresh the stat information on destination index entry, making its 'CE_UPTODATE' flag out-of-date until the index is refreshed (e.g., by 'git status'). Some commands, such as 'git reset', assume the 'CE_UPTODATE' information they read from the index is accurate, and use that information to determine whether the operation can be done successfully or not. In order to ensure the index is correct for commands such as these, explicitly refresh the destination index entry in 'git mv' before exiting. Reported-by: Maximilian Reichel <reichemn@xxxxxxxxxx> Signed-off-by: Victoria Dye <vdye@xxxxxxxxxx> --- mv: refresh stat info for moved entry This patch fixes a bug [1] encountered when executing 'git reset --merge HEAD' immediately after 'git mv -f' overwrites an existing index entry. Because the 'CE_UPTODATE' flag is not refreshed on the destination entry (and therefore incorrectly appeared to not be "up-to-date"), 'git reset --merge HEAD' fails when it should otherwise succeed. To avoid exiting 'git mv' with a stale index that may affect subsequent commands, 'rename_index_entry_at()' (used internally by 'git mv') is updated to refresh the destination index entry's stat information after the move is complete. [1] https://lore.kernel.org/git/84FF8F9A-3A9A-4F2A-8D8E-5D50F2F06203@xxxxxxxxxx/ Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1187%2Fvdye%2Freset%2Fmerge-inconsistency-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1187/vdye/reset/merge-inconsistency-v1 Pull-Request: https://github.com/gitgitgadget/git/pull/1187 read-cache.c | 1 + t/t7001-mv.sh | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/read-cache.c b/read-cache.c index 1ad56d02e1d..2c5ccc48d6c 100644 --- a/read-cache.c +++ b/read-cache.c @@ -148,6 +148,7 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n untracked_cache_remove_from_index(istate, old_entry->name); remove_index_entry_at(istate, nr); add_index_entry(istate, new_entry, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + refresh_cache_entry(istate, new_entry, CE_MATCH_REFRESH); } void fill_stat_data(struct stat_data *sd, struct stat *st) diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 963356ba5f9..ab8607678e7 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -4,6 +4,17 @@ test_description='git mv in subdirs' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-data.sh +test_expect_success 'mv -f refreshes updated index entry' ' + echo test >bar && + git add bar && + git commit -m test && + + echo foo >foo && + git add foo && + git mv -f foo bar && + git reset --merge HEAD +' + test_expect_success 'prepare reference tree' ' mkdir path0 path1 && COPYING_test_data >path0/COPYING && base-commit: a68dfadae5e95c7f255cf38c9efdcbc2e36d1931 -- gitgitgadget