From: Ciaran McCreesh <ciaran.mccreesh@googlemail.com>
To: git@vger.kernel.org
Cc: Ciaran McCreesh <ciaran.mccreesh@googlemail.com>
Subject: [PATCH,RFC] Implement 'git rm --if-missing'
Date: Wed, 16 Jul 2008 19:00:50 +0100 [thread overview]
Message-ID: <1216231250-21141-1-git-send-email-ciaran.mccreesh@googlemail.com> (raw)
git rm --if-missing will only remove files if they've already been removed from
disk.
Signed-off-by: Ciaran McCreesh <ciaran.mccreesh@googlemail.com>
---
There's nothing here that can't be done using git update-index, but git rm
is less scary.
Regarding exit status: I'm not sure whether exit status should be based upon
whether any files were actually removed, or whether it should be based upon
whether or not all of the supplied patterns were matched. I've gone for the
latter, so that 'git rm --if-missing -r .' succeeds if there's nothing to
remove.
I'm not sure whether 'missing' is the best word. '--if-noent' might be more
appropriate, but less familiar to some. Or is this worth a short option?
Documentation/git-rm.txt | 8 +++++++-
builtin-rm.c | 9 ++++++++-
t/t3600-rm.sh | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index 4d0c495..f9335f3 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -7,7 +7,8 @@ git-rm - Remove files from the working tree and from the index
SYNOPSIS
--------
-'git rm' [-f] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
+'git rm' [-f] [-n] [-r] [--cached] [--ignore-unmatch] [--if-missing]
+ [--quiet] [--] <file>...
DESCRIPTION
-----------
@@ -61,6 +62,11 @@ OPTIONS
--ignore-unmatch::
Exit with a zero status even if no files matched.
+--if-missing::
+ Only remove files if they have been removed from disk. Exit status
+ is still based upon whether matches succeed, not whether a remove
+ actually took place.
+
-q::
--quiet::
'git-rm' normally outputs one line (in the form of an "rm" command)
diff --git a/builtin-rm.c b/builtin-rm.c
index 22c9bd1..4b89705 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -125,7 +125,7 @@ static int check_local_mod(unsigned char *head, int index_only)
static struct lock_file lock_file;
static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
-static int ignore_unmatch = 0;
+static int ignore_unmatch = 0, if_missing = 0;
static struct option builtin_rm_options[] = {
OPT__DRY_RUN(&show_only),
@@ -135,6 +135,7 @@ static struct option builtin_rm_options[] = {
OPT_BOOLEAN('r', NULL, &recursive, "allow recursive removal"),
OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch,
"exit with a zero status even if nothing matched"),
+ OPT_BOOLEAN( 0 , "if-missing", &if_missing, "only remove missing files"),
OPT_END(),
};
@@ -168,6 +169,12 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
struct cache_entry *ce = active_cache[i];
if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
continue;
+ if (if_missing)
+ {
+ struct stat st;
+ if ((lstat(ce->name, &st) == 0) || (errno != ENOENT))
+ continue;
+ }
add_list(ce->name);
}
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index f542f0a..c7c1810 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -143,6 +143,45 @@ test_expect_success '"rm" command suppressed with --quiet' '
git commit -m "remove file from rm --quiet test"
'
+test_expect_success 'Test that "rm --if-missing" works' '
+ echo frotz > test-file &&
+ echo frotz > other-file &&
+ git add test-file other-file &&
+ git commit -m "add files from rm --if-missing test" &&
+ rm test-file &&
+ git rm --if-missing test-file other-file &&
+ ! git ls-files --error-unmatch test-file &&
+ git ls-files --error-unmatch other-file &&
+ git rm other-file &&
+ git commit -m "remove file from rm --if-missing test"
+'
+
+test_expect_success 'Test that "rm --if-missing -r *" works' '
+ echo frotz > test-file &&
+ mkdir -p frotz &&
+ echo frotz > frotz/other-file &&
+ git add test-file frotz/other-file &&
+ git commit -m "add file from rm --if-missing -r * test" &&
+ rm frotz/other-file
+ git rm --if-missing --ignore-unmatch -r \* &&
+ git ls-files --error-unmatch test-file &&
+ git rm test-file &&
+ git commit -m "remove file from rm --missing -r * test &&
+ ! test -d frotz"
+'
+
+test_expect_success 'Test that "rm --if-missing -r *" works even if nothing is removed' '
+ echo frotz > test-file &&
+ mkdir -p frotz &&
+ echo frotz > frotz/other-file &&
+ git add test-file frotz/other-file &&
+ git commit -m "add file from rm --if-missing -r * test" &&
+ git rm --if-missing --ignore-unmatch -r \* &&
+ git rm test-file frotz/other-file &&
+ git commit -m "remove file from rm --missing -r * test &&
+ ! test -d frotz"
+'
+
# Now, failure cases.
test_expect_success 'Re-add foo and baz' '
git add foo baz &&
@@ -217,4 +256,8 @@ test_expect_success 'Remove nonexistent file returns nonzero exit status' '
! git rm nonexistent
'
+test_expect_success 'Test that "rm --if-missing nonexistent" fails' '
+ ! git rm --if-missing nonexistent
+'
+
test_done
--
1.5.6.3.385.g7c3f1
next reply other threads:[~2008-07-16 18:01 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-16 18:00 Ciaran McCreesh [this message]
2008-07-16 18:06 ` [PATCH,RFC] Implement 'git rm --if-missing' Petr Baudis
2008-07-16 18:17 ` Avery Pennarun
2008-07-16 18:48 ` Junio C Hamano
2008-07-16 18:58 ` Peter Baumann
2008-07-16 19:43 ` David Christensen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1216231250-21141-1-git-send-email-ciaran.mccreesh@googlemail.com \
--to=ciaran.mccreesh@googlemail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).