git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH v4] git-clean: Display more accurate delete messages
@ 2013-01-06 23:16 Zoltan Klinger
  2013-01-06 23:40 ` Jonathan Nieder
  2013-01-10  2:56 ` Junio C Hamano
  0 siblings, 2 replies; 6+ messages in thread
From: Zoltan Klinger @ 2013-01-06 23:16 UTC (permalink / raw)
  To: git; +Cc: Zoltan Klinger

(1) Only print out the names of the files and directories that got
    actually deleted.
(2) Show warning message for ignored untracked git repositories

Consider the following repo layout:

  test.git/
    |-- tracked_dir/
    |     |-- some_tracked_file
    |     |-- some_untracked_file
    |-- tracked_file
    |-- untracked_file
    |-- untracked_foo/
    |     |-- bar/
    |     |     |-- bar.txt
    |     |-- emptydir/
    |     |-- frotz.git/
    |           |-- frotz.tx
    |-- untracked_some.git/
          |-- some.txt

Suppose the user issues 'git clean -fd' from the test.git directory.

When -d option is used and untracked directory 'foo' contains a
subdirectory 'frotz.git' that is managed by a different git repository
therefore it will not be removed.

  $ git clean -fd
  Removing tracked_dir/some_untracked_file
  Removing untracked_file
  Removing untracked_foo/
  Removing untracked_some.git/

The message displayed to the user is slightly misleading. The foo/
directory has not been removed because of foo/frotz.git still exists.
On the other hand the subdirectories 'bar' and 'emptydir' have been
deleted but they're not mentioned anywhere. Also, untracked_some.git
has not been removed either.

This behaviour is the result of the way the deletion of untracked
directories are reported. In the current implementation they are
deleted recursively but only the name of the top most directory is
printed out. The calling function does not know about any
subdirectories that could not be removed during the recursion.

Improve the way the deleted directories are reported back to
the user:
  (1) Create a recursive delete function 'remove_dirs' in builtin/clean.c
      to run in both dry_run and delete modes with the delete logic as
      follows:
        (a) Check if the current directory to be deleted is an untracked
            git repository. If it is and --force --force option is not set
            do not touch this directory, print ignore message, set dir_gone
            flag to false for the caller and return.
        (b) Otherwise for each item in current directory:
              (i)   If current directory cannot be accessed, print warning,
                    set dir_gone flag to false and return.
              (ii)  If the item is a subdirectory recurse into it,
                    check for the returned value of the dir_gone flag.
                    If the subdirectory is gone, add the name of the deleted
                    directory to a list of successfully removed items 'dels'.
                    Else set the dir_gone flag as the current directory
                    cannot be removed because we have at least one subdirectory
                    hanging around.
              (iii) If it is a file try to remove it. If success add the
                    file name to the 'dels' list, else print error and set
                    dir_gone flag to false.
        (c) After we finished deleting all items in the current directory and
            the dir_gone flag is still true, remove the directory itself.
            If failed set the dir_gone flag to false.

        (d) If the current directory cannot be deleted because the dir_gone flag
            has been set to false, print out all the successfully deleted items
            for this directory from the 'dels' list.
        (e) We're done with the current directory, return.

  (2) Modify the cmd_clean() function to:
        (a) call the recursive delete function 'remove_dirs()' for each
            topmost directory it wants to remove
        (b) check for the returned value of dir_gone flag. If it's true
            print the name of the directory as being removed.

Consider the output of the improved version:

  $ git clean -fd
  Removing tracked_dir/some_untracked_file
  Removing untracked_file
  warning: ignoring untracked git repository untracked_foo/frotz.git
  Removing untracked_foo/bar
  Removing untracked_foo/emptydir
  warning: ignoring untracked git repository untracked_some.git/

Now it displays only the file and directory names that got actually
deleted and shows warnings about ignored untracked git repositories.

Reported-by: Soren Brinkmann <soren.brinkmann@xilinx.com>

Signed-off-by: Zoltan Klinger <zoltan.klinger@gmail.com>
---
 builtin/clean.c |  158 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 129 insertions(+), 29 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 69c1cda..1714546 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -10,6 +10,7 @@
 #include "cache.h"
 #include "dir.h"
 #include "parse-options.h"
