Skip to content

Commit

Permalink
clean: remove mount points when possible
Browse files Browse the repository at this point in the history
Windows' equivalent to "bind mounts", NTFS junction points, can be
unlinked without affecting the mount target. This is clearly what users
expect to happen when they call `git clean -dfx` in a worktree that
contains NTFS junction points: the junction should be removed, and the
target directory of said junction should be left alone (unless it is
inside the worktree).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Sep 22, 2022
1 parent cae3981 commit 31df13d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 0 deletions.
13 changes: 13 additions & 0 deletions builtin/clean.c
Expand Up @@ -34,8 +34,10 @@ static const char *msg_remove = N_("Removing %s\n");
static const char *msg_would_remove = N_("Would remove %s\n");
static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
#ifndef CAN_UNLINK_MOUNT_POINTS
static const char *msg_skip_mount_point = N_("Skipping mount point %s\n");
static const char *msg_would_skip_mount_point = N_("Would skip mount point %s\n");
#endif
static const char *msg_warn_remove_failed = N_("failed to remove %s");
static const char *msg_warn_lstat_failed = N_("could not lstat %s\n");
static const char *msg_skip_cwd = N_("Refusing to remove current working directory\n");
Expand Down Expand Up @@ -178,13 +180,24 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
}

if (is_mount_point(path)) {
#ifndef CAN_UNLINK_MOUNT_POINTS
if (!quiet) {
quote_path(path->buf, prefix, &quoted, 0);
printf(dry_run ?
_(msg_would_skip_mount_point) :
_(msg_skip_mount_point), quoted.buf);
}
*dir_gone = 0;
#else
if (!dry_run && unlink(path->buf)) {
int saved_errno = errno;
quote_path(path->buf, prefix, &quoted, 0);
errno = saved_errno;
warning_errno(_(msg_warn_remove_failed), quoted.buf);
*dir_gone = 0;
ret = -1;
}
#endif

goto out;
}
Expand Down
1 change: 1 addition & 0 deletions compat/mingw.h
Expand Up @@ -452,6 +452,7 @@ static inline void convert_slashes(char *path)
struct strbuf;
int mingw_is_mount_point(struct strbuf *path);
#define is_mount_point mingw_is_mount_point
#define CAN_UNLINK_MOUNT_POINTS 1
#define PATH_SEP ';'
char *mingw_query_user_email(void);
#define query_user_email mingw_query_user_email
Expand Down
1 change: 1 addition & 0 deletions t/t7300-clean.sh
Expand Up @@ -794,6 +794,7 @@ test_expect_success MINGW 'clean does not traverse mount points' '
git init with-mountpoint &&
cmd //c "mklink /j with-mountpoint\\mountpoint target" &&
git -C with-mountpoint clean -dfx &&
test_path_is_missing with-mountpoint/mountpoint &&
test_path_is_file target/dont-clean-me
'

Expand Down

0 comments on commit 31df13d

Please sign in to comment.