Git development
 help / color / mirror / Atom feed
* Re: [PATCH 3/3] match_basename: use strncmp instead of strcmp
From: Fredrik Gustafsson @ 2013-03-09  8:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nguyễn Thái Ngọc Duy, git
In-Reply-To: <7v4nglf1w3.fsf@alter.siamese.dyndns.org>

On Fri, Mar 08, 2013 at 11:50:04PM -0800, Junio C Hamano wrote:
> At the same time, I wonder if we can take advantage of the fact that
> these call sites only care about equality and not ordering.

I did an RFC-patch for that (that I mistakenly didn't sent as a reply to
this e-mail). And I believe that you're correct. My solution is inspired
of curl's strequal.

Is the reason for git not to care about lower/upper-case for beeing able
to support windows? Or is there any other smart reason?

I was also thinking about discarding files by looking at their
modification date. If the modification timestamp is older than/or equal to
the latest commit, there's probably no reason for examine that file any
further. I'm not sure about the side effects this may imply though. I
think they can be quite nasty. Is this something worth digging more in
or am I already on the wrong path?

-- 
Med vänliga hälsningar
Fredrik Gustafsson

tel: 0733-608274
e-post: iveqy@iveqy.com

^ permalink raw reply

* [PATCH] Replace strcmp_icase with strequal_icase
From: Fredrik Gustafsson @ 2013-03-09  8:42 UTC (permalink / raw)
  To: gitster; +Cc: git, iveqy, pclouds

To improve performance.
git status before:
user    0m0.020s
user    0m0.024s
user    0m0.024s
user    0m0.020s
user    0m0.024s
user    0m0.028s
user    0m0.024s
user    0m0.024s
user    0m0.016s
user    0m0.028s

git status after:
user    0m0.012s
user    0m0.008s
user    0m0.008s
user    0m0.008s
user    0m0.008s
user    0m0.008s
user    0m0.008s
user    0m0.004s
user    0m0.008s
user    0m0.016s

Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
---
 dir.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/dir.c b/dir.c
index 57394e4..2b801e8 100644
--- a/dir.c
+++ b/dir.c
@@ -37,6 +37,17 @@ int fnmatch_icase(const char *pattern, const char *string, int flags)
 	return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
 }
 
