-z makes clean output only the names of paths which are or would be
deleted, and separates them with \0.
Use as "xargs -0 -a <(git clean -nz [-d]) rm -ri", e.g., as a quick
"git clean -i".
Signed-off-by: Michael J Gruber
---
Here's an alternative approach to that problem with a complete different attach
vector but a similar purpose. I've been using it for a while, but it's kind of
unpolished. My "git-clean-i" looks like:
--->%---
#!/bin/bash
xargs -0 -a <(git clean -n -z "$@") rm -ri
--->%---
Documentation/git-clean.txt | 9 -
builtin/clean.c | 27 +++
2 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index bdc3ab8..849e775 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 ] [-x | -X] [--] ...
+'git clean' [-d] [-f] [-n] [-q] [-z] [-e ] [-x | -X] [--] ...
DESCRIPTION
---
@@ -63,6 +63,13 @@ OPTIONS
Remove only files ignored by Git. This may be useful to rebuild
everything from scratch, but keep manually created files.
+-z::
+ Use machine readable output for (to be) removed paths: Output the paths
+ which are or would be removed only (without extra wording) and
+ separate them with \0.
++
+This does not imply `-n` but can be combined with it.
+
SEE ALSO
linkgit:gitignore[5]
diff --git a/builtin/clean.c b/builtin/clean.c
index 04e396b..0ebba24 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -41,8 +41,18 @@ static int exclude_cb(const struct option *opt, const char
*arg, int unset)
return 0;
}
+void write_name(const char *fmt, const char *name, int nul_terminated)
+{
+ if (nul_terminated) {
+ fputs(name, stdout);
+ fputc(0, stdout);
+ } else {
+ printf(fmt, name);
+ }
+}
+
static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
- int dry_run, int quiet, int *dir_gone)
+ int dry_run, int quiet, int *dir_gone, int nul_terminated)
{
DIR *dir;
struct strbuf quoted = STRBUF_INIT;
@@ -57,8 +67,8 @@ static int remove_dirs(struct strbuf *path, const char
*prefix, int force_flag,
!resolve_gitlink_ref(path->buf, "HEAD",
submodule_head)) {
if (!quiet) {
quote_path_relative(path->buf, strlen(path->buf),
"ed, prefix);
- printf(dry_run ? _(msg_would_skip_git_dir) :
_(msg_skip_git_dir),
- quoted.buf);
+ write_name(dry_run ? _(msg_would_skip_git_dir) :
_(msg_skip_git_dir),
+ quoted.buf, nul_terminated);
}
*dir_gone = 0;
@@ -91,7 +101,7 @@ static int remove_dirs(struct strbuf *path, const char
*prefix, int force_flag,
if (lstat(path->buf, &st))
; /* fall thru */
else if (S_ISDIR(st.st_mode)) {
- if (remove_dirs(path, prefix, force_flag, dry_run,
quiet, &gone))
+ if (remove_dirs(path, prefix, force_flag, dry_run,
quiet, &gone, nul_terminated))
ret = 1;
if (gone) {
quote_path_relative(path->buf,
strlen(path->buf), "ed, prefix);
@@ -136,7 +146,7 @@ static int remove_dirs(struct strbuf *path, const char
*prefix, int force_flag,
if (!*dir_gone && !quiet) {
for (i = 0; i < dels.nr; i++)
- printf(dry_run ? _(msg_would_remove) : _(msg_remove),
dels.items[i].string);
+ write_name(dry_run ? _(msg_would_remove) :
_(msg_remove), dels.items[i].string, nul_terminated);
}
string_list_clear(&dels, 0);
return ret;
@@ -146,7 +156,7 @@ int cmd_clean(int argc, const char **argv, const char
*prefix)
{
int i, res;
int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0;
- int ignored_only = 0, config_set = 0, errors = 0, gone = 1;
+ int ignored_only = 0, config_set = 0, errors = 0, gone = 1,
nul_terminated = 0;
int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
struct strbuf directory = STRBUF_INIT;
struct dir_struct dir;
@@ -167,6 +177,7 @@ int cmd_clean(int argc, const char **argv, const char
*prefix)
OPT_BOOLEAN('x', NULL, &ignored, N_("remove ignored files,
too")),
OPT_BOOLEAN('X', NULL, &ignored_only,
N_("remove only ignored files")),
+ OPT_BOOLEAN('z', NULL, &nul_terminated, "(actually or to be)
removed paths are separated with NUL character"),
OPT_END()
};
@@ -259,7 +270,7 @@ int cmd_clean(