Skip to content

Commit 5df633c

Browse files
dschodrizzd
authored andcommitted
clean: remove mount points when possible
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 <[email protected]>
1 parent b8ff1fa commit 5df633c

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

builtin/clean.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ static const char *msg_remove = N_("Removing %s\n");
3333
static const char *msg_would_remove = N_("Would remove %s\n");
3434
static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
3535
static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
36+
#ifndef CAN_UNLINK_MOUNT_POINTS
3637
static const char *msg_skip_mount_point = N_("Skipping mount point %s\n");
3738
static const char *msg_would_skip_mount_point = N_("Would skip mount point %s\n");
39+
#endif
3840
static const char *msg_warn_remove_failed = N_("failed to remove %s");
3941

4042
enum color_clean {
@@ -171,13 +173,24 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
171173
}
172174

173175
if (is_mount_point(path)) {
176+
#ifndef CAN_UNLINK_MOUNT_POINTS
174177
if (!quiet) {
175178
quote_path_relative(path->buf, prefix, &quoted);
176179
printf(dry_run ?
177180
_(msg_would_skip_mount_point) :
178181
_(msg_skip_mount_point), quoted.buf);
179182
}
180183
*dir_gone = 0;
184+
#else
185+
if (!dry_run && unlink(path->buf)) {
186+
int saved_errno = errno;
187+
quote_path_relative(path->buf, prefix, &quoted);
188+
errno = saved_errno;
189+
warning_errno(_(msg_warn_remove_failed), quoted.buf);
190+
*dir_gone = 0;
191+
ret = -1;
192+
}
193+
#endif
181194

182195
goto out;
183196
}

compat/mingw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ static inline void convert_slashes(char *path)
466466
struct strbuf;
467467
int mingw_is_mount_point(struct strbuf *path);
468468
#define is_mount_point mingw_is_mount_point
469+
#define CAN_UNLINK_MOUNT_POINTS 1
469470
#define PATH_SEP ';'
470471
extern char *mingw_query_user_email(void);
471472
#define query_user_email mingw_query_user_email

t/t7300-clean.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ test_expect_success MINGW 'clean does not traverse mount points' '
686686
git init with-mountpoint &&
687687
cmd //c "mklink /j with-mountpoint\\mountpoint target" &&
688688
git -C with-mountpoint clean -dfx &&
689+
test_path_is_missing with-mountpoint/mountpoint &&
689690
test_path_is_file target/dont-clean-me
690691
'
691692

0 commit comments

Comments
 (0)