+int strequal_icase(const char *first, const char *second)
+{
+	while (*first && *second) {
+		if( toupper(*first) != toupper(*second))
+			break;
+		first++;
+		second++;
+	}
+	return toupper(*first) == toupper(*second);
+}
+
 inline int git_fnmatch(const char *pattern, const char *string,
 		       int flags, int prefix)
 {
@@ -626,11 +637,11 @@ int match_basename(const char *basename, int basenamelen,
 		   int flags)
 {
 	if (prefix == patternlen) {
-		if (!strcmp_icase(pattern, basename))
+		if (!strequal_icase(pattern, basename))
 			return 1;
 	} else if (flags & EXC_FLAG_ENDSWITH) {
 		if (patternlen - 1 <= basenamelen &&
-		    !strcmp_icase(pattern + 1,
+		    !strequal_icase(pattern + 1,
 				  basename + basenamelen - patternlen + 1))
 			return 1;
 	} else {
@@ -663,7 +674,7 @@ int match_pathname(const char *pathname, int pathlen,
 	 */
 	if (pathlen < baselen + 1 ||
 	    (baselen && pathname[baselen] != '/') ||
-	    strncmp_icase(pathname, base, baselen))
+	    strequal_icase(pathname, base))
 		return 0;
 
 	namelen = baselen ? pathlen - baselen - 1 : pathlen;
-- 
1.8.1.5

^ permalink raw reply related

* [PATCH v2 2/2] git add: -u/-A now affects the entire working tree
From: Junio C Hamano @ 2013-03-09  8:23 UTC (permalink / raw)
  To: git
In-Reply-To: <1362817391-24452-1-git-send-email-gitster@pobox.com>

As promised in 0fa2eb530fb7 (add: warn when -u or -A is used without
pathspec, 2013-01-28), in Git 2.0, "git add -u/-A" that is run
without pathspec in a subdirectory updates all updated paths in the
entire working tree, not just the current directory and its
subdirectories.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-add.txt | 24 ++++++++----------------
 builtin/add.c             | 47 ++++-------------------------------------------
 2 files changed, 12 insertions(+), 59 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index b849b78..02b99cb 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -104,14 +104,10 @@ apply to the index. See EDITING PATCHES below.
 	<pathspec>.  This removes as well as modifies index entries to
 	match the working tree, but adds no new files.
 +
-If no <pathspec> is given when `-u` option is used, Git used
-to update all tracked files in the current directory and its
-subdirectories. We would eventually want to change this to operate
-on the entire working tree, not limiting it to the current
-directory, to make it consistent with `git commit -a` and other
-commands.  In order to avoid harming users who are used to the old
-default, Git *errors out* when no <pathspec> is given to train their
-fingers to explicitly type `git add -u .` when they mean it.
+If no <pathspec> is given when `-u` option is used, all
+tracked files in the entire working tree are updated (old versions
+of Git used to limit the update to the current directory and its
+subdirectories).
 
 -A::
 --all::
@@ -120,14 +116,10 @@ fingers to explicitly type `git add -u .` when they mean it.
 	entry.	This adds, modifies, and removes index entries to
 	match the working tree.
 +
-If no <pathspec> is given when `-A` option is used, Git used
-to update all files in the current directory and its
-subdirectories. We would eventually want to change this to operate
-on the entire working tree, not limiting it to the current
-directory, to make it consistent with `git commit -a` and other
-commands.  In order to avoid harming users who are used to the old
-default, Git *errors out* when no <pathspec> is given to train their
-fingers to explicitly type `git add -A .` when they mean it.
+If no <pathspec> is given when `-A` option is used, all
+files in the entire working tree are updated (old versions
+of Git used to limit the update to the current directory and its
+subdirectories).
 
 -N::
 --intent-to-add::
diff --git a/builtin/add.c b/builtin/add.c
index 4b9d57c..6cd063f 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -321,33 +321,6 @@ static int add_files(struct dir_struct *dir, int flags)
 	return exit_status;
 }
 
-static void die_on_pathless_add(const char *option_name, const char *short_name)
-{
-	/*
-	 * To be consistent with "git add -p" and most Git
-	 * commands, we should default to being tree-wide, but
-	 * this is not the original behavior and can't be
-	 * changed until users trained themselves not to type
-	 * "git add -u" or "git add -A". In the previous release,
-	 * we kept the old behavior but gave a big warning.
-	 */
-	die(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
-	      "subdirectory of the tree will change in Git 2.0 and should not be "
-	      "used anymore.\n"
-	      "To add content for the whole tree, run:\n"
-	      "\n"
-	      "  git add %s :/\n"
-	      "  (or git add %s :/)\n"
-	      "\n"
-	      "To restrict the command to the current directory, run:\n"
-	      "\n"
-	      "  git add %s .\n"
-	      "  (or git add %s .)"),
-		option_name, short_name,
-		option_name, short_name,
-		option_name, short_name);
-}
-
 int cmd_add(int argc, const char **argv, const char *prefix)
 {
 	int exit_status = 0;
@@ -358,8 +331,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	int add_new_files;
 	int require_pathspec;
 	char *seen = NULL;
-	const char *option_with_implicit_dot = NULL;
-	const char *short_option_with_implicit_dot = NULL;
 
 	git_config(add_config, NULL);
 
@@ -379,21 +350,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		die(_("-A and -u are mutually incompatible"));
 	if (!show_only && ignore_missing)
 		die(_("Option --ignore-missing can only be used together with --dry-run"));
-	if (addremove) {
-		option_with_implicit_dot = "--all";
-		short_option_with_implicit_dot = "-A";
-	}
-	if (take_worktree_changes) {
-		option_with_implicit_dot = "--update";
-		short_option_with_implicit_dot = "-u";
-	}
-	if (option_with_implicit_dot && !argc) {
-		static const char *here[2] = { ".", NULL };
-		if (prefix)
-			die_on_pathless_add(option_with_implicit_dot,
-					    short_option_with_implicit_dot);
+
+	if ((addremove || take_worktree_changes) && !argc) {
+		static const char *whole[2] = { ":/", NULL };
 		argc = 1;
-		argv = here;
+		argv = whole;
 	}
 
 	add_new_files = !take_worktree_changes && !refresh_only;
-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply related

* [PATCH v2 1/2] require pathspec for "git add -u/-A"
From: Junio C Hamano @ 2013-03-09  8:23 UTC (permalink / raw)
  To: git
In-Reply-To: <1362817391-24452-1-git-send-email-gitster@pobox.com>

As promised in 0fa2eb530fb7 (add: warn when -u or -A is used without
pathspec, 2013-01-28), "git add -u/-A" that is run without pathspec
in a subdirectory will stop working sometime before Git 2.0, to wean
users off of the old default, in preparation for adopting the new
default in Git 2.0.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-add.txt | 24 ++++++++++++++++--------
 builtin/add.c             | 38 ++++++++++++++++++--------------------
 2 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index b0944e5..b849b78 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -104,10 +104,14 @@ apply to the index. See EDITING PATCHES below.
 	<pathspec>.  This removes as well as modifies index entries to
 	match the working tree, but adds no new files.
 +
-If no <pathspec> is given, the current version of Git defaults to
-"."; in other words, update all tracked files in the current directory
-and its subdirectories. This default will change in a future version
-of Git, hence the form without <pathspec> should not be used.
+If no <pathspec> is given when `-u` option is used, Git used
+to update all tracked files in the current directory and its
+subdirectories. We would eventually want to change this to operate
+on the entire working tree, not limiting it to the current
+directory, to make it consistent with `git commit -a` and other
+commands.  In order to avoid harming users who are used to the old
+default, Git *errors out* when no <pathspec> is given to train their
+fingers to explicitly type `git add -u .` when they mean it.
 
 -A::
 --all::
@@ -116,10 +120,14 @@ of Git, hence the form without <pathspec> should not be used.
 	entry.	This adds, modifies, and removes index entries to
 	match the working tree.
 +
-If no <pathspec> is given, the current version of Git defaults to
-"."; in other words, update all files in the current directory
-and its subdirectories. This default will change in a future version
-of Git, hence the form without <pathspec> should not be used.
+If no <pathspec> is given when `-A` option is used, Git used
+to update all files in the current directory and its
+subdirectories. We would eventually want to change this to operate
+on the entire working tree, not limiting it to the current
+directory, to make it consistent with `git commit -a` and other
+commands.  In order to avoid harming users who are used to the old
+default, Git *errors out* when no <pathspec> is given to train their
+fingers to explicitly type `git add -A .` when they mean it.
 
 -N::
 --intent-to-add::
diff --git a/builtin/add.c b/builtin/add.c
index 0dd014e..4b9d57c 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -321,30 +321,28 @@ static int add_files(struct dir_struct *dir, int flags)
 	return exit_status;
 }
 
-static void warn_pathless_add(const char *option_name, const char *short_name) {
+static void die_on_pathless_add(const char *option_name, const char *short_name)
+{
 	/*
 	 * To be consistent with "git add -p" and most Git
 	 * commands, we should default to being tree-wide, but
 	 * this is not the original behavior and can't be
 	 * changed until users trained themselves not to type
-	 * "git add -u" or "git add -A". For now, we warn and
-	 * keep the old behavior. Later, this warning can be
-	 * turned into a die(...), and eventually we may
-	 * reallow the command with a new behavior.
+	 * "git add -u" or "git add -A". In the previous release,
+	 * we kept the old behavior but gave a big warning.
 	 */
-	warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
-		  "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
-		  "To add content for the whole tree, run:\n"
-		  "\n"
-		  "  git add %s :/\n"
-		  "  (or git add %s :/)\n"
-		  "\n"
-		  "To restrict the command to the current directory, run:\n"
-		  "\n"
-		  "  git add %s .\n"
-		  "  (or git add %s .)\n"
-		  "\n"
-		  "With the current Git version, the command is restricted to the current directory."),
+	die(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
+	      "subdirectory of the tree will change in Git 2.0 and should not be "
+	      "used anymore.\n"
+	      "To add content for the whole tree, run:\n"
+	      "\n"
+	      "  git add %s :/\n"
+	      "  (or git add %s :/)\n"
+	      "\n"
+	      "To restrict the command to the current directory, run:\n"
+	      "\n"
+	      "  git add %s .\n"
+	      "  (or git add %s .)"),
 		option_name, short_name,
 		option_name, short_name,
 		option_name, short_name);
@@ -392,8 +390,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	if (option_with_implicit_dot && !argc) {
 		static const char *here[2] = { ".", NULL };
 		if (prefix)
-			warn_pathless_add(option_with_implicit_dot,
-					  short_option_with_implicit_dot);
+			die_on_pathless_add(option_with_implicit_dot,
+					    short_option_with_implicit_dot);
 		argc = 1;
 		argv = here;
 	}
-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply related

* [PATCH v2 0/2] "git add -u/-A" from future
From: Junio C Hamano @ 2013-03-09  8:23 UTC (permalink / raw)
  To: git

Here are two future steps to update the behaviour of "add -u/-A" run
without pathspec towards Git 2.0; the first step may probably be
optional, but it is included for completeness.

Rebased on top of the recent "git add -u/-A" documentation updates
5cae93566027 (add: Clarify documentation of -A and -u, 2013-03-07)
by Greg Price.

Junio C Hamano (2):
  require pathspec for "git add -u/-A"
  git add: -u/-A now affects the entire working tree

 Documentation/git-add.txt | 16 ++++++++--------
 builtin/add.c             | 49 ++++-------------------------------------------
 2 files changed, 12 insertions(+), 53 deletions(-)

-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply

* [PATCH 3/3] git add <pathspec>... defaults to "-A"
From: Junio C Hamano @ 2013-03-09  8:22 UTC (permalink / raw)
  To: git
In-Reply-To: <1362817358-24356-1-git-send-email-gitster@pobox.com>

Make "git add <pathspec>..." notice paths that have been removed
from the working tree, i.e. a synonym to "git add -A <pathspec>...".

Given that "git add <pathspec>" is to update the index with the
state of the named part of the working tree as a whole, it makes it
more intuitive, and also makes it possible to simplify the advice we
give while marking the paths the user finished resolving conflicts
with.  We used to say "to record removal as a resolution, remove the
path from the working tree and say 'git rm'; for all other cases,
edit the path in the working tree and say 'git add'", but we can now
say "update the path in the working tree and say 'git add'" instead.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-add.txt | 18 +++++++++++-------
 builtin/add.c             | 33 +++------------------------------
 2 files changed, 14 insertions(+), 37 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 5c501a2..e96fa84 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -53,8 +53,14 @@ OPTIONS
 	Files to add content from.  Fileglobs (e.g. `*.c`) can
 	be given to add all matching files.  Also a
 	leading directory name (e.g. `dir` to add `dir/file1`
-	and `dir/file2`) can be given to add all files in the
-	directory, recursively.
+	and `dir/file2`) can be given to update the index to
+	match the current state of the directory as a whole (e.g.
+	specifying `dir` will record not just a file `dir/file1`
+	modified in the working tree, a file `dir/file2` added to
+	the working tree, but also a file `dir/file3` removed from
+	the working tree.  Note that older versions of 	Git used
+	to ignore removed files; use `--no-all` option if you want
+	to add modified or new files but ignore removed	ones.
 
 -n::
 --dry-run::
@@ -127,11 +133,9 @@ of Git, hence the form without <pathspec> should not be used.
 	files that have been removed from the working tree.  This
 	option is a no-op when no <pathspec> is used.
 +
-This option is primarily to help the current users of Git, whose
-"git add <pathspec>..." ignores removed files.  In future versions
-of Git, "git add <pathspec>..." will be a synonym to "git add -A
-<pathspec>..." and "git add --no-all <pathspec>..." will behave like
-today's "git add <pathspec>...", ignoring removed files.
+This option is primarily to help users who are used to older
+versions of Git, whose "git add <pathspec>..." was a synonym
+to "git add --no-all <pathspec...", i.e. ignored removed files.
 
 -N::
 --intent-to-add::
diff --git a/builtin/add.c b/builtin/add.c
index f8f6c9e..21c685f 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -273,7 +273,7 @@ N_("The following paths are ignored by one of your .gitignore files:\n");
 static int verbose, show_only, ignored_too, refresh_only;
 static int ignore_add_errors, intent_to_add, ignore_missing;
 
-#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
+#define ADDREMOVE_DEFAULT 1
 static int addremove = ADDREMOVE_DEFAULT;
 static int addremove_explicit = -1; /* unspecified */
 
@@ -354,18 +354,6 @@ static void warn_pathless_add(const char *option_name, const char *short_name) {
 		option_name, short_name);
 }
 
-static int directory_given(int argc, const char **argv)
-{
-	struct stat st;
-
-	while (argc--) {
-		if (!lstat(*argv, &st) && S_ISDIR(st.st_mode))
-			return 1;
-		argv++;
-	}
-	return 0;
-}
-
 int cmd_add(int argc, const char **argv, const char *prefix)
 {
 	int exit_status = 0;
@@ -401,24 +389,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	if (addremove && take_worktree_changes)
 		die(_("-A and -u are mutually incompatible"));
 
-	/*
-	 * Warn when "git add pathspec..." was given without "-u" or "-A"
-	 * and pathspec... contains a directory name.
-	 */
-	if (!take_worktree_changes && addremove_explicit < 0 &&
-	    directory_given(argc, argv))
-		warning(_("In Git 2.0, 'git add <pathspec>...' will also update the\n"
-			  "index for paths removed from the working tree that match\n"
-			  "the given pathspec. If you want to 'add' only changed\n"
-			  "or newly created paths, say 'git add --no-all <pathspec>...'"
-			  " instead."));
-
 	if (!take_worktree_changes && addremove_explicit < 0 && argc)
-		/*
-		 * Turn "git add pathspec..." to "git add -A pathspec..."
-		 * in Git 2.0 but not yet
-		 */
-		; /* addremove = 1; */
+		/* Turn "git add pathspec..." to "git add -A pathspec..." */
+		addremove = 1;
 
 	if (!show_only && ignore_missing)
 		die(_("Option --ignore-missing can only be used together with --dry-run"));
-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply related

* [PATCH 2/3] git add: start preparing for "git add <pathspec>..." to default to "-A"
From: Junio C Hamano @ 2013-03-09  8:22 UTC (permalink / raw)
  To: git
In-Reply-To: <1362817358-24356-1-git-send-email-gitster@pobox.com>

When "git add subdir/" is run without "-u" or "-A" option, e.g.

    $ edit subdir/x
    $ create subdir/y
    $ rm subdir/z
    $ git add subdir/

the command does not notice removal of paths (e.g. subdir/z) from
the working tree.  This sometimes confuses new people, as arguably
"git add" is told to record the current state of "subdir/" as a
whole, not the current state of the paths that exist in the working
tree that matches that pathspec (the latter by definition excludes
the state of "subdir/z" because it does not exist in the working
tree).

Plan to eventually make "git add" pretend as if "-A" is given when
there is a pathspec on the command line.  When resolving a conflict
to remove a path, the current code tells you to "git rm $path", but
with such a change, you will be able to say "git add $path" (of
course you can do "git add -A $path" today).  That means that we can
simplify the advice messages given by "git status".  That all will
be in Git 2.0 or later, if we are going to do so.

For that transition to work, people need to learn either to say "git
add --no-all subdir/" when they want to ignore the removed paths
like "subdir/z", or to say "git add -A subdir/" when they want to
take the state of the directory as a whole.

"git add" without any argument will continue to be a no-op.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-add.txt | 14 +++++++++++++-
 builtin/add.c             | 45 +++++++++++++++++++++++++++++++++++++++++++--
 t/t2200-add-update.sh     |  6 +++---
 3 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index b0944e5..5c501a2 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]
-	  [--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N]
+	  [--edit | -e] [--[no-]all | [--update | -u]] [--intent-to-add | -N]
 	  [--refresh] [--ignore-errors] [--ignore-missing] [--]
 	  [<pathspec>...]
 
@@ -121,6 +121,18 @@ If no <pathspec> is given, the current version of Git defaults to
 and its subdirectories. This default will change in a future version
 of Git, hence the form without <pathspec> should not be used.
 
+--no-all::
+	Update the index by adding new files that are unknown to the
+	index and files modified in the working tree, but ignore
+	files that have been removed from the working tree.  This
+	option is a no-op when no <pathspec> is used.
++
+This option is primarily to help the current users of Git, whose
+"git add <pathspec>..." ignores removed files.  In future versions
+of Git, "git add <pathspec>..." will be a synonym to "git add -A
+<pathspec>..." and "git add --no-all <pathspec>..." will behave like
+today's "git add <pathspec>...", ignoring removed files.
+
 -N::
 --intent-to-add::
 	Record only the fact that the path will be added later. An entry
diff --git a/builtin/add.c b/builtin/add.c
index 220321b..f8f6c9e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -271,7 +271,11 @@ static const char ignore_error[] =
 N_("The following paths are ignored by one of your .gitignore files:\n");
 
 static int verbose, show_only, ignored_too, refresh_only;
-static int ignore_add_errors, addremove, intent_to_add, ignore_missing;
+static int ignore_add_errors, intent_to_add, ignore_missing;
+
+#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
+static int addremove = ADDREMOVE_DEFAULT;
+static int addremove_explicit = -1; /* unspecified */
 
 static struct option builtin_add_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
@@ -283,7 +287,7 @@ static struct option builtin_add_options[] = {
 	OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
 	OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
 	OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
-	OPT_BOOL('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
+	OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")),
 	OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
 	OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
 	OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
@@ -350,6 +354,18 @@ static void warn_pathless_add(const char *option_name, const char *short_name) {
 		option_name, short_name);
 }
 
+static int directory_given(int argc, const char **argv)
+{
+	struct stat st;
+
+	while (argc--) {
+		if (!lstat(*argv, &st) && S_ISDIR(st.st_mode))
+			return 1;
+		argv++;
+	}
+	return 0;
+}
+
 int cmd_add(int argc, const char **argv, const char *prefix)
 {
 	int exit_status = 0;
@@ -377,8 +393,33 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	argc--;
 	argv++;
 
+	if (0 <= addremove_explicit)
+		addremove = addremove_explicit;
+	else if (take_worktree_changes && ADDREMOVE_DEFAULT)
+		addremove = 0; /* "-u" was given but not "-A" */
+
 	if (addremove && take_worktree_changes)
 		die(_("-A and -u are mutually incompatible"));
+
+	/*
+	 * Warn when "git add pathspec..." was given without "-u" or "-A"
+	 * and pathspec... contains a directory name.
+	 */
+	if (!take_worktree_changes && addremove_explicit < 0 &&
+	    directory_given(argc, argv))
+		warning(_("In Git 2.0, 'git add <pathspec>...' will also update the\n"
+			  "index for paths removed from the working tree that match\n"
+			  "the given pathspec. If you want to 'add' only changed\n"
+			  "or newly created paths, say 'git add --no-all <pathspec>...'"
+			  " instead."));
+
+	if (!take_worktree_changes && addremove_explicit < 0 && argc)
+		/*
+		 * Turn "git add pathspec..." to "git add -A pathspec..."
+		 * in Git 2.0 but not yet
+		 */
+		; /* addremove = 1; */
+
 	if (!show_only && ignore_missing)
 		die(_("Option --ignore-missing can only be used together with --dry-run"));
 	if (addremove) {
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 4cdebda..32f932a 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -150,9 +150,9 @@ test_expect_success 'add -u resolves unmerged paths' '
 	echo 2 >path3 &&
 	echo 2 >path5 &&
 
-	# Explicit resolving by adding removed paths should fail
-	test_must_fail git add path4 &&
-	test_must_fail git add path6 &&
+	# Fail to explicitly resolve removed paths with "git add"
+	test_must_fail git add --no-all path4 &&
+	test_must_fail git add --no-all path6 &&
 
 	# "add -u" should notice removals no matter what stages
 	# the index entries are in.
-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply related

* [PATCH 1/3] builtin/add.c: simplify boolean variables
From: Junio C Hamano @ 2013-03-09  8:22 UTC (permalink / raw)
  To: git
In-Reply-To: <1362817358-24356-1-git-send-email-gitster@pobox.com>

Do not to explicitly initialize static variables to 0 and instead
let BSS take care of it.  Also use OPT_BOOL() to let the command
line arguments set these variables to 0 or 1, instead of the
deprecated OPT_BOOLEAN() aka OPT_COUNTUP().

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/add.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 0dd014e..220321b 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -270,23 +270,23 @@ static struct lock_file lock_file;
 static const char ignore_error[] =
 N_("The following paths are ignored by one of your .gitignore files:\n");
 
-static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
-static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
+static int verbose, show_only, ignored_too, refresh_only;
+static int ignore_add_errors, addremove, intent_to_add, ignore_missing;
 
 static struct option builtin_add_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__VERBOSE(&verbose, N_("be verbose")),
 	OPT_GROUP(""),
-	OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
-	OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
-	OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
+	OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")),
+	OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")),
+	OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")),
 	OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
-	OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
-	OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
-	OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
-	OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
-	OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
-	OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
+	OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")),
+	OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
+	OPT_BOOL('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
+	OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
+	OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
+	OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
 	OPT_END(),
 };
 
-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply related

* [PATCH 0/3] Make "git add dir/" notice removed "dir/file"
From: Junio C Hamano @ 2013-03-09  8:22 UTC (permalink / raw)
  To: git

This resurrects an ancient stalled topic from last year, rebased on
top of the recent "git add -u/-A" documentation updates 5cae93566027
(add: Clarify documentation of -A and -u, 2013-03-07) by Greg Price.

The first one is a pure clean-up.  The second one is a preparatory
step that can happen before Git 2.0 to prepare existing users to
form a habit of saying "--all" (or "--no-all") explicitly when
giving a directory name to "git add <pathspec>...".

Then the last one can be done in Git 2.0 to swap the default.

Junio C Hamano (3):
  builtin/add.c: simplify boolean variables
  git add: start preparing for "git add <pathspec>..." to default to "-A"
  git add <pathspec>... defaults to "-A"

 Documentation/git-add.txt | 22 +++++++++++++++++++---
 builtin/add.c             | 36 +++++++++++++++++++++++++-----------
 t/t2200-add-update.sh     |  6 +++---
 3 files changed, 47 insertions(+), 17 deletions(-)

-- 
1.8.2-rc3-203-gc9aaab5

^ permalink raw reply

* Re: [PATCH 3/3] match_basename: use strncmp instead of strcmp
From: Junio C Hamano @ 2013-03-09  7:50 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1362802190-7331-4-git-send-email-pclouds@gmail.com>

Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:

> strncmp provides length information, compared to strcmp, which could
> be taken advantage by the implementation. Even better, we could check
> if the lengths are equal before calling strncmp, eliminating a bit of
> strncmp calls.

I think I am a bit slower than my usual self tonight, but I am
utterly confused by the above.

strncmp() compares _only_ up to the first n bytes, so when you are
using it for equality, it is not "we could check length", but is "we
MUST check they match to the length of the shorter string", if you
want to obtain not just faster but correct result.

Am I mistaken?

Even if you are using strcmp() that yields ordering not just
equality, it can return a correct result as soon as it hits the
first bytes that are different; I doubt using strncmp() contributes
to the performance very much.  Comparing lengths before doing
byte-for-byte comparison could help because you can reject two
strings with different lengths without looking at them.

At the same time, I wonder if we can take advantage of the fact that
these call sites only care about equality and not ordering.

^ permalink raw reply

* Re: Ignore pattern with trailing whitespace in .gitignore is void using git 1.8.1.5
From: Junio C Hamano @ 2013-03-09  6:28 UTC (permalink / raw)
  To: Thor Andreas Rognan; +Cc: git
In-Reply-To: <7vehfpf8kk.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Thor Andreas Rognan <thor.rognan@gmail.com> writes:
>
>> Maybe I'm doing it wrong, or maybe it's the intended behaviour,
>> but I find that a trailing whitespace after a pattern in .gitignore
>> makes the pattern void with git 1.8.1.5.
>
> I doubt we do anything clever like that.
> ...
> The user tells to ignore anything followed by a dot followed by a
> lowercase Oh followed by a SP.  We ignore "hello. ", but not "hello.o"
> nor "hello.o  " (two SPs at the end), just as told.

Of course, having said all that, I do not think anybody objects too
deeply against a patch that change the behaviour to ignore trailing
whitespaces, as long as the patch leaves an escape hatch to allow
people who do want to specify a pattern that matches with pathnames
with trailing whitespaces.  Without thinking it through, perhaps

	echo '*.o\ ' >.gitignore

or something?

Technically speaking, such a change is a regression, but I doubt
that many people would mind it too much.

^ permalink raw reply

* Re: [RFC v2] git-multimail: a replacement for post-receive-email
From: Michael Haggerty @ 2013-03-09  5:32 UTC (permalink / raw)
  To: Matthieu Moy
  Cc: git discussion list, Andy Parkins, Sitaram Chamarty,
	Junio C Hamano, Marc Branchaud,
	Ævar Arnfjörð Bjarmason, Chris Hiestand
In-Reply-To: <512B4203.3090802@alum.mit.edu>

On 02/25/2013 11:50 AM, Michael Haggerty wrote:
> On 02/25/2013 10:54 AM, Matthieu Moy wrote:
>> [...] Works for me. One minor knit: you've included 10-characters sha1s (this
>> comes from
>>
>>         self.short = read_output(['git', 'rev-parse', '--short=10', sha1])
>>
>> ), I'd find it better with shorter sha1s. In the case of branch update,
>> if the branch name is a bit long, it could be nice to save a few
>> characters.
>>
>> Why not just say "git rev-parse --short", without argument? This way,
>> the default is used, ie. AFAICT it uses 7 characters by default, but
>> will use more if needed to keep the unicity.
> 
> [...] I guess I will change the code to use $(git rev-parse --short) (i.e.,
> shorter SHA1s) but reserving 10 columns in tables for them (which can be
> done via Python string formatting in the templates).  That should give
> the best of both worlds.

I implemented this change (allow git to choose the SHA1 abbreviation
length) and just pushed it to github.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply

* Re: Ignore pattern with trailing whitespace in .gitignore is void using git 1.8.1.5
From: Junio C Hamano @ 2013-03-09  5:25 UTC (permalink / raw)
  To: Thor Andreas Rognan; +Cc: git
In-Reply-To: <CAMn8hCexsiizsjoXO-ebfpEtZcW7n0dY-jV0q+aLh8U+pbUo9A@mail.gmail.com>

Thor Andreas Rognan <thor.rognan@gmail.com> writes:

> Maybe I'm doing it wrong, or maybe it's the intended behaviour,
> but I find that a trailing whitespace after a pattern in .gitignore
> makes the pattern void with git 1.8.1.5.

I doubt we do anything clever like that.

        $ git init
        $ touch hello.o "hello.o " "hello.o  " hello.c
        $ echo "*.o " >.gitignore
        $ git status | cat -e
        # On branch master$
        #$
        # Initial commit$
        #$
        # Untracked files:$
        #   (use "git add <file>..." to include in what will be committed)$
        #$
        #       .gitignore$
        #       hello.c$
        #       hello.o$
        #       hello.o  $
        nothing added to commit but untracked files present (use "git add" to track)$
        
The user tells to ignore anything followed by a dot followed by a
lowercase Oh followed by a SP.  We ignore "hello. ", but not "hello.o"
nor "hello.o  " (two SPs at the end), just as told.

^ permalink raw reply

* Re: Memory corruption when rebasing with git version 1.8.1.5 on arch
From: Jeff King @ 2013-03-09  4:48 UTC (permalink / raw)
  To: Bernhard Posselt; +Cc: git
In-Reply-To: <513A7D80.5000501@bernhard-posselt.com>

On Sat, Mar 09, 2013 at 01:08:32AM +0100, Bernhard Posselt wrote:

> >The problem is likely happening in a sub-command of git-pull, so
> >valgrind isn't reporting it. Can you try re-running with
> >"valgrind --trace-children=yes", or alternatively narrow down the
> >problematic command by setting GIT_TRACE=1 in the environment?
>
> Heres the output with GIT_TRACE=1, the valgrind log has 4000 lines.
> If you should still require the valgrind log, please tell me.

Hmm, the GIT_TRACE output was less clear than I had hoped; it's unclear
to me which git program is actually dying (my guess is "git apply", and
we are squelching stderr, which is where the GIT_TRACE output is going).

Can you try it once again with something like GIT_TRACE=/tmp/foo.out,
which will make sure we record the trace directly, even if stderr ends
up redirected?

Also, I can almost reproduce here, as PatrickHeller/core.git is public.
However, I suspect the problem is particular to your work built on top,
which looks like it is at commit 0525bbd73c9015499ba92d1ac654b980aaca35b2.
Is it possible for you to make that commit available on a temporary
branch?

-Peff

^ permalink raw reply

* [PATCH 3/3] match_basename: use strncmp instead of strcmp
From: Nguyễn Thái Ngọc Duy @ 2013-03-09  4:09 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1362802190-7331-1-git-send-email-pclouds@gmail.com>

strncmp provides length information, compared to strcmp, which could
be taken advantage by the implementation. Even better, we could check
if the lengths are equal before calling strncmp, eliminating a bit of
strncmp calls.

        before      after
user    0m0.519s    0m0.489s
user    0m0.521s    0m0.504s
user    0m0.523s    0m0.507s
user    0m0.532s    0m0.510s
user    0m0.534s    0m0.513s
user    0m0.536s    0m0.514s
user    0m0.537s    0m0.522s
user    0m0.545s    0m0.523s
user    0m0.546s    0m0.527s
user    0m0.548s    0m0.529s

While at there, fix an inconsistency about pattern/patternlen in how
attr handles EXC_FLAG_MUSTBEDIR. When parse_exclude_pattern detects
this flag, it sets patternlen _not_ to include the trailing slash and
expects the caller to trim it. add_exclude does, parse_attr_line does
not.

In attr.c, the pattern could be "foo/" while patternlen tells us it
only has 3 chars. Some functions do not care about patternlen and will
see the pattern as "foo/" while others may see it as "foo". This patch
makes patternlen 4 in this case. (Although for a piece of mind,
perhaps we should trim it to "foo" like exclude, and never pass a
pathname like "abc/" to match_{base,path}name)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 attr.c | 2 ++
 dir.c  | 8 +++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/attr.c b/attr.c
index e2f9377..1818ba5 100644
--- a/attr.c
+++ b/attr.c
@@ -255,6 +255,8 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
 				      &res->u.pat.patternlen,
 				      &res->u.pat.flags,
 				      &res->u.pat.nowildcardlen);
+		if (res->u.pat.flags & EXC_FLAG_MUSTBEDIR)
+			res->u.pat.patternlen++;
 		if (res->u.pat.flags & EXC_FLAG_NEGATIVE) {
 			warning(_("Negative patterns are ignored in git attributes\n"
 				  "Use '\\!' for literal leading exclamation."));
diff --git a/dir.c b/dir.c
index f58320d..2a91d14 100644
--- a/dir.c
+++ b/dir.c
@@ -610,12 +610,14 @@ int match_basename(const char *basename, int basenamelen,
 		   int flags)
 {
 	if (prefix == patternlen) {
-		if (!strcmp_icase(pattern, basename))
+		if (patternlen == basenamelen &&
+		    !strncmp_icase(pattern, basename, patternlen))
 			return 1;
 	} else if (flags & EXC_FLAG_ENDSWITH) {
 		if (patternlen - 1 <= basenamelen &&
-		    !strcmp_icase(pattern + 1,
-				  basename + basenamelen - patternlen + 1))
+		    !strncmp_icase(pattern + 1,
+				   basename + basenamelen - patternlen + 1,
+				   patternlen - 1))
 			return 1;
 	} else {
 		if (fnmatch_icase(pattern, basename, 0) == 0)
-- 
1.8.1.2.536.gf441e6d

^ permalink raw reply related

* [PATCH 2/3] dir.c: inline convenient *_icase helpers
From: Nguyễn Thái Ngọc Duy @ 2013-03-09  4:09 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1362802190-7331-1-git-send-email-pclouds@gmail.com>

Like the previous patch, this cuts down the number of str*cmp calls in
read_directory (which does _a lot_). Again sorted results on webkit.git:

        before      after
user    0m0.546s    0m0.519s
user    0m0.549s    0m0.521s
user    0m0.550s    0m0.523s
user    0m0.558s    0m0.532s
user    0m0.560s    0m0.534s
user    0m0.561s    0m0.536s
user    0m0.562s    0m0.537s
user    0m0.566s    0m0.545s
user    0m0.568s    0m0.546s
user    0m0.573s    0m0.548s

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 dir.c | 16 ----------------
 dir.h | 18 +++++++++++++++---
 2 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/dir.c b/dir.c
index 669cf80..f58320d 100644
--- a/dir.c
+++ b/dir.c
@@ -21,22 +21,6 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, in
 	int check_only, const struct path_simplify *simplify);
 static int get_dtype(struct dirent *de, const char *path, int len);
 
-/* helper string functions with support for the ignore_case flag */
-int strcmp_icase(const char *a, const char *b)
-{
-	return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
-}
-
-int strncmp_icase(const char *a, const char *b, size_t count)
-{
-	return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
-}
-
-int fnmatch_icase(const char *pattern, const char *string, int flags)
-{
-	return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
-}
-
 inline int git_fnmatch(const char *pattern, const char *string,
 		       int flags, int prefix)
 {
diff --git a/dir.h b/dir.h
index c3eb4b5..560ade4 100644
--- a/dir.h
+++ b/dir.h
@@ -200,9 +200,21 @@ extern int remove_dir_recursively(struct strbuf *path, int flag);
 /* tries to remove the path with empty directories along it, ignores ENOENT */
 extern int remove_path(const char *path);
 
-extern int strcmp_icase(const char *a, const char *b);
-extern int strncmp_icase(const char *a, const char *b, size_t count);
-extern int fnmatch_icase(const char *pattern, const char *string, int flags);
+/* helper string functions with support for the ignore_case flag */
+static inline int strcmp_icase(const char *a, const char *b)
+{
+	return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
+}
+
+static inline int strncmp_icase(const char *a, const char *b, size_t count)
+{
+	return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
+}
+
+static inline int fnmatch_icase(const char *pattern, const char *string, int flags)
+{
+	return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
+}
 
 /*
  * The prefix part of pattern must not contains wildcards.
-- 
1.8.1.2.536.gf441e6d

^ permalink raw reply related

* [PATCH 0/3] Trivial (and small) exclude optimizations
From: Nguyễn Thái Ngọc Duy @ 2013-03-09  4:09 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

I've been examining how and where str*cmp are called by
read_directory(). They are presumably where most of the time is spent.
The gain is not big, but still worth it, I think.

These are tested without nd/read-directory-recursive-optim. The saving
is probably smaller as nd/read... cuts down a big number of entries to
be processed by exclude machinery.

There is another optimization window, which a simple hack suggests it
may shave 100ms out of 500ms ls-files time on my machine. Say you have
"/INSTALL" in your root .gitignore. The pattern will be tested for
_all_ pathnames including "path/deep/down/here". By limiting the
pattern to pathnames of the same directory level, the number of
applicable pathnames to the pattern will be usually small and limited
(otherwise as the repository grows with more pathnames, we pay more
for exclude). Haven't figured out how to save directory level yet
though.

Nguyễn Thái Ngọc Duy (3):
  match_pathname: avoid calling strncmp if baselen is 0
  dir.c: inline convenient *_icase helpers
  match_basename: use strncmp instead of strcmp

 attr.c |  2 ++
 dir.c  | 26 ++++++--------------------
 dir.h  | 18 +++++++++++++++---
 3 files changed, 23 insertions(+), 23 deletions(-)

-- 
1.8.1.2.536.gf441e6d

^ permalink raw reply

* [PATCH 1/3] match_pathname: avoid calling strncmp if baselen is 0
From: Nguyễn Thái Ngọc Duy @ 2013-03-09  4:09 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1362802190-7331-1-git-send-email-pclouds@gmail.com>

This reduces "git status" user time by a little bit. This is the
sorted results of 10 consecutive runs of "git ls-files
--exclude-standard -o" on webkit.git, compiled with gcc -O2:

        before      after
user    0m0.580s    0m0.546s
user    0m0.581s    0m0.549s
user    0m0.582s    0m0.550s
user    0m0.584s    0m0.558s
user    0m0.586s    0m0.560s
user    0m0.587s    0m0.561s
user    0m0.587s    0m0.562s
user    0m0.593s    0m0.566s
user    0m0.597s    0m0.568s
user    0m0.601s    0m0.573s

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index 57394e4..669cf80 100644
--- a/dir.c
+++ b/dir.c
@@ -663,7 +663,7 @@ int match_pathname(const char *pathname, int pathlen,
 	 */
 	if (pathlen < baselen + 1 ||
 	    (baselen && pathname[baselen] != '/') ||
-	    strncmp_icase(pathname, base, baselen))
+	    (baselen && strncmp_icase(pathname, base, baselen)))
 		return 0;
 
 	namelen = baselen ? pathlen - baselen - 1 : pathlen;
-- 
1.8.1.2.536.gf441e6d

^ permalink raw reply related

* Ignore pattern with trailing whitespace in .gitignore is void using git 1.8.1.5
From: Thor Andreas Rognan @ 2013-03-09  1:36 UTC (permalink / raw)
  To: git
In-Reply-To: <CAMn8hCd6_V2Kq_OUgBFAoOkqqmrTpN_ohcP3wM44qWvQB_8R5g@mail.gmail.com>

Hi guys,

Maybe I'm doing it wrong, or maybe it's the intended behaviour,
but I find that a trailing whitespace after a pattern in .gitignore
makes the pattern void with git 1.8.1.5.

It's a subtle error to make, although cleaning undesired commits
from the git history can be educational and fun in itself.

How to reproduce:

$ > mkdir -p ~/tmp/git-ignore-test/ \
&& cd ~/tmp/git-ignore-test/ \
&& touch .gitignore .secret-passwords .secret-passwords.swp \
&& echo ".*.sw? " > .gitignore \
&& echo ".secret-passwords" >> .gitignore \
&& git init && git status

Remove the white space after ``` .*.sw?``` in .gitignore
to see the .swp file disappear:

$ > echo -e ".*.sw?\n.secret-passwords" > .gitignore > .gitignore \
&& git status

You will of course have to temporarily disable your
global .gitignore file if you handle vim swap files correctly there.

I am using git 1.8.1.5 installed with homebrew on os x 10.8.2.

^ permalink raw reply

* Re: Memory corruption when rebasing with git version 1.8.1.5 on arch
From: Bernhard Posselt @ 2013-03-09  0:08 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20130308212831.GA9217@sigill.intra.peff.net>

On 03/08/2013 10:28 PM, Jeff King wrote:
> On Fri, Mar 08, 2013 at 01:19:57PM +0100, Bernhard Posselt wrote:
>
>> Using valgrind gives me:
>>
>> $ valgrind /usr/bin/git pull --rebasehttps://github.com/PatrickHeller/core.git  master
>> ==5995== Memcheck, a memory error detector
>> ==5995== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
>> ==5995== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
>> ==5995== Command: /usr/bin/git pull --rebasehttps://github.com/PatrickHeller/core.git  master
>> ==5995==
>> remote: Counting objects: 5, done.
>> remote: Compressing objects: 100% (1/1), done.
>> remote: Total 3 (delta 2), reused 3 (delta 2)
>> Unpacking objects: 100% (3/3), done.
>>   Fromhttps://github.com/PatrickHeller/core
>>    * branch            master     -> FETCH_HEAD
>> First, rewinding head to replay your work on top of it...
>> Applying: distinguish between touch and write
>> Applying: remove debug output
>> *** Error in `git': malloc(): memory corruption: 0x00000000027f14e0 ***
> The problem is likely happening in a sub-command of git-pull, so
> valgrind isn't reporting it. Can you try re-running with
> "valgrind --trace-children=yes", or alternatively narrow down the
> problematic command by setting GIT_TRACE=1 in the environment?
>
> -Peff
Thanks for the reply!

Heres the output with GIT_TRACE=1, the valgrind log has 4000 lines. If 
you should still require the valgrind log, please tell me.

$ git pull --rebase https://github.com/PatrickHeller/core.git master
trace: exec: 'git-pull' '--rebase' 
'https://github.com/PatrickHeller/core.git' 'master'
trace: run_command: 'git-pull' '--rebase' 
'https://github.com/PatrickHeller/core.git' 'master'
trace: built-in: git 'rev-parse' '--git-dir'
trace: built-in: git 'rev-parse' '--is-bare-repository'
trace: built-in: git 'rev-parse' '--show-toplevel'
trace: built-in: git 'ls-files' '-u'
trace: built-in: git 'symbolic-ref' '-q' 'HEAD'
trace: built-in: git 'config' '--bool' 'branch.master.rebase'
trace: built-in: git 'config' '--bool' 'pull.rebase'
trace: built-in: git 'rev-parse' '-q' '--verify' 'HEAD'
trace: built-in: git 'rev-parse' '--verify' 'HEAD'
trace: built-in: git 'update-index' '-q' '--ignore-submodules' '--refresh'
trace: built-in: git 'diff-files' '--quiet' '--ignore-submodules'
trace: built-in: git 'diff-index' '--cached' '--quiet' 
'--ignore-submodules' 'HEAD' '--'
trace: built-in: git 'rev-parse' '-q' '--git-dir'
trace: built-in: git 'rev-parse' '-q' '--verify' 
'refs/remotes/https://github.com/PatrickHeller/core.git/master'
trace: built-in: git 'rev-parse' '-q' '--verify' 'HEAD'
trace: built-in: git 'fetch' '--update-head-ok' 
'https://github.com/PatrickHeller/core.git' 'master'
trace: run_command: 'git-remote-https' 
'https://github.com/PatrickHeller/core.git' 
'https://github.com/PatrickHeller/core.git'
trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' 
'--quiet'
trace: run_command: 'fetch-pack' '--stateless-rpc' '--stdin' 
'--lock-pack' '--thin' 'https://github.com/PatrickHeller/core.git/'
trace: exec: 'git' 'fetch-pack' '--stateless-rpc' '--stdin' 
'--lock-pack' '--thin' 'https://github.com/PatrickHeller/core.git/'
trace: built-in: git 'fetch-pack' '--stateless-rpc' '--stdin' 
'--lock-pack' '--thin' 'https://github.com/PatrickHeller/core.git/'
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 2), reused 3 (delta 2)
trace: run_command: 'unpack-objects' '--pack_header=2,3'
trace: exec: 'git' 'unpack-objects' '--pack_header=2,3'
trace: built-in: git 'unpack-objects' '--pack_header=2,3'
Unpacking objects: 100% (3/3), done.
trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all'
trace: exec: 'git' 'rev-list' '--objects' '--stdin' '--not' '--all'
trace: built-in: git 'rev-list' '--objects' '--stdin' '--not' '--all'
 From https://github.com/PatrickHeller/core
  * branch            master     -> FETCH_HEAD
trace: built-in: git 'rev-parse' '-q' '--verify' 'HEAD'
trace: built-in: git 'show-branch' '--merge-base' 'refs/heads/master' 
'd686039828089d53fb42e42046d7a9a3992a0507'
trace: built-in: git 'fmt-merge-msg'
trace: built-in: git 'rev-parse' '--parseopt' '--' '--onto' 
'd686039828089d53fb42e42046d7a9a3992a0507' 
'd686039828089d53fb42e42046d7a9a3992a0507'
trace: built-in: git 'rev-parse' '--git-dir'
trace: built-in: git 'rev-parse' '--is-bare-repository'
trace: built-in: git 'rev-parse' '--show-toplevel'
trace: built-in: git 'config' '--bool' 'rebase.stat'
trace: built-in: git 'config' '--bool' 'rebase.autosquash'
trace: built-in: git 'rev-parse' '--verify' 
'd686039828089d53fb42e42046d7a9a3992a0507^0'
trace: built-in: git 'rev-parse' '--verify' 
'd686039828089d53fb42e42046d7a9a3992a0507^0'
trace: built-in: git 'symbolic-ref' '-q' 'HEAD'
trace: built-in: git 'rev-parse' '--verify' 'master^0'
trace: built-in: git 'rev-parse' '--verify' 'HEAD'
trace: built-in: git 'update-index' '-q' '--ignore-submodules' '--refresh'
trace: built-in: git 'diff-files' '--quiet' '--ignore-submodules'
trace: built-in: git 'diff-index' '--cached' '--quiet' 
'--ignore-submodules' 'HEAD' '--'
trace: built-in: git 'merge-base' 
'd686039828089d53fb42e42046d7a9a3992a0507' 
'0525bbd73c9015499ba92d1ac654b980aaca35b2'
First, rewinding head to replay your work on top of it...
trace: built-in: git 'checkout' '-q' 
'd686039828089d53fb42e42046d7a9a3992a0507^0'
trace: built-in: git 'update-ref' 'ORIG_HEAD' 
'0525bbd73c9015499ba92d1ac654b980aaca35b2'
trace: exec: 'git-am' '--rebasing' '--resolvemsg=
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase 
--abort".
'
trace: run_command: 'git-am' '--rebasing' '--resolvemsg=
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase 
--abort".
'
trace: built-in: git 'format-patch' '-k' '--stdout' '--full-index' 
'--ignore-if-in-upstream' '--src-prefix=a/' '--dst-prefix=b/' 
'--no-renames' 
'd686039828089d53fb42e42046d7a9a3992a0507..0525bbd73c9015499ba92d1ac654b980aaca35b2'
trace: built-in: git 'rev-parse' '--parseopt' '--' '--rebasing' 
'--resolvemsg=
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase 
--abort".
'
trace: built-in: git 'rev-parse' '--git-dir'
trace: built-in: git 'rev-parse' '--show-prefix'
trace: built-in: git 'rev-parse' '--show-toplevel'
trace: built-in: git 'var' 'GIT_COMMITTER_IDENT'
trace: built-in: git 'rev-parse' '--verify' '-q' 'HEAD'
trace: built-in: git 'config' '--bool' '--get' 'am.keepcr'
trace: built-in: git 'mailsplit' '-d4' 
'-o/srv/http/owncloud/.git/rebase-apply' '-b' '--'
trace: built-in: git 'update-index' '-q' '--refresh'
trace: built-in: git 'diff-index' '--cached' '--name-only' 'HEAD' '--'
trace: built-in: git 'cat-file' '-t' 
'48bb53030c657e1133da47765c7c778a069af665'
trace: built-in: git 'cat-file' 'commit' 
'48bb53030c657e1133da47765c7c778a069af665'
trace: built-in: git 'config' 'i18n.commitencoding'
trace: built-in: git 'show' '-s' '--pretty=raw' '--encoding=UTF-8' 
'48bb53030c657e1133da47765c7c778a069af665' '--'
trace: built-in: git 'diff-tree' '--root' '--binary' '--full-index' 
'48bb53030c657e1133da47765c7c778a069af665'
Applying: distinguish between touch and write
trace: built-in: git 'write-tree'
trace: built-in: git 'rev-parse' '--verify' '-q' 'HEAD'
trace: built-in: git 'commit-tree' 
'd785d568d8b4649dfdcc01e03d6c8e87b036ea5a' '-p' 
'd686039828089d53fb42e42046d7a9a3992a0507'
trace: built-in: git 'update-ref' '-m' 'pull --rebase 
https://github.com/PatrickHeller/core.git master: distinguish between 
touch and write' 'HEAD' '2726978d8cbd9b0a3367fd3d62b64b4c78438e79'
trace: built-in: git 'cat-file' '-t' 
'45869afa5ac718e11c3d2e3bccdb501a022cfc24'
trace: built-in: git 'cat-file' 'commit' 
'45869afa5ac718e11c3d2e3bccdb501a022cfc24'
trace: built-in: git 'config' 'i18n.commitencoding'
trace: built-in: git 'show' '-s' '--pretty=raw' '--encoding=UTF-8' 
'45869afa5ac718e11c3d2e3bccdb501a022cfc24' '--'
trace: built-in: git 'diff-tree' '--root' '--binary' '--full-index' 
'45869afa5ac718e11c3d2e3bccdb501a022cfc24'
Applying: remove debug output
*** Error in `git': malloc(): memory corruption: 0x000000000139f4e0 ***

^ permalink raw reply

* [PATCH 2/2] git add: -u/-A now affects the entire working tree
From: Junio C Hamano @ 2013-03-08 23:54 UTC (permalink / raw)
  To: git; +Cc: Matthieu Moy, Jeff King
In-Reply-To: <1362786889-28688-1-git-send-email-gitster@pobox.com>

As promised in 0fa2eb530fb7 (add: warn when -u or -A is used without
pathspec, 2013-01-28), in Git 2.0, "git add -u/-A" that is run
without pathspec in a subdirectory updates all updated paths in the
entire working tree, not just the current directory and its
subdirectories.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-add.txt | 12 ++++--------
 builtin/add.c             | 47 ++++-------------------------------------------
 2 files changed, 8 insertions(+), 51 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 1ea1d39..15a8859 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -107,14 +107,10 @@ apply to the index. See EDITING PATCHES below.
 	from the index if the corresponding files in the working tree
 	have been removed.
 +
-If no <pathspec> is given when `-u` or `-A` option is used, Git used
-to update all tracked files in the current directory and its
-subdirectories. We would eventually want to change this to operate
-on the entire working tree, not limiting it to the current
-directory, to make it consistent with `git commit -a` and other
-commands.  In order to avoid harming users who are used to the old
-default, Git *errors out* when no <pathspec> is given to train their
-fingers to explicitly type `git add -u .` when they mean it.
+If no <pathspec> is given when `-u` or `-A` option is used, all
+tracked files in the entire working tree are updated (old versions
+of Git used to limit the update to the current directory and its
+subdirectories).
 
 -A::
 --all::
diff --git a/builtin/add.c b/builtin/add.c
index 4b9d57c..6cd063f 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -321,33 +321,6 @@ static int add_files(struct dir_struct *dir, int flags)
 	return exit_status;
 }
 
-static void die_on_pathless_add(const char *option_name, const char *short_name)
-{
-	/*
-	 * To be consistent with "git add -p" and most Git
-	 * commands, we should default to being tree-wide, but
-	 * this is not the original behavior and can't be
-	 * changed until users trained themselves not to type
-	 * "git add -u" or "git add -A". In the previous release,
-	 * we kept the old behavior but gave a big warning.
-	 */
-	die(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
-	      "subdirectory of the tree will change in Git 2.0 and should not be "
-	      "used anymore.\n"
-	      "To add content for the whole tree, run:\n"
-	      "\n"
-	      "  git add %s :/\n"
-	      "  (or git add %s :/)\n"
-	      "\n"
-	      "To restrict the command to the current directory, run:\n"
-	      "\n"
-	      "  git add %s .\n"
-	      "  (or git add %s .)"),
-		option_name, short_name,
-		option_name, short_name,
-		option_name, short_name);
-}
-
 int cmd_add(int argc, const char **argv, const char *prefix)
 {
 	int exit_status = 0;
@@ -358,8 +331,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	int add_new_files;
 	int require_pathspec;
 	char *seen = NULL;
-	const char *option_with_implicit_dot = NULL;
-	const char *short_option_with_implicit_dot = NULL;
 
 	git_config(add_config, NULL);
 
@@ -379,21 +350,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		die(_("-A and -u are mutually incompatible"));
 	if (!show_only && ignore_missing)
 		die(_("Option --ignore-missing can only be used together with --dry-run"));
-	if (addremove) {
-		option_with_implicit_dot = "--all";
-		short_option_with_implicit_dot = "-A";
-	}
-	if (take_worktree_changes) {
-		option_with_implicit_dot = "--update";
-		short_option_with_implicit_dot = "-u";
-	}
-	if (option_with_implicit_dot && !argc) {
-		static const char *here[2] = { ".", NULL };
-		if (prefix)
-			die_on_pathless_add(option_with_implicit_dot,
-					    short_option_with_implicit_dot);
+
+	if ((addremove || take_worktree_changes) && !argc) {
+		static const char *whole[2] = { ":/", NULL };
 		argc = 1;
-		argv = here;
+		argv = whole;
 	}
 
 	add_new_files = !take_worktree_changes && !refresh_only;
-- 
1.8.2-rc3-196-gfcda97c

^ permalink raw reply related

* [PATCH 1/2] require pathspec for "git add -u/-A"
From: Junio C Hamano @ 2013-03-08 23:54 UTC (permalink / raw)
  To: git; +Cc: Matthieu Moy, Jeff King
In-Reply-To: <1362786889-28688-1-git-send-email-gitster@pobox.com>

As promised in 0fa2eb530fb7 (add: warn when -u or -A is used without
pathspec, 2013-01-28), "git add -u/-A" that is run without pathspec
in a subdirectory will stop working sometime before Git 2.0, to wean
users off of the old default, in preparation for adopting the new
default in Git 2.0.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-add.txt | 12 ++++++++----
 builtin/add.c             | 38 ++++++++++++++++++--------------------
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 388a225..1ea1d39 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -107,10 +107,14 @@ apply to the index. See EDITING PATCHES below.
 	from the index if the corresponding files in the working tree
 	have been removed.
 +
-If no <pathspec> is given, the current version of Git defaults to
-"."; in other words, update all tracked files in the current directory
-and its subdirectories. This default will change in a future version
-of Git, hence the form without <pathspec> should not be used.
+If no <pathspec> is given when `-u` or `-A` option is used, Git used
+to update all tracked files in the current directory and its
+subdirectories. We would eventually want to change this to operate
+on the entire working tree, not limiting it to the current
+directory, to make it consistent with `git commit -a` and other
+commands.  In order to avoid harming users who are used to the old
+default, Git *errors out* when no <pathspec> is given to train their
+fingers to explicitly type `git add -u .` when they mean it.
 
 -A::
 --all::
diff --git a/builtin/add.c b/builtin/add.c
index 0dd014e..4b9d57c 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -321,30 +321,28 @@ static int add_files(struct dir_struct *dir, int flags)
 	return exit_status;
 }
 
-static void warn_pathless_add(const char *option_name, const char *short_name) {
+static void die_on_pathless_add(const char *option_name, const char *short_name)
+{
 	/*
 	 * To be consistent with "git add -p" and most Git
 	 * commands, we should default to being tree-wide, but
 	 * this is not the original behavior and can't be
 	 * changed until users trained themselves not to type
-	 * "git add -u" or "git add -A". For now, we warn and
-	 * keep the old behavior. Later, this warning can be
-	 * turned into a die(...), and eventually we may
-	 * reallow the command with a new behavior.
+	 * "git add -u" or "git add -A". In the previous release,
+	 * we kept the old behavior but gave a big warning.
 	 */
-	warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
-		  "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
-		  "To add content for the whole tree, run:\n"
-		  "\n"
-		  "  git add %s :/\n"
-		  "  (or git add %s :/)\n"
-		  "\n"
-		  "To restrict the command to the current directory, run:\n"
-		  "\n"
-		  "  git add %s .\n"
-		  "  (or git add %s .)\n"
-		  "\n"
-		  "With the current Git version, the command is restricted to the current directory."),
+	die(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
+	      "subdirectory of the tree will change in Git 2.0 and should not be "
+	      "used anymore.\n"
+	      "To add content for the whole tree, run:\n"
+	      "\n"
+	      "  git add %s :/\n"
+	      "  (or git add %s :/)\n"
+	      "\n"
+	      "To restrict the command to the current directory, run:\n"
+	      "\n"
+	      "  git add %s .\n"
+	      "  (or git add %s .)"),
 		option_name, short_name,
 		option_name, short_name,
 		option_name, short_name);
@@ -392,8 +390,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	if (option_with_implicit_dot && !argc) {
 		static const char *here[2] = { ".", NULL };
 		if (prefix)
-			warn_pathless_add(option_with_implicit_dot,
-					  short_option_with_implicit_dot);
+			die_on_pathless_add(option_with_implicit_dot,
+					    short_option_with_implicit_dot);
 		argc = 1;
 		argv = here;
 	}
-- 
1.8.2-rc3-196-gfcda97c

^ permalink raw reply related

* [PATCH 0/2] "git add -u/-A" from future
From: Junio C Hamano @ 2013-03-08 23:54 UTC (permalink / raw)
  To: git; +Cc: Matthieu Moy, Jeff King

Here are two future steps to update the behaviour of "add -u/-A" run
without pathspec towards Git 2.0; the first step may probably be
optional, but it is included for completeness.

Junio C Hamano (2):
  require pathspec for "git add -u/-A"
  git add: -u/-A now affects the entire working tree

 Documentation/git-add.txt |  8 ++++----
 builtin/add.c             | 49 ++++-------------------------------------------
 2 files changed, 8 insertions(+), 49 deletions(-)

-- 
1.8.2-rc3-196-gfcda97c

^ permalink raw reply

* Re: [PATCH v2 2/3] environment: add GIT_PREFIX to local_repo_env
From: Junio C Hamano @ 2013-03-08 23:03 UTC (permalink / raw)
  To: Jeff King; +Cc: Eric Sunshine, git, Johannes Sixt, Mark Lodato
In-Reply-To: <20130308214404.GA9723@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> On Fri, Mar 08, 2013 at 04:39:02PM -0500, Eric Sunshine wrote:
>
>> On Fri, Mar 8, 2013 at 4:30 AM, Jeff King <peff@peff.net> wrote:
>> > The GIT_PREFIX variable is set based on our location within
>> > the working tree. It should therefore be cleared whenever
>> > GIT_WORK_TREE is cleared.
>> >
>> > In practice, this doesn't cause any bugs, because none of
>> > the sub-programs we invoke with local_repo_env cleared
>> > actually care about GIT_PREFIX. But this is the right thing
>> > to do, and future proofs us again that assumption changing.
>> 
>> s/again/against/
>
> Yep, thanks.

Thanks; squashed-in.

^ permalink raw reply

* [PATCH 2/3] for_each_recent_reflog_ent(): simplify opening of a reflog file
From: Junio C Hamano @ 2013-03-08 21:53 UTC (permalink / raw)
  To: git
In-Reply-To: <1362779624-15513-1-git-send-email-gitster@pobox.com>

There is no reason to use a temporary variable logfile.
---
 refs.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/refs.c b/refs.c
index 9f702a7..e302521 100644
--- a/refs.c
+++ b/refs.c
@@ -2320,13 +2320,11 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c
 
 int for_each_recent_reflog_ent(const char *refname, each_reflog_ent_fn fn, long ofs, void *cb_data)
 {
-	const char *logfile;
 	FILE *logfp;
 	struct strbuf sb = STRBUF_INIT;
 	int ret = 0;
 
-	logfile = git_path("logs/%s", refname);
-	logfp = fopen(logfile, "r");
+	logfp = fopen(git_path("logs/%s", refname), "r");
 	if (!logfp)
 		return -1;
 
-- 
1.8.2-rc3-189-g94c4d42

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox