Skip to content

Commit 9a6728d

Browse files
peffgitster
authored andcommitted
rm: do not complain about d/f conflicts during deletion
If we used to have an index entry "d/f", but "d" has been replaced by a non-directory entry, the user may still want to run "git rm" to delete the stale index entry. They could use "git rm --cached" to just touch the index, but "git rm" should also work: we explicitly try to handle the case that the file has already been removed from the working tree. However, because unlinking "d/f" in this case will not yield ENOENT, but rather ENOTDIR, we do not notice that the file is already gone. Instead, we report it as an error. The simple solution is to treat ENOTDIR in this case exactly like ENOENT; all we want to know is whether the file is already gone, and if a leading path is no longer a directory, then by definition the sub-path is gone. Reported-by: jpinheiro <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9b924ee commit 9a6728d

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

builtin/rm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static int check_local_mod(unsigned char *head, int index_only)
110110
ce = active_cache[pos];
111111

112112
if (lstat(ce->name, &st) < 0) {
113-
if (errno != ENOENT)
113+
if (errno != ENOENT && errno != ENOTDIR)
114114
warning("'%s': %s", ce->name, strerror(errno));
115115
/* It already vanished from the working tree */
116116
continue;

dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,7 @@ int remove_path(const char *name)
16031603
{
16041604
char *slash;
16051605

1606-
if (unlink(name) && errno != ENOENT)
1606+
if (unlink(name) && errno != ENOENT && errno != ENOTDIR)
16071607
return -1;
16081608

16091609
slash = strrchr(name, '/');

t/t3600-rm.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,4 +622,29 @@ test_expect_success 'rm of a populated nested submodule with a nested .git direc
622622
rm -rf submod
623623
'
624624

625+
test_expect_success 'rm of d/f when d has become a non-directory' '
626+
rm -rf d &&
627+
mkdir d &&
628+
>d/f &&
629+
git add d &&
630+
rm -rf d &&
631+
>d &&
632+
git rm d/f &&
633+
test_must_fail git rev-parse --verify :d/f &&
634+
test_path_is_file d
635+
'
636+
637+
test_expect_success SYMLINKS 'rm of d/f when d has become a dangling symlink' '
638+
rm -rf d &&
639+
mkdir d &&
640+
>d/f &&
641+
git add d &&
642+
rm -rf d &&
643+
ln -s nonexistent d &&
644+
git rm d/f &&
645+
test_must_fail git rev-parse --verify :d/f &&
646+
test -h d &&
647+
test_path_is_missing d
648+
'
649+
625650
test_done

0 commit comments

Comments
 (0)