Skip to content

Commit aaf8e16

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 49fceb1 commit aaf8e16

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
static const char *msg_warn_lstat_failed = N_("could not lstat %s\n");
4042

@@ -173,13 +175,24 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
173175
}
174176

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

184197
goto out;
185198
}

compat/mingw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ static inline void convert_slashes(char *path)
445445
struct strbuf;
446446
int mingw_is_mount_point(struct strbuf *path);
447447
#define is_mount_point mingw_is_mount_point
448+
#define CAN_UNLINK_MOUNT_POINTS 1
448449
#define PATH_SEP ';'
449450
char *mingw_query_user_email(void);
450451
#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
@@ -752,6 +752,7 @@ test_expect_success MINGW 'clean does not traverse mount points' '
752752
git init with-mountpoint &&
753753
cmd //c "mklink /j with-mountpoint\\mountpoint target" &&
754754
git -C with-mountpoint clean -dfx &&
755+
test_path_is_missing with-mountpoint/mountpoint &&
755756
test_path_is_file target/dont-clean-me
756757
'
757758

0 commit comments

Comments
 (0)