Skip to content

Commit 15225d4

Browse files
dschoGit for Windows Build Agent
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 497babc commit 15225d4

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

builtin/clean.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ static const char *msg_remove = N_("Removing %s\n");
3434
static const char *msg_would_remove = N_("Would remove %s\n");
3535
static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
3636
static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
37+
#ifndef CAN_UNLINK_MOUNT_POINTS
3738
static const char *msg_skip_mount_point = N_("Skipping mount point %s\n");
3839
static const char *msg_would_skip_mount_point = N_("Would skip mount point %s\n");
40+
#endif
3941
static const char *msg_warn_remove_failed = N_("failed to remove %s");
4042
static const char *msg_warn_lstat_failed = N_("could not lstat %s\n");
4143

@@ -174,13 +176,24 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
174176
}
175177

176178
if (is_mount_point(path)) {
179+
#ifndef CAN_UNLINK_MOUNT_POINTS
177180
if (!quiet) {
178-
quote_path_relative(path->buf, prefix, &quoted);
181+
quote_path(path->buf, prefix, &quoted, 0);
179182
printf(dry_run ?
180183
_(msg_would_skip_mount_point) :
181184
_(msg_skip_mount_point), quoted.buf);
182185
}
183186
*dir_gone = 0;
187+
#else
188+
if (!dry_run && unlink(path->buf)) {
189+
int saved_errno = errno;
190+
quote_path(path->buf, prefix, &quoted, 0);
191+
errno = saved_errno;
192+
warning_errno(_(msg_warn_remove_failed), quoted.buf);
193+
*dir_gone = 0;
194+
ret = -1;
195+
}
196+
#endif
184197

185198
goto out;
186199
}

compat/mingw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ static inline void convert_slashes(char *path)
446446
struct strbuf;
447447
int mingw_is_mount_point(struct strbuf *path);
448448
#define is_mount_point mingw_is_mount_point
449+
#define CAN_UNLINK_MOUNT_POINTS 1
449450
#define PATH_SEP ';'
450451
char *mingw_query_user_email(void);
451452
#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
@@ -794,6 +794,7 @@ test_expect_success MINGW 'clean does not traverse mount points' '
794794
git init with-mountpoint &&
795795
cmd //c "mklink /j with-mountpoint\\mountpoint target" &&
796796
git -C with-mountpoint clean -dfx &&
797+
test_path_is_missing with-mountpoint/mountpoint &&
797798
test_path_is_file target/dont-clean-me
798799
'
799800

0 commit comments

Comments
 (0)