+#include "refs.h"
 #include "string-list.h"
 #include "quote.h"
 
@@ -20,6 +21,12 @@ static const char *const builtin_clean_usage[] = {
 	NULL
 };
 
+static const char *msg_remove = N_("Removing %s\n");
+static const char *msg_would_remove = N_("Would remove %s\n");
+static const char *msg_would_ignore_git_dir = N_("Would ignore untracked git repository %s\n");
+static const char *msg_warn_ignore_git_dir = N_("ignoring untracked git repository %s");
+static const char *msg_warn_remove_failed = N_("failed to remove %s");
+
 static int git_clean_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "clean.requireforce"))
@@ -34,11 +41,116 @@ static int exclude_cb(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
+		int dry_run, int quiet, int *dir_gone)
+{
+	DIR *dir;
+	struct strbuf quoted = STRBUF_INIT;
+	struct dirent *e;
+	int res = 0, ret = 0, gone = 1, original_len = path->len, len, i;
+	unsigned char submodule_head[20];
+	struct string_list dels = STRING_LIST_INIT_DUP;
+
+	*dir_gone = 1;
+
+	if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
+	    !resolve_gitlink_ref(path->buf, "HEAD", submodule_head)) {
+		if (dry_run && !quiet) {
+			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+			printf(_(msg_would_ignore_git_dir), quoted.buf);
+		} else if (!dry_run) {
+			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+			warning(_(msg_warn_ignore_git_dir), quoted.buf);
+		}
+
+		*dir_gone = 0;
+		return 0;
+	}
+
+	dir = opendir(path->buf);
+	if (!dir) {
+		/* an empty dir could be removed even if it is unreadble */
+		res = dry_run ? 0 : rmdir(path->buf);
+		if (res) {
+			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+			warning(_(msg_warn_remove_failed), quoted.buf);
+			*dir_gone = 0;
+		}
+		return res;
+	}
+
+	if (path->buf[original_len - 1] != '/')
+		strbuf_addch(path, '/');
+
+	len = path->len;
+	while ((e = readdir(dir)) != NULL) {
+		struct stat st;
+		if (is_dot_or_dotdot(e->d_name))
+			continue;
+
+		strbuf_setlen(path, len);
+		strbuf_addstr(path, e->d_name);
+		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))
+				ret = 1;
+			if (gone) {
+				quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+				string_list_append(&dels, quoted.buf);
+			}
+			else
+				*dir_gone = 0;
+			continue;
+		} else {
+			res = dry_run ? 0 : unlink(path->buf);
+			if (!res) {
+				quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+				string_list_append(&dels, quoted.buf);
+			}
+			else {
+				quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+				warning(_(msg_warn_remove_failed), quoted.buf);
+				*dir_gone = 0;
+				ret = 1;
+			}
+			continue;
+		}
+
+		/* path too long, stat fails, or non-directory still exists */
+		*dir_gone = 0;
+		ret = 1;
+		break;
+	}
+	closedir(dir);
+
+	strbuf_setlen(path, original_len);
+
+	if (*dir_gone) {
+		res = dry_run ? 0 : rmdir(path->buf);
+		if (!res)
+			*dir_gone = 1;
+		else {
+			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
+			warning(_(msg_warn_remove_failed), quoted.buf);
+			*dir_gone = 0;
+			ret = 1;
+		}
+	}
+
+	if (!*dir_gone && !quiet) {
+		for (i = 0; i < dels.nr; i++)
+			printf(dry_run ?  _(msg_would_remove) : _(msg_remove), dels.items[i].string);
+	}
+	string_list_clear(&dels, 0);
+	return ret;
+}
+
 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, config_set = 0, errors = 0;
+	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 rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
 	struct strbuf directory = STRBUF_INIT;
 	struct dir_struct dir;
@@ -49,7 +161,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	char *seen = NULL;
 	struct option options[] = {
 		OPT__QUIET(&quiet, N_("do not print names of files removed")),
-		OPT__DRY_RUN(&show_only, N_("dry run")),
+		OPT__DRY_RUN(&dry_run, N_("dry run")),
 		OPT__FORCE(&force, N_("force")),
 		OPT_BOOLEAN('d', NULL, &remove_directories,
 				N_("remove whole directories")),
@@ -77,7 +189,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	if (ignored && ignored_only)
 		die(_("-x and -X cannot be used together"));
 
-	if (!show_only && !force) {
+	if (!dry_run && !force) {
 		if (config_set)
 			die(_("clean.requireForce set to true and neither -n nor -f given; "
 				  "refusing to clean"));
@@ -149,38 +261,26 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 
 		if (S_ISDIR(st.st_mode)) {
 			strbuf_addstr(&directory, ent->name);
-			qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
-			if (show_only && (remove_directories ||
-			    (matches == MATCHED_EXACTLY))) {
-				printf(_("Would remove %s\n"), qname);
-			} else if (remove_directories ||
-				   (matches == MATCHED_EXACTLY)) {
-				if (!quiet)
-					printf(_("Removing %s\n"), qname);
-				if (remove_dir_recursively(&directory,
-							   rm_flags) != 0) {
-					warning(_("failed to remove %s"), qname);
+			if (remove_directories || (matches == MATCHED_EXACTLY)) {
+				if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone))
 					errors++;
+				if (gone && !quiet) {
+					qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
+					printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
 				}
-			} else if (show_only) {
-				printf(_("Would not remove %s\n"), qname);
-			} else {
-				printf(_("Not removing %s\n"), qname);
 			}
 			strbuf_reset(&directory);
 		} else {
 			if (pathspec && !matches)
 				continue;
-			qname = quote_path_relative(ent->name, -1, &buf, prefix);
-			if (show_only) {
-				printf(_("Would remove %s\n"), qname);
-				continue;
-			} else if (!quiet) {
-				printf(_("Removing %s\n"), qname);
-			}
-			if (unlink(ent->name) != 0) {
-				warning(_("failed to remove %s"), qname);
+			res = dry_run ? 0 : unlink(ent->name);
+			if (res) {
+				qname = quote_path_relative(ent->name, -1, &buf, prefix);
+				warning(_(msg_warn_remove_failed), qname);
 				errors++;
+			} else if (!quiet) {
+				qname = quote_path_relative(ent->name, -1, &buf, prefix);
+				printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
 			}
 		}
 	}
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] git-clean: Display more accurate delete messages
  2013-01-06 23:16 [PATCH v4] git-clean: Display more accurate delete messages Zoltan Klinger
@ 2013-01-06 23:40 ` Jonathan Nieder
  2013-01-10  1:01   ` Zoltan Klinger
  2013-01-10  2:56 ` Junio C Hamano
  1 sibling, 1 reply; 6+ messages in thread
From: Jonathan Nieder @ 2013-01-06 23:40 UTC (permalink / raw)
  To: Zoltan Klinger; +Cc: git, Soren Brinkmann, Jens Lehmann, Peter Collingbourne

Zoltan Klinger wrote:

>   $ git clean -fd
>   Removing tracked_dir/some_untracked_file
>   Removing untracked_file
>   Removing untracked_foo/
>   Removing untracked_some.git/
>
> The message displayed to the user is slightly misleading. The foo/
> directory has not been removed because of foo/frotz.git still exists.
> On the other hand the subdirectories 'bar' and 'emptydir' have been
> deleted but they're not mentioned anywhere. Also, untracked_some.git
> has not been removed either.
[...]
> Consider the output of the improved version:
>
>   $ git clean -fd
>   Removing tracked_dir/some_untracked_file
>   Removing untracked_file
>   warning: ignoring untracked git repository untracked_foo/frotz.git
>   Removing untracked_foo/bar
>   Removing untracked_foo/emptydir
>   warning: ignoring untracked git repository untracked_some.git/

Thanks, this looks like a nice improvement.

I wonder whether it's possible to make the output more consistent,
as in:

	Removing tracked_dir/some_untracked_file
	Removing untracked_file
	Skipping repository untracked_foo/frotz.git
	Removing untracked_foo/bar
	Removing untracked_foo/emptydir
	Skipping repository untracked_some.git

or similar.  What do you think?

Thanks,
Jonathan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] git-clean: Display more accurate delete messages
  2013-01-06 23:40 ` Jonathan Nieder
@ 2013-01-10  1:01   ` Zoltan Klinger
  0 siblings, 0 replies; 6+ messages in thread
From: Zoltan Klinger @ 2013-01-10  1:01 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, Soren Brinkmann, Jens Lehmann, Peter Collingbourne

> I wonder whether it's possible to make the output more consistent,
> as in:
>
>     Removing tracked_dir/some_untracked_file
>     Removing untracked_file
>     Skipping repository untracked_foo/frotz.git
>     Removing untracked_foo/bar
>     Removing untracked_foo/emptydir
>     Skipping repository untracked_some.git
>
> or similar.  What do you think?

Agree, the output looks much neater printed like that. I am going to
update the patch unless someone feels strongly against the proposed
output.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] git-clean: Display more accurate delete messages
  2013-01-06 23:16 [PATCH v4] git-clean: Display more accurate delete messages Zoltan Klinger
  2013-01-06 23:40 ` Jonathan Nieder
@ 2013-01-10  2:56 ` Junio C Hamano
  2013-01-10 10:41   ` Zoltan Klinger
  1 sibling, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2013-01-10  2:56 UTC (permalink / raw)
  To: Zoltan Klinger; +Cc: git

Zoltan Klinger <zoltan.klinger@gmail.com> writes:

> Consider the output of the improved version:
>
>   $ git clean -fd
>   Removing tracked_dir/some_untracked_file
>   Removing untracked_file
>   warning: ignoring untracked git repository untracked_foo/frotz.git
>   Removing untracked_foo/bar
>   Removing untracked_foo/emptydir
>   warning: ignoring untracked git repository untracked_some.git/
>
> Now it displays only the file and directory names that got actually
> deleted and shows warnings about ignored untracked git repositories.
>
> Reported-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
>
> Signed-off-by: Zoltan Klinger <zoltan.klinger@gmail.com>
> ---

I think the code before this patch used to say "Would not remove"
and "Not removing" in certain cases to report the paths that the
command decided not to remove, but after this patch these two
messages no longer appear in the patch.

Is it expected, are we losing information, or...?

>  builtin/clean.c |  158 +++++++++++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 129 insertions(+), 29 deletions(-)
>
> diff --git a/builtin/clean.c b/builtin/clean.c
> index 69c1cda..1714546 100644
> --- a/builtin/clean.c
> +++ b/builtin/clean.c
> @@ -10,6 +10,7 @@
>  #include "cache.h"
>  #include "dir.h"
>  #include "parse-options.h"
> +#include "refs.h"
>  #include "string-list.h"
>  #include "quote.h"
>  
> @@ -20,6 +21,12 @@ static const char *const builtin_clean_usage[] = {
>  	NULL
>  };
>  
> +static const char *msg_remove = N_("Removing %s\n");
> +static const char *msg_would_remove = N_("Would remove %s\n");
> +static const char *msg_would_ignore_git_dir = N_("Would ignore untracked git repository %s\n");
> +static const char *msg_warn_ignore_git_dir = N_("ignoring untracked git repository %s");
> +static const char *msg_warn_remove_failed = N_("failed to remove %s");
> +
>  static int git_clean_config(const char *var, const char *value, void *cb)
>  {
>  	if (!strcmp(var, "clean.requireforce"))
> @@ -34,11 +41,116 @@ static int exclude_cb(const struct option *opt, const char *arg, int unset)
>  	return 0;
>  }
>  
> +static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
> +		int dry_run, int quiet, int *dir_gone)
> +{
> +	DIR *dir;
> +	struct strbuf quoted = STRBUF_INIT;
> +	struct dirent *e;
> +	int res = 0, ret = 0, gone = 1, original_len = path->len, len, i;
> +	unsigned char submodule_head[20];
> +	struct string_list dels = STRING_LIST_INIT_DUP;
> +
> +	*dir_gone = 1;
> +
> +	if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
> +	    !resolve_gitlink_ref(path->buf, "HEAD", submodule_head)) {
> +		if (dry_run && !quiet) {
> +			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +			printf(_(msg_would_ignore_git_dir), quoted.buf);
> +		} else if (!dry_run) {
> +			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +			warning(_(msg_warn_ignore_git_dir), quoted.buf);
> +		}
> +
> +		*dir_gone = 0;
> +		return 0;
> +	}
> +
> +	dir = opendir(path->buf);
> +	if (!dir) {
> +		/* an empty dir could be removed even if it is unreadble */
> +		res = dry_run ? 0 : rmdir(path->buf);
> +		if (res) {
> +			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +			warning(_(msg_warn_remove_failed), quoted.buf);
> +			*dir_gone = 0;
> +		}
> +		return res;
> +	}
> +
> +	if (path->buf[original_len - 1] != '/')
> +		strbuf_addch(path, '/');
> +
> +	len = path->len;
> +	while ((e = readdir(dir)) != NULL) {
> +		struct stat st;
> +		if (is_dot_or_dotdot(e->d_name))
> +			continue;
> +
> +		strbuf_setlen(path, len);
> +		strbuf_addstr(path, e->d_name);
> +		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))
> +				ret = 1;
> +			if (gone) {
> +				quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +				string_list_append(&dels, quoted.buf);
> +			}
> +			else
> +				*dir_gone = 0;
> +			continue;
> +		} else {
> +			res = dry_run ? 0 : unlink(path->buf);
> +			if (!res) {
> +				quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +				string_list_append(&dels, quoted.buf);
> +			}
> +			else {
> +				quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +				warning(_(msg_warn_remove_failed), quoted.buf);
> +				*dir_gone = 0;
> +				ret = 1;
> +			}
> +			continue;
> +		}
> +
> +		/* path too long, stat fails, or non-directory still exists */
> +		*dir_gone = 0;
> +		ret = 1;
> +		break;
> +	}
> +	closedir(dir);
> +
> +	strbuf_setlen(path, original_len);
> +
> +	if (*dir_gone) {
> +		res = dry_run ? 0 : rmdir(path->buf);
> +		if (!res)
> +			*dir_gone = 1;
> +		else {
> +			quote_path_relative(path->buf, strlen(path->buf), &quoted, prefix);
> +			warning(_(msg_warn_remove_failed), quoted.buf);
> +			*dir_gone = 0;
> +			ret = 1;
> +		}
> +	}
> +
> +	if (!*dir_gone && !quiet) {
> +		for (i = 0; i < dels.nr; i++)
> +			printf(dry_run ?  _(msg_would_remove) : _(msg_remove), dels.items[i].string);
> +	}
> +	string_list_clear(&dels, 0);
> +	return ret;
> +}
> +
>  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, config_set = 0, errors = 0;
> +	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 rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
>  	struct strbuf directory = STRBUF_INIT;
>  	struct dir_struct dir;
> @@ -49,7 +161,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
>  	char *seen = NULL;
>  	struct option options[] = {
>  		OPT__QUIET(&quiet, N_("do not print names of files removed")),
> -		OPT__DRY_RUN(&show_only, N_("dry run")),
> +		OPT__DRY_RUN(&dry_run, N_("dry run")),
>  		OPT__FORCE(&force, N_("force")),
>  		OPT_BOOLEAN('d', NULL, &remove_directories,
>  				N_("remove whole directories")),
> @@ -77,7 +189,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
>  	if (ignored && ignored_only)
>  		die(_("-x and -X cannot be used together"));
>  
> -	if (!show_only && !force) {
> +	if (!dry_run && !force) {
>  		if (config_set)
>  			die(_("clean.requireForce set to true and neither -n nor -f given; "
>  				  "refusing to clean"));
> @@ -149,38 +261,26 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
>  
>  		if (S_ISDIR(st.st_mode)) {
>  			strbuf_addstr(&directory, ent->name);
> -			qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
> -			if (show_only && (remove_directories ||
> -			    (matches == MATCHED_EXACTLY))) {
> -				printf(_("Would remove %s\n"), qname);
> -			} else if (remove_directories ||
> -				   (matches == MATCHED_EXACTLY)) {
> -				if (!quiet)
> -					printf(_("Removing %s\n"), qname);
> -				if (remove_dir_recursively(&directory,
> -							   rm_flags) != 0) {
> -					warning(_("failed to remove %s"), qname);
> +			if (remove_directories || (matches == MATCHED_EXACTLY)) {
> +				if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone))
>  					errors++;
> +				if (gone && !quiet) {
> +					qname = quote_path_relative(directory.buf, directory.len, &buf, prefix);
> +					printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
>  				}
> -			} else if (show_only) {
> -				printf(_("Would not remove %s\n"), qname);
> -			} else {
> -				printf(_("Not removing %s\n"), qname);
>  			}
>  			strbuf_reset(&directory);
>  		} else {
>  			if (pathspec && !matches)
>  				continue;
> -			qname = quote_path_relative(ent->name, -1, &buf, prefix);
> -			if (show_only) {
> -				printf(_("Would remove %s\n"), qname);
> -				continue;
> -			} else if (!quiet) {
> -				printf(_("Removing %s\n"), qname);
> -			}
> -			if (unlink(ent->name) != 0) {
> -				warning(_("failed to remove %s"), qname);
> +			res = dry_run ? 0 : unlink(ent->name);
> +			if (res) {
> +				qname = quote_path_relative(ent->name, -1, &buf, prefix);
> +				warning(_(msg_warn_remove_failed), qname);
>  				errors++;
> +			} else if (!quiet) {
> +				qname = quote_path_relative(ent->name, -1, &buf, prefix);
> +				printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
>  			}
>  		}
>  	}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] git-clean: Display more accurate delete messages
  2013-01-10  2:56 ` Junio C Hamano
@ 2013-01-10 10:41   ` Zoltan Klinger
  2013-01-10 17:45     ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Zoltan Klinger @ 2013-01-10 10:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

> I think the code before this patch used to say "Would not remove"
> and "Not removing" in certain cases to report the paths that the
> command decided not to remove, but after this patch these two
> messages no longer appear in the patch.
>
> Is it expected, are we losing information, or...?
>

I do not think we are losing any information.
Say, we have a repo like this:
    test.git
     |-- untracked_file
     |-- untracked_bar
     |     |-- bar.txt
     |-- untracked_foo
           |-- foo.txt

The original version prints out:
  $ git clean -fn
  Would remove untracked_file
  Would not remove untracked_bar/
  Would not remove untracked_foo/

We never asked for any directories to be removed so IMHO the "Would
not remove ..." messages are just noise.

The new version prints out:
  $ git clean -fn
  Would remove untracked_file

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4] git-clean: Display more accurate delete messages
  2013-01-10 10:41   ` Zoltan Klinger
@ 2013-01-10 17:45     ` Junio C Hamano
  0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2013-01-10 17:45 UTC (permalink / raw)
  To: Zoltan Klinger; +Cc: git

Zoltan Klinger <zoltan.klinger@gmail.com> writes:

>> I think the code before this patch used to say "Would not remove"
>> and "Not removing" in certain cases to report the paths that the
>> command decided not to remove, but after this patch these two
>> messages no longer appear in the patch.
>>
>> Is it expected, are we losing information, or...?
>
> I do not think we are losing any information.
> Say, we have a repo like this:
>     test.git
>      |-- untracked_file
>      |-- untracked_bar
>      |     |-- bar.txt
>      |-- untracked_foo
>            |-- foo.txt
>
> The original version prints out:
>   $ git clean -fn
>   Would remove untracked_file
>   Would not remove untracked_bar/
>   Would not remove untracked_foo/
>
> We never asked for any directories to be removed so IMHO the "Would
> not remove ..." messages are just noise.
>
> The new version prints out:
>   $ git clean -fn
>   Would remove untracked_file

Oh.  I was blinded by the primary reason of your patch being "be
more careful and defer reporting a removal until we know everything
in a directory did get removed and managed to remove the directory",
and did not realize this "noise removal".

Perhaps add

	Also do not mention that we are not removing directories
	when the user did not ask us to do so with '-d'.

or something to the description?

Thanks for a clarification.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-01-10 17:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-06 23:16 [PATCH v4] git-clean: Display more accurate delete messages Zoltan Klinger
2013-01-06 23:40 ` Jonathan Nieder
2013-01-10  1:01   ` Zoltan Klinger
2013-01-10  2:56 ` Junio C Hamano
2013-01-10 10:41   ` Zoltan Klinger
2013-01-10 17:45     ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).