From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 10/10] clean: support cleaning sparse checkout with -S
Date: Mon, 15 Nov 2010 17:36:50 +0700 [thread overview]
Message-ID: <1289817410-32470-11-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1289817410-32470-1-git-send-email-pclouds@gmail.com>
Those files that are managed by git, but out of working directory due
to sparse-checkout file are subjected to be cleaned by "-S". Files
that match the index exactly will be cleaned without "-f". Otherwise
'-f' is needed.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-clean.txt | 6 ++-
builtin/clean.c | 70 ++++++++++++++++++++++++++++++++
t/t7301-clean-sparse.sh | 92 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 167 insertions(+), 1 deletions(-)
create mode 100755 t/t7301-clean-sparse.sh
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 60e38e6..e0c95b1 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree
SYNOPSIS
--------
[verse]
-'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>...
+'git clean' [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X | -S] [--] <path>...
DESCRIPTION
-----------
@@ -61,6 +61,10 @@ OPTIONS
Remove only files ignored by git. This may be useful to rebuild
everything from scratch, but keep manually created files.
+-S::
+ Remove files tracked by git but are outside of sparse checkout.
+ Files that match the index exactly will be removed even when
+ '-f' is not given and clean.requireForce is no.
Author
------
diff --git a/builtin/clean.c b/builtin/clean.c
index c8798f5..5827993 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -34,11 +34,71 @@ static int exclude_cb(const struct option *opt, const char *arg, int unset)
return 0;
}
+static int clean_sparse_checkout(const char *prefix, const char **pathspec,
+ int show_only, int quiet, int force)
+{
+ struct stat st;
+ int i, errors = 0;
+ unsigned char sha1[20];
+ const char *qname;
+ struct strbuf buf = STRBUF_INIT;
+
+ if (read_cache() < 0)
+ die("index file corrupt");
+ for (i = 0; i < the_index.cache_nr; i++) {
+ struct cache_entry *ce = the_index.cache[i];
+
+ if (!ce_skip_worktree(ce))
+ continue;
+ if (pathspec && !match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+ continue;
+
+ if (stat(ce->name, &st) < 0)
+ continue;
+ qname = quote_path_relative(ce->name, ce_namelen(ce), &buf, prefix);
+ if (index_path(sha1, ce->name, &st, 0) < 0) {
+ warning("failed to hash %s", qname);
+ errors++;
+ continue;
+ }
+ if (!hashcmp(sha1, ce->sha1)) {
+ if (show_only) {
+ printf("Would remove %s\n", qname);
+ continue;
+ }
+ if (!quiet)
+ printf("Removing %s\n", qname);
+ if (unlink(ce->name) != 0) {
+ warning("failed to remove %s", qname);
+ errors++;
+ }
+ continue;
+ }
+ if (force) {
+ if (show_only) {
+ printf("Would remove %s\n", qname);
+ continue;
+ }
+ if (!quiet)
+ printf("Removing %s\n", qname);
+ if (unlink(ce->name) != 0) {
+ warning("failed to remove %s", qname);
+ errors++;
+ }
+ continue;
+ }
+ if (show_only)
+ printf("Would not remove %s\n", qname);
+ }
+ return errors != 0;
+}
+
int cmd_clean(int argc, const char **argv, const char *prefix)
{
int i;
int show_only = 0, remove_directories = 0, quiet = 0, ignored = 0;
int ignored_only = 0, baselen = 0, config_set = 0, errors = 0;
+ int sparse = 0;
int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
struct strbuf directory = STRBUF_INIT;
struct dir_struct dir;
@@ -55,6 +115,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
"remove whole directories"),
{ OPTION_CALLBACK, 'e', "exclude", &exclude_list, "pattern",
"exclude <pattern>", PARSE_OPT_NONEG, exclude_cb },
+ OPT_BOOLEAN('S', NULL, &sparse, "remove tracked files outside sparse checkout"),
OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
OPT_BOOLEAN('X', NULL, &ignored_only,
"remove only ignored files"),
@@ -70,6 +131,15 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, builtin_clean_usage,
0);
+ if (sparse) {
+ if (ignored || ignored_only)
+ die("-S, -x and -X cannot be used together");
+ if (exclude_list.nr)
+ die("-S and -e cannot be used together (yet)");
+ pathspec = get_pathspec(prefix, argv);
+ return clean_sparse_checkout(prefix, pathspec, show_only, quiet, force);
+ }
+
memset(&dir, 0, sizeof(dir));
if (ignored_only)
dir.flags |= DIR_SHOW_IGNORED;
diff --git a/t/t7301-clean-sparse.sh b/t/t7301-clean-sparse.sh
new file mode 100755
index 0000000..3ac0b0a
--- /dev/null
+++ b/t/t7301-clean-sparse.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+test_description='git clean -S basic tests'
+
+. ./test-lib.sh
+
+git config clean.requireForce yes
+
+test_expect_success 'setup' '
+ mkdir src &&
+ touch file1 file2 &&
+ touch src/file1 src/file2 &&
+ git add . &&
+ git update-index --skip-worktree file1 src/file1
+'
+
+test_expect_success 'clean -x -S does not work' '
+ test_must_fail git clean -x -S &&
+ test_must_fail git clean -X -S
+'
+
+test_expect_success 'clean -n -S' '
+ cat >expected <<\EOF
+Would remove file1
+Would remove src/file1
+EOF
+ git clean -n -S >result &&
+ test_cmp expected result
+'
+
+test_expect_success 'clean -n -S src' '
+ cat >expected <<\EOF
+Would remove src/file1
+EOF
+ git clean -n -S src >result &&
+ test_cmp expected result
+'
+
+test_expect_success '[src] clean -n -S .' '
+ (
+ cd src
+ cat >expected <<\EOF
+Would remove file1
+EOF
+ git clean -n -S . >result &&
+ test_cmp expected result
+ )
+'
+
+test_expect_success '[src] clean -n -S ../file1' '
+ (
+ cd src
+ cat >expected <<\EOF
+Would remove ../file1
+EOF
+ git clean -n -S ../file1 >result &&
+ test_cmp expected result
+ )
+'
+
+test_expect_success 'clean -n -S with dirty worktree' '
+ echo dirty >file1 &&
+ cat >expected <<\EOF
+Would not remove file1
+Would remove src/file1
+EOF
+ git clean -n -S >result &&
+ test_cmp expected result
+'
+
+test_expect_success 'clean -f -n -S with dirty worktree' '
+ echo dirty >file1 &&
+ cat >expected <<\EOF
+Would remove file1
+Would remove src/file1
+EOF
+ git clean -f -n -S >result &&
+ test_cmp expected result
+'
+
+test_expect_success 'clean -S with dirty worktree' '
+ git clean -S &&
+ grep dirty file1 &&
+ test ! -f src/file1
+'
+
+test_expect_success 'clean -f -S with dirty worktree' '
+ git clean -f -S &&
+ test ! -f file1
+'
+
+test_done
--
1.7.3.2.210.g045198
next prev parent reply other threads:[~2010-11-15 10:41 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-15 10:36 [PATCH 00/10] Sparse checkout fixes and improvements Nguyễn Thái Ngọc Duy
2010-11-15 10:36 ` [PATCH 01/10] add: do not rely on dtype being NULL behavior Nguyễn Thái Ngọc Duy
2010-11-15 12:14 ` Jonathan Nieder
2010-11-16 2:18 ` Nguyen Thai Ngoc Duy
2010-11-16 2:42 ` Jonathan Nieder
2010-11-16 18:58 ` Junio C Hamano
2010-11-17 6:38 ` Nguyen Thai Ngoc Duy
2010-11-15 10:36 ` [PATCH 02/10] unpack-trees: move all skip-worktree check back to unpack_trees() Nguyễn Thái Ngọc Duy
2010-11-15 12:34 ` Thiago Farina
2010-11-16 2:19 ` Nguyen Thai Ngoc Duy
2010-11-15 16:01 ` Jonathan Nieder
2010-11-16 2:39 ` Nguyen Thai Ngoc Duy
2010-11-15 10:36 ` [PATCH 03/10] unpack-trees: add function to update ce_flags based on sparse patterns Nguyễn Thái Ngọc Duy
2010-11-15 18:30 ` Jonathan Nieder
2010-11-15 20:19 ` Jonathan Nieder
2010-11-15 10:36 ` [PATCH 04/10] unpack-trees: fix sparse checkout's "unable to match directories" fault Nguyễn Thái Ngọc Duy
2010-11-15 19:10 ` Jonathan Nieder
2010-11-16 2:43 ` Nguyen Thai Ngoc Duy
2010-11-15 10:36 ` [PATCH 05/10] unpack-trees: optimize full checkout case Nguyễn Thái Ngọc Duy
2010-11-15 20:41 ` Jonathan Nieder
2010-11-15 10:36 ` [PATCH 06/10] templates: add info/sparse-checkout Nguyễn Thái Ngọc Duy
2010-11-15 10:36 ` [PATCH 07/10] checkout: add -S to update sparse checkout Nguyễn Thái Ngọc Duy
2010-11-15 21:16 ` Jonathan Nieder
2010-11-15 21:52 ` Miles Bader
2010-11-17 15:02 ` Nguyen Thai Ngoc Duy
2010-11-16 3:08 ` Nguyen Thai Ngoc Duy
2010-11-15 10:36 ` [PATCH 08/10] checkout: add --full to fully populate working directory Nguyễn Thái Ngọc Duy
2010-11-15 21:23 ` Jonathan Nieder
2010-11-16 2:50 ` Nguyen Thai Ngoc Duy
2010-11-15 10:36 ` [PATCH 09/10] git-checkout.txt: mention of sparse checkout Nguyễn Thái Ngọc Duy
2010-11-15 10:36 ` Nguyễn Thái Ngọc Duy [this message]
2010-11-15 21:30 ` [PATCH 10/10] clean: support cleaning sparse checkout with -S Jonathan Nieder
2010-11-16 2:53 ` Nguyen Thai Ngoc Duy
2010-11-16 3:07 ` Jonathan Nieder
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=1289817410-32470-11-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.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).