-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 <git@xxxxxxxxxxxxxxxxxxxx> --- 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 <pattern>] [-x | -X] [--] <path>... +'git clean' [-d] [-f] [-n] [-q] [-z] [-e <pattern>] [-x | -X] [--] <path>... 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(int argc, const char **argv, const char *prefix) if (S_ISDIR(st.st_mode)) { strbuf_addstr(&directory, ent->name); if (remove_directories || (matches == MATCHED_EXACTLY)) { - if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone)) + if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone, nul_terminated)) errors++; if (gone && !quiet) { qname = quote_path_relative(directory.buf, directory.len, &buf, prefix); @@ -277,7 +288,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) errors++; } else if (!quiet) { qname = quote_path_relative(ent->name, -1, &buf, prefix); - printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname); + write_name(dry_run ? _(msg_would_remove) : _(msg_remove), qname, nul_terminated); } } } -- 1.8.3.rc0.297.g8c90ec5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html