From 10e13ec8ed36019d131d27cd9fe2e8cc0f99b896 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 26 Mar 2010 15:25:32 +0000 Subject: [PATCH 1/4] Generalise the unlink_or_warn function This patch moves the warning code of the unlink_or_warn function into a separate function named warn_if_unremovable so that it may be reused. Signed-off-by: Peter Collingbourne Signed-off-by: Junio C Hamano --- wrapper.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/wrapper.c b/wrapper.c index 9c71b21242..0bbff56e2c 100644 --- a/wrapper.c +++ b/wrapper.c @@ -311,18 +311,20 @@ int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1) return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); } -int unlink_or_warn(const char *file) +static int warn_if_unremovable(const char *op, const char *file, int rc) { - int rc = unlink(file); - if (rc < 0) { int err = errno; if (ENOENT != err) { - warning("unable to unlink %s: %s", - file, strerror(errno)); + warning("unable to %s %s: %s", + op, file, strerror(errno)); errno = err; } } return rc; } +int unlink_or_warn(const char *file) +{ + return warn_if_unremovable("unlink", file, unlink(file)); +} From d1723296af67e6bbadf6e73cd1e921aefafe491f Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 26 Mar 2010 15:25:33 +0000 Subject: [PATCH 2/4] Implement the rmdir_or_warn function This patch implements an rmdir_or_warn function (like unlink_or_warn but for directories) that uses the generalised warning code in warn_if_unremovable. Signed-off-by: Peter Collingbourne Signed-off-by: Junio C Hamano --- git-compat-util.h | 4 ++++ wrapper.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/git-compat-util.h b/git-compat-util.h index a3c4537366..67ea4c89f5 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -469,5 +469,9 @@ void git_qsort(void *base, size_t nmemb, size_t size, * Always returns the return value of unlink(2). */ int unlink_or_warn(const char *path); +/* + * Likewise for rmdir(2). + */ +int rmdir_or_warn(const char *path); #endif diff --git a/wrapper.c b/wrapper.c index 0bbff56e2c..4017bff6bb 100644 --- a/wrapper.c +++ b/wrapper.c @@ -328,3 +328,8 @@ int unlink_or_warn(const char *file) { return warn_if_unremovable("unlink", file, unlink(file)); } + +int rmdir_or_warn(const char *file) +{ + return warn_if_unremovable("rmdir", file, rmdir(file)); +} From 80d706afed6c6c6fb3ac9c168a6a958244405b45 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 26 Mar 2010 15:25:34 +0000 Subject: [PATCH 3/4] 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 Signed-off-by: Junio C Hamano --- builtin/apply.c | 6 +----- git-compat-util.h | 5 +++++ t/t4134-apply-submodule.sh | 38 ++++++++++++++++++++++++++++++++++++++ unpack-trees.c | 12 ++---------- wrapper.c | 5 +++++ 5 files changed, 51 insertions(+), 15 deletions(-) create mode 100755 t/t4134-apply-submodule.sh diff --git a/builtin/apply.c b/builtin/apply.c index 7ca90472c1..65a594c985 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -3144,11 +3144,7 @@ static void remove_file(struct patch *patch, int rmdir_empty) die("unable to remove %s from index", patch->old_name); } if (!cached) { - if (S_ISGITLINK(patch->old_mode)) { - if (rmdir(patch->old_name)) - warning("unable to remove submodule %s", - patch->old_name); - } else if (!unlink_or_warn(patch->old_name) && rmdir_empty) { + if (!remove_or_warn(patch->old_mode, patch->old_name) && rmdir_empty) { remove_path(patch->old_name); } } diff --git a/git-compat-util.h b/git-compat-util.h index 67ea4c89f5..3ebf96690a 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -473,5 +473,10 @@ int unlink_or_warn(const char *path); * Likewise for rmdir(2). */ int rmdir_or_warn(const char *path); +/* + * Calls the correct function out of {unlink,rmdir}_or_warn based on + * the supplied file mode. + */ +int remove_or_warn(unsigned int mode, const char *path); #endif diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh new file mode 100755 index 0000000000..1b82f93cff --- /dev/null +++ b/t/t4134-apply-submodule.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (c) 2010 Peter Collingbourne +# + +test_description='git apply submodule tests' + +. ./test-lib.sh + +test_expect_success setup ' + cat > create-sm.patch < remove-sm.patch <name, ce_namelen(ce))) return; - if (S_ISGITLINK(ce->ce_mode)) { - if (rmdir(ce->name)) { - warning("unable to rmdir %s: %s", - ce->name, strerror(errno)); - return; - } - } - else - if (unlink_or_warn(ce->name)) - return; + if (remove_or_warn(ce->ce_mode, ce->name)) + return; schedule_dir_for_removal(ce->name, ce_namelen(ce)); } diff --git a/wrapper.c b/wrapper.c index 4017bff6bb..10a6750795 100644 --- a/wrapper.c +++ b/wrapper.c @@ -333,3 +333,8 @@ int rmdir_or_warn(const char *file) { return warn_if_unremovable("rmdir", file, rmdir(file)); } + +int remove_or_warn(unsigned int mode, const char *file) +{ + return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file); +} From 25755e842f814751fbdb7abfc8255a40f24bfaa3 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 26 Mar 2010 15:25:35 +0000 Subject: [PATCH 4/4] Remove a redundant errno test in a usage of remove_path The errno test is redundant because the same test is carried out in remove_path itself. Signed-off-by: Peter Collingbourne Signed-off-by: Junio C Hamano --- merge-recursive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/merge-recursive.c b/merge-recursive.c index 195ebf9744..87232b899d 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -409,7 +409,7 @@ static int remove_file(struct merge_options *o, int clean, return -1; } if (update_working_directory) { - if (remove_path(path) && errno != ENOENT) + if (remove_path(path)) return -1; } return 0;