Introduce remove_or_warn function
This patch introduces the remove_or_warn function which is a generalised version of the {unlink,rmdir}_or_warn functions. It takes an additional parameter indicating the mode of the file to be removed. The patch also modifies certain functions to use remove_or_warn where appropriate, and adds a test case for a bug fixed by the use of remove_or_warn. Signed-off-by: Peter Collingbourne <peter@pcc.me.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Peter Collingbourne committed
Mar 26, 2010 at 15:25 UTC
80d706afed6c6c6fb3ac9c168a6a958244405b45
5 files changed
+51
-15
builtin/apply.c
+1
-5
@@ -3144,11 +3144,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)
3144
die("unable to remove %s from index", patch->old_name);
3145
}
3146
if (!cached) {
3147
- if (S_ISGITLINK(patch->old_mode)) {
3148
- if (rmdir(patch->old_name))
3149
- warning("unable to remove submodule %s",
3150
- patch->old_name);
3151
- } else if (!unlink_or_warn(patch->old_name) && rmdir_empty) {
3147
+ if (!remove_or_warn(patch->old_mode, patch->old_name) && rmdir_empty) {
3148
remove_path(patch->old_name);
3149
}
3150
}
git-compat-util.h
+5
@@ -473,5 +473,10 @@ int unlink_or_warn(const char *path);
473
* Likewise for rmdir(2).
474
*/
475
int rmdir_or_warn(const char *path);
476
+/*
477
+ * Calls the correct function out of {unlink,rmdir}_or_warn based on
478
+ * the supplied file mode.
479
+ */
480
+int remove_or_warn(unsigned int mode, const char *path);
481
482
#endif
t/t4134-apply-submodule.sh
new
+38
@@ -0,0 +1,38 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2010 Peter Collingbourne
4
+#
5
+
6
+test_description='git apply submodule tests'
7
+
8
+. ./test-lib.sh
9
+
10
+test_expect_success setup '
11
+ cat > create-sm.patch <<EOF
12
+diff --git a/dir/sm b/dir/sm
13
+new file mode 160000
14
+index 0000000..0123456
15
+--- /dev/null
16
++++ b/dir/sm
17
+@@ -0,0 +1 @@
18
++Subproject commit 0123456789abcdef0123456789abcdef01234567
19
+EOF
20
+ cat > remove-sm.patch <<EOF
21
+diff --git a/dir/sm b/dir/sm
22
+deleted file mode 160000
23
+index 0123456..0000000
24
+--- a/dir/sm
25
++++ /dev/null
26
+@@ -1 +0,0 @@
27
+-Subproject commit 0123456789abcdef0123456789abcdef01234567
28
+EOF
29
+'
30
+
31
+test_expect_success 'removing a submodule also removes all leading subdirectories' '
32
+ git apply --index create-sm.patch &&
33
+ test -d dir/sm &&
34
+ git apply --index remove-sm.patch &&
35
+ test \! -d dir
36
+'
37
+
38
+test_done
unpack-trees.c
+2
-10
@@ -67,16 +67,8 @@ static void unlink_entry(struct cache_entry *ce)
67
{
68
if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))
69
return;
70
- if (S_ISGITLINK(ce->ce_mode)) {
71
- if (rmdir(ce->name)) {
72
- warning("unable to rmdir %s: %s",
73
- ce->name, strerror(errno));
74
- return;
75
- }
76
- }
77
- else
78
- if (unlink_or_warn(ce->name))
79
- return;
70
+ if (remove_or_warn(ce->ce_mode, ce->name))
71
+ return;
72
schedule_dir_for_removal(ce->name, ce_namelen(ce));
73
}
74
wrapper.c
+5
@@ -333,3 +333,8 @@ int rmdir_or_warn(const char *file)
333
{
334
return warn_if_unremovable("rmdir", file, rmdir(file));
335
}
336
+
337
+int remove_or_warn(unsigned int mode, const char *file)
338
+{
339
+ return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file);
340
+}