Git development
 help / color / mirror / Atom feed
* [PATCH v3 06/19] dir.c: rename excluded() to is_excluded()
From: Adam Spiers @ 2012-12-27  2:32 UTC (permalink / raw)
  To: git list
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

Continue adopting clearer names for exclude functions.  This is_*
naming pattern for functions returning booleans was discussed here:

http://thread.gmane.org/gmane.comp.version-control.git/204661/focus=204924

Signed-off-by: Adam Spiers <git@adamspiers.org>
---
 attr.c |  2 +-
 dir.c  | 10 +++++-----
 dir.h  |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/attr.c b/attr.c
index 2fc6353..5362563 100644
--- a/attr.c
+++ b/attr.c
@@ -284,7 +284,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
  * (reading the file from top to bottom), .gitattribute of the root
  * directory (again, reading the file from top to bottom) down to the
  * current directory, and then scan the list backwards to find the first match.
- * This is exactly the same as what excluded() does in dir.c to deal with
+ * This is exactly the same as what is_excluded() does in dir.c to deal with
  * .gitignore
  */
 
diff --git a/dir.c b/dir.c
index 0800491..8c99dc4 100644
--- a/dir.c
+++ b/dir.c
@@ -645,7 +645,7 @@ int is_excluded_from_list(const char *pathname,
 	return -1; /* undecided */
 }
 
-static int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
+static int is_excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
 {
 	int pathlen = strlen(pathname);
 	int st;
@@ -695,7 +695,7 @@ int is_path_excluded(struct path_exclude_check *check,
 	/*
 	 * we allow the caller to pass namelen as an optimization; it
 	 * must match the length of the name, as we eventually call
-	 * excluded() on the whole name string.
+	 * is_excluded() on the whole name string.
 	 */
 	if (namelen < 0)
 		namelen = strlen(name);
@@ -712,7 +712,7 @@ int is_path_excluded(struct path_exclude_check *check,
 
 		if (ch == '/') {
 			int dt = DT_DIR;
-			if (excluded(check->dir, path->buf, &dt))
+			if (is_excluded(check->dir, path->buf, &dt))
 				return 1;
 		}
 		strbuf_addch(path, ch);
@@ -721,7 +721,7 @@ int is_path_excluded(struct path_exclude_check *check,
 	/* An entry in the index; cannot be a directory with subentries */
 	strbuf_setlen(path, 0);
 
-	return excluded(check->dir, name, dtype);
+	return is_excluded(check->dir, name, dtype);
 }
 
 static struct dir_entry *dir_entry_new(const char *pathname, int len)
@@ -1021,7 +1021,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
 					  const struct path_simplify *simplify,
 					  int dtype, struct dirent *de)
 {
-	int exclude = excluded(dir, path->buf, &dtype);
+	int exclude = is_excluded(dir, path->buf, &dtype);
 	if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
 	    && exclude_matches_pathspec(path->buf, path->len, simplify))
 		dir_add_ignored(dir, path->buf, path->len);
diff --git a/dir.h b/dir.h
index 554f87a..d68a997 100644
--- a/dir.h
+++ b/dir.h
@@ -113,8 +113,8 @@ extern int match_pathname(const char *, int,
 			  const char *, int, int, int);
 
 /*
- * The excluded() API is meant for callers that check each level of leading
- * directory hierarchies with excluded() to avoid recursing into excluded
+ * The is_excluded() API is meant for callers that check each level of leading
+ * directory hierarchies with is_excluded() to avoid recursing into excluded
  * directories.  Callers that do not do so should use this API instead.
  */
 struct path_exclude_check {
-- 
1.7.11.2.249.g31c7954

^ permalink raw reply related

* [PATCH v3 01/19] api-directory-listing.txt: update to match code
From: Adam Spiers @ 2012-12-27  2:32 UTC (permalink / raw)
  To: git list
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

7c4c97c0ac turned the flags in struct dir_struct into a single bitfield
variable, but forgot to update this document.

Signed-off-by: Adam Spiers <git@adamspiers.org>
---
For some reason this patch was dropped from the v2 series when it was
applied to the 'pu' branch.

 Documentation/technical/api-directory-listing.txt | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt
index add6f43..0356d25 100644
--- a/Documentation/technical/api-directory-listing.txt
+++ b/Documentation/technical/api-directory-listing.txt
@@ -17,24 +17,24 @@ options are:
 	The name of the file to be read in each directory for excluded
 	files (typically `.gitignore`).
 
-`collect_ignored`::
+`flags`::
 
-	Include paths that are to be excluded in the result.
+	A bit-field of options:
 
-`show_ignored`::
+`DIR_SHOW_IGNORED`:::
 
 	The traversal is for finding just ignored files, not unignored
 	files.
 
-`show_other_directories`::
+`DIR_SHOW_OTHER_DIRECTORIES`:::
 
 	Include a directory that is not tracked.
 
-`hide_empty_directories`::
+`DIR_HIDE_EMPTY_DIRECTORIES`:::
 
 	Do not include a directory that is not tracked and is empty.
 
-`no_gitlinks`::
+`DIR_NO_GITLINKS`:::
 
 	If set, recurse into a directory that looks like a git
 	directory.  Otherwise it is shown as a directory.
-- 
1.7.11.2.249.g31c7954

^ permalink raw reply related

* [PATCH v3 15/19] add.c: remove unused argument from validate_pathspec()
From: Adam Spiers @ 2012-12-27  2:32 UTC (permalink / raw)
  To: git list
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

The 'argc' argument passed to validate_pathspec() was never used.

Signed-off-by: Adam Spiers <git@adamspiers.org>
---
 builtin/add.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 856d232..1ba2a86 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -211,7 +211,7 @@ static void refresh(int verbose, const char **pathspec)
         free(seen);
 }
 
-static const char **validate_pathspec(int argc, const char **argv, const char *prefix)
+static const char **validate_pathspec(const char **argv, const char *prefix)
 {
 	const char **pathspec = get_pathspec(prefix, argv);
 
@@ -262,7 +262,7 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 	const char **pathspec = NULL;
 
 	if (argc) {
-		pathspec = validate_pathspec(argc, argv, prefix);
+		pathspec = validate_pathspec(argv, prefix);
 		if (!pathspec)
 			return -1;
 	}
@@ -428,7 +428,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
 		return 0;
 	}
-	pathspec = validate_pathspec(argc, argv, prefix);
+	pathspec = validate_pathspec(argv, prefix);
 
 	if (read_cache() < 0)
 		die(_("index file corrupt"));
-- 
1.7.11.2.249.g31c7954

^ permalink raw reply related

* [PATCH v3 09/19] dir.c: refactor is_path_excluded()
From: Adam Spiers @ 2012-12-27  2:32 UTC (permalink / raw)
  To: git list
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

In a similar way to the previous commit, this extracts a new helper
function last_exclude_matching_path() which return the last
exclude_list element which matched, or NULL if no match was found.
is_path_excluded() becomes a wrapper around this, and just returns 0
or 1 depending on whether any matching exclude_list element was found.

This allows callers to find out _why_ a given path was excluded,
rather than just whether it was or not, paving the way for a new git
sub-command which allows users to test their exclude lists from the
command line.

Signed-off-by: Adam Spiers <git@adamspiers.org>
---
 dir.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 dir.h |  3 +++
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/dir.c b/dir.c
index b9d4234..16e10b0 100644
--- a/dir.c
+++ b/dir.c
@@ -709,6 +709,7 @@ void path_exclude_check_init(struct path_exclude_check *check,
 			     struct dir_struct *dir)
 {
 	check->dir = dir;
+	check->exclude = NULL;
 	strbuf_init(&check->path, 256);
 }
 
@@ -718,18 +719,21 @@ void path_exclude_check_clear(struct path_exclude_check *check)
 }
 
 /*
- * Is this name excluded?  This is for a caller like show_files() that
- * do not honor directory hierarchy and iterate through paths that are
- * possibly in an ignored directory.
+ * For each subdirectory in name, starting with the top-most, checks
+ * to see if that subdirectory is excluded, and if so, returns the
+ * corresponding exclude structure.  Otherwise, checks whether name
+ * itself (which is presumably a file) is excluded.
  *
  * A path to a directory known to be excluded is left in check->path to
  * optimize for repeated checks for files in the same excluded directory.
  */
-int is_path_excluded(struct path_exclude_check *check,
-		     const char *name, int namelen, int *dtype)
+struct exclude *last_exclude_matching_path(struct path_exclude_check *check,
+					   const char *name, int namelen,
+					   int *dtype)
 {
 	int i;
 	struct strbuf *path = &check->path;
+	struct exclude *exclude;
 
 	/*
 	 * we allow the caller to pass namelen as an optimization; it
@@ -739,11 +743,17 @@ int is_path_excluded(struct path_exclude_check *check,
 	if (namelen < 0)
 		namelen = strlen(name);
 
+	/*
+	 * If path is non-empty, and name is equal to path or a
+	 * subdirectory of path, name should be excluded, because
+	 * it's inside a directory which is already known to be
+	 * excluded and was previously left in check->path.
+	 */
 	if (path->len &&
 	    path->len <= namelen &&
 	    !memcmp(name, path->buf, path->len) &&
 	    (!name[path->len] || name[path->len] == '/'))
-		return 1;
+		return check->exclude;
 
 	strbuf_setlen(path, 0);
 	for (i = 0; name[i]; i++) {
@@ -751,8 +761,12 @@ int is_path_excluded(struct path_exclude_check *check,
 
 		if (ch == '/') {
 			int dt = DT_DIR;
-			if (is_excluded(check->dir, path->buf, &dt))
-				return 1;
+			exclude = last_exclude_matching(check->dir,
+							path->buf, &dt);
+			if (exclude) {
+				check->exclude = exclude;
+				return exclude;
+			}
 		}
 		strbuf_addch(path, ch);
 	}
@@ -760,7 +774,22 @@ int is_path_excluded(struct path_exclude_check *check,
 	/* An entry in the index; cannot be a directory with subentries */
 	strbuf_setlen(path, 0);
 
-	return is_excluded(check->dir, name, dtype);
+	return last_exclude_matching(check->dir, name, dtype);
+}
+
+/*
+ * Is this name excluded?  This is for a caller like show_files() that
+ * do not honor directory hierarchy and iterate through paths that are
+ * possibly in an ignored directory.
+ */
+int is_path_excluded(struct path_exclude_check *check,
+		  const char *name, int namelen, int *dtype)
+{
+	struct exclude *exclude =
+		last_exclude_matching_path(check, name, namelen, dtype);
+	if (exclude)
+		return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;
+	return 0;
 }
 
 static struct dir_entry *dir_entry_new(const char *pathname, int len)
diff --git a/dir.h b/dir.h
index d68a997..dcb1ad3 100644
--- a/dir.h
+++ b/dir.h
@@ -119,10 +119,13 @@ extern int match_pathname(const char *, int,
  */
 struct path_exclude_check {
 	struct dir_struct *dir;
+	struct exclude *exclude;
 	struct strbuf path;
 };
 extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
 extern void path_exclude_check_clear(struct path_exclude_check *);
+extern struct exclude *last_exclude_matching_path(struct path_exclude_check *, const char *,
+						  int namelen, int *dtype);
 extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
 
 
-- 
1.7.11.2.249.g31c7954

^ permalink raw reply related

* [PATCH v3 04/19] dir.c: rename path_excluded() to is_path_excluded()
From: Adam Spiers @ 2012-12-27  2:32 UTC (permalink / raw)
  To: git list
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

Start adopting clearer names for exclude functions.  This 'is_*'
naming pattern for functions returning booleans was agreed here:

http://thread.gmane.org/gmane.comp.version-control.git/204661/focus=204924

Signed-off-by: Adam Spiers <git@adamspiers.org>
---
 builtin/add.c      | 2 +-
 builtin/ls-files.c | 2 +-
 dir.c              | 4 ++--
 dir.h              | 2 +-
 unpack-trees.c     | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 89dce56..c689f37 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -453,7 +453,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 			    && !file_exists(pathspec[i])) {
 				if (ignore_missing) {
 					int dtype = DT_UNKNOWN;
-					if (path_excluded(&check, pathspec[i], -1, &dtype))
+					if (is_path_excluded(&check, pathspec[i], -1, &dtype))
 						dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
 				} else
 					die(_("pathspec '%s' did not match any files"),
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 31b3f2d..ef7f99a 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -203,7 +203,7 @@ static void show_ru_info(void)
 static int ce_excluded(struct path_exclude_check *check, struct cache_entry *ce)
 {
 	int dtype = ce_to_dtype(ce);
-	return path_excluded(check, ce->name, ce_namelen(ce), &dtype);
+	return is_path_excluded(check, ce->name, ce_namelen(ce), &dtype);
 }
 
 static void show_files(struct dir_struct *dir)
diff --git a/dir.c b/dir.c
index f31aa59..f1c0abd 100644
--- a/dir.c
+++ b/dir.c
@@ -685,8 +685,8 @@ void path_exclude_check_clear(struct path_exclude_check *check)
  * A path to a directory known to be excluded is left in check->path to
  * optimize for repeated checks for files in the same excluded directory.
  */
-int path_excluded(struct path_exclude_check *check,
-		  const char *name, int namelen, int *dtype)
+int is_path_excluded(struct path_exclude_check *check,
+		     const char *name, int namelen, int *dtype)
 {
 	int i;
 	struct strbuf *path = &check->path;
diff --git a/dir.h b/dir.h
index 680c1eb..c59bad8 100644
--- a/dir.h
+++ b/dir.h
@@ -123,7 +123,7 @@ struct path_exclude_check {
 };
 extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
 extern void path_exclude_check_clear(struct path_exclude_check *);
-extern int path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
+extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
 
 
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
diff --git a/unpack-trees.c b/unpack-trees.c
index 33a5819..3ac6370 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1372,7 +1372,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
 		return 0;
 
 	if (o->dir &&
-	    path_excluded(o->path_exclude_check, name, -1, &dtype))
+	    is_path_excluded(o->path_exclude_check, name, -1, &dtype))
 		/*
 		 * ce->name is explicitly excluded, so it is Ok to
 		 * overwrite it.
-- 
1.7.11.2.249.g31c7954

^ permalink raw reply related

* [PATCH v3 03/19] dir.c: rename cryptic 'which' variable to more consistent name
From: Adam Spiers @ 2012-12-27  2:32 UTC (permalink / raw)
  To: git list
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

'el' is only *slightly* less cryptic, but is already used as the
variable name for a struct exclude_list pointer in numerous other
places, so this reduces the number of cryptic variable names in use by
one :-)

Signed-off-by: Adam Spiers <git@adamspiers.org>
---
 dir.c | 10 +++++-----
 dir.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/dir.c b/dir.c
index 89e27a6..f31aa59 100644
--- a/dir.c
+++ b/dir.c
@@ -349,7 +349,7 @@ void parse_exclude_pattern(const char **pattern,
 }
 
 void add_exclude(const char *string, const char *base,
-		 int baselen, struct exclude_list *which)
+		 int baselen, struct exclude_list *el)
 {
 	struct exclude *x;
 	int patternlen;
@@ -373,8 +373,8 @@ void add_exclude(const char *string, const char *base,
 	x->base = base;
 	x->baselen = baselen;
 	x->flags = flags;
-	ALLOC_GROW(which->excludes, which->nr + 1, which->alloc);
-	which->excludes[which->nr++] = x;
+	ALLOC_GROW(el->excludes, el->nr + 1, el->alloc);
+	el->excludes[el->nr++] = x;
 }
 
 static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
@@ -416,7 +416,7 @@ int add_excludes_from_file_to_list(const char *fname,
 				   const char *base,
 				   int baselen,
 				   char **buf_p,
-				   struct exclude_list *which,
+				   struct exclude_list *el,
 				   int check_index)
 {
 	struct stat st;
@@ -463,7 +463,7 @@ int add_excludes_from_file_to_list(const char *fname,
 		if (buf[i] == '\n') {
 			if (entry != buf + i && entry[0] != '#') {
 				buf[i - (i && buf[i-1] == '\r')] = 0;
-				add_exclude(entry, base, baselen, which);
+				add_exclude(entry, base, baselen, el);
 			}
 			entry = buf + i + 1;
 		}
diff --git a/dir.h b/dir.h
index e0869bc..680c1eb 100644
--- a/dir.h
+++ b/dir.h
@@ -127,11 +127,11 @@ extern int path_excluded(struct path_exclude_check *, const char *, int namelen,
 
 
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
-					  char **buf_p, struct exclude_list *which, int check_index);
+					  char **buf_p, struct exclude_list *el, int check_index);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
 extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen);
 extern void add_exclude(const char *string, const char *base,
-			int baselen, struct exclude_list *which);
+			int baselen, struct exclude_list *el);
 extern void free_excludes(struct exclude_list *el);
 extern int file_exists(const char *);
 
-- 
1.7.11.2.249.g31c7954

^ permalink raw reply related

* Re: [PATCH v2] wt-status: Show ignored files in untracked dirs
From: Junio C Hamano @ 2012-12-27  2:37 UTC (permalink / raw)
  To: Antoine Pelisse; +Cc: git
In-Reply-To: <1356528674-2730-1-git-send-email-apelisse@gmail.com>

Antoine Pelisse <apelisse@gmail.com> writes:

> When looking for ignored files, we do not recurse into untracked
> directory, and simply consider the directory ignored status.

When asked to show ignored ones, instead of listing all ignored
files in such a directory, we just say "everything in this directory
is ignored"?

That sounds like a more desirable behaviour, than listing everything
there, at least to me, but perhaps I am missing something.

Care to add a test for this new behaviour?

> As a consequence, we don't see ignored files in those directories.
>
> Change that behavior by recursing into untracked directories, if not
> ignored themselves, searching for ignored files.
>
> Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
> ---
> Actually, the previous patch breaks the case where the directory is ignored.
> This one should fix both issues.
> Let me know if you see any other use case that could be an issue.
>
>  dir.c       | 7 +++++++
>  wt-status.c | 2 +-
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/dir.c b/dir.c
> index 5a83aa7..2863799 100644
> --- a/dir.c
> +++ b/dir.c
> @@ -1042,6 +1042,13 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
>  			return path_ignored;
>  	}
>
> +	/*
> +	 * Don't recurse into ignored directories when looking for
> +	 * ignored files, but still show the directory as ignored.
> +	 */
> +	if (exclude && (dir->flags & DIR_SHOW_IGNORED) && dtype == DT_DIR)
> +		return path_handled;
> +
>  	switch (dtype) {
>  	default:
>  		return path_ignored;
> diff --git a/wt-status.c b/wt-status.c
> index 2a9658b..7c41488 100644
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -516,7 +516,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
>
>  	if (s->show_ignored_files) {
>  		dir.nr = 0;
> -		dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
> +		dir.flags = DIR_SHOW_IGNORED;
>  		fill_directory(&dir, s->pathspec);
>  		for (i = 0; i < dir.nr; i++) {
>  			struct dir_entry *ent = dir.entries[i];
> --
> 1.8.1.rc3.12.g8864e38

^ permalink raw reply

* Re: [PATCH v2] wt-status: Show ignored files in untracked dirs
From: Jeff King @ 2012-12-27  3:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Antoine Pelisse, git
In-Reply-To: <7vip7omd8c.fsf@alter.siamese.dyndns.org>

On Wed, Dec 26, 2012 at 06:37:55PM -0800, Junio C Hamano wrote:

> Antoine Pelisse <apelisse@gmail.com> writes:
> 
> > When looking for ignored files, we do not recurse into untracked
> > directory, and simply consider the directory ignored status.
> 
> When asked to show ignored ones, instead of listing all ignored
> files in such a directory, we just say "everything in this directory
> is ignored"?
> 
> That sounds like a more desirable behaviour, than listing everything
> there, at least to me, but perhaps I am missing something.

I do not use this feature myself, but I would think that it should
respect the same DIR_SHOW_OTHER_DIRECTORIES flag (or a parallel flag)
that we already hook into "--untracked={all,normal}".

IOW, given:

  git init
  mkdir untracked ignored
  >untracked/file
  >ignored/file
  echo ignored >.git/info/exclude

I would expect:

  $ git status --short --ignored --untracked=normal
  ?? untracked/
  !! ignored/

  $ git status --short --ignored --untracked=all
  ?? untracked/file
  !! ignored/file

I do not know if anybody cares about the distinction, but optionally we
could give --ignored its own selector, like:

  $ git status --short --ignored=all --untracked=normal
  ?? untracked/
  !! ignored/file

where obviously it would default to "none" (whereas untracked defaults
to "normal"). But the behavior with Antoine's patch is:

  $ git status --short --ignored --untracked=normal
  ?? untracked/
  !! ignored

  $ git status --short --ignored --untracked=all
  ?? untracked/file
  !! ignored

which seems wrong to me for two reasons:

  1. It does not recurse for ignored but untracked entries. Neither does
     the current code, but I think it should.

  2. It loses the trailing slash from the ignored directory in both
     cases (which is printed by the current code).

-Peff

^ permalink raw reply

* Re: [PATCH v2] wt-status: Show ignored files in untracked dirs
From: Junio C Hamano @ 2012-12-27  5:08 UTC (permalink / raw)
  To: Jeff King; +Cc: Antoine Pelisse, git
In-Reply-To: <20121227034859.GA20817@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> IOW, given:
>
>   git init
>   mkdir untracked ignored
>   >untracked/file
>   >ignored/file
>   echo ignored >.git/info/exclude
>
> I would expect:
>
>   $ git status --short --ignored --untracked=normal
>   ?? untracked/
>   !! ignored/

Sensible.

>   $ git status --short --ignored --untracked=all
>   ?? untracked/file
>   !! ignored/file

Again sensible; OK, --untracked=all is what I was missing.

> I do not know if anybody cares about the distinction, but optionally we
> could give --ignored its own selector, like:
>
>   $ git status --short --ignored=all --untracked=normal
>   ?? untracked/
>   !! ignored/file
>
> where obviously it would default to "none" (whereas untracked defaults
> to "normal").

We could just say the selector for the ignored implicitly follows
what is given for --untracked, if we don't care.

> But the behavior with Antoine's patch is:
>
>   $ git status --short --ignored --untracked=normal
>   ?? untracked/
>   !! ignored
>
>   $ git status --short --ignored --untracked=all
>   ?? untracked/file
>   !! ignored
>
> which seems wrong to me for two reasons:
>
>   1. It does not recurse for ignored but untracked entries. Neither does
>      the current code, but I think it should.
>
>   2. It loses the trailing slash from the ignored directory in both
>      cases (which is printed by the current code).

Nicely analysed.  Perhaps we would want new test pieces to define
the behaviour we want to see first?

^ permalink raw reply

* Re: [PATCH v3 00/19] new git check-ignore sub-command
From: Michael Leal @ 2012-12-27  5:15 UTC (permalink / raw)
  To: git
In-Reply-To: <1356575558-2674-1-git-send-email-git@adamspiers.org>

Adam Spiers <git <at> 
adamspiers.org> writes:

> 
> This v3 re-roll of my check-
ignore series is a reasonably 
substantial
> revamp over v2, and applies on 
top of Junio's current
> nd/attr-match-optim-more 
branch (82dce998c202).
> 
> All feedback and patches from 
the v2 series has been 
incorporated, and
> several other improvements 
too, including:
> 
>   - composite exclude_lists 
have been split up into
>     exclude_list_groups each 
containing one exclude_list per 
source
> 
>   - smaller commits for easier 
review
> 
>   - minor memory leaks have 
been fixed and verified via 
valgrind
> 
>   - t0007-ignores.sh has been 
renumbered to t0008-ignores.sh 
to avoid
>     a conflict with t0007-git-
var.sh
> 
>   - improvements to 
documentation and comments
> 
> For reference, the v2 series 
was announced here:
> 
>     http://thread.gmane.org/
gmane.comp.version-
control.git/204661/
focus=206074
> 
> All tests pass except for t91*, 
since there seems to be some
> pre-existing breakage in 
82dce998c202 relating to git-
svn.
> 
> Adam Spiers (19):
>   api-directory-listing.txt: 
update to match code
>   Improve documentation and 
comments regarding directory 
traversal API
>   dir.c: rename cryptic 'which' 
variable to more consistent 
name
>   dir.c: rename path_excluded() 
to is_path_excluded()
>   dir.c: rename 
excluded_from_list() to 
is_excluded_from_list()
>   dir.c: rename excluded() to 
is_excluded()
>   dir.c: refactor 
is_excluded_from_list()
>   dir.c: refactor is_excluded()
>   dir.c: refactor 
is_path_excluded()
>   dir.c: rename free_excludes() 
to clear_exclude_list()
>   dir.c: use a single struct 
exclude_list per source of 
excludes
>   dir.c: keep track of where 
patterns came from
>   dir.c: provide clear_directory() 
for reclaiming dir_struct memory
>   add.c: refactor treat_gitlinks()
>   add.c: remove unused 
argument from 
validate_pathspec()
>   pathspec.c: move reusable 
code from builtin/add.c
>   pathspec.c: extract new 
validate_path() for reuse
>   setup.c: document 
get_pathspec()
>   Add git-check-ignore sub-
command
> 
>  .gitignore                                        
|   1 +
>  Documentation/git-check-
ignore.txt                |  89 ++++
>  Documentation/gitignore.txt                       
|   6 +-
>  Documentation/technical/api-
directory-listing.txt |  35 +-
>  Makefile                                          
|   3 +
>  attr.c                                            |   
2 +-
>  builtin.h                                         
|   1 +
>  builtin/add.c                                     
|  84 +--
>  builtin/check-ignore.c                            
| 170 +++++++
>  builtin/clean.c                                   
|   3 +-
>  builtin/ls-files.c                                
|  11 +-
>  command-list.txt                                  
|   1 +
>  contrib/completion/git-
completion.bash            |   1 +
>  dir.c                                             | 
243 +++++++--
>  dir.h                                             |  
87 +++-
>  git.c                                             |   
1 +
>  pathspec.c                                        
| 107 ++++
>  pathspec.h                                        
|   6 +
>  setup.c                                           
|  15 +
>  t/t0008-ignores.sh                                
| 595 
++++++++++++++++++++++
>  unpack-trees.c                                    
|  14 +-
>  21 files changed, 1305 
insertions(+), 170 deletions(-)
>  create mode 100644 
Documentation/git-check-
ignore.txt
>  create mode 100644 builtin/
check-ignore.c
>  create mode 100644 
pathspec.c
>  create mode 100644 
pathspec.h
>  create mode 100755 t/t0008-
ignores.sh
> 

^ permalink raw reply

* Re: Push Windows to Linux Repository Problem
From: Robin Rosenberg @ 2012-12-27 12:18 UTC (permalink / raw)
  To: Dennis Putnam; +Cc: git
In-Reply-To: <50D7230F.80204@bellsouth.net>



----- Ursprungligt meddelande -----
> Hi Andreas,
> 
> Thanks for the reply and no, I could not. However, you put me on the
> right track. Since I was only pushing/pulling from Windows to/from my
> Linux repository, I did not realize that an SSH session from the
> Linux
> back to Windows would ever be necessary. I don't really understand
> why
> but apparently it is. 

No. Git itself does not require a reverse connection of any kind. Maybe the Linux
box checks that reverse lookup is set up for the client and refuses connection
if reverse lookup of the connecting client's ip does not resolve to a hostname that
in turn resolves back to the client's ip. If that is the case the server does not 
actually try to connect to the client with SSH or otherwise.

-- robin

^ permalink raw reply

* [PATCH] gitk: Replaced "green" with "#00FF00".
From: Peter Hofmann @ 2012-12-27 12:59 UTC (permalink / raw)
  To: git; +Cc: gitster

The definition of "green" has changed in Tk 8.6:

- http://wiki.tcl.tk/21276
- http://www.tcl.tk/cgi-bin/tct/tip/403

gitk looks pretty awkward with Tk 8.6. "green" is simply too dark now
because it has changed from "#00FF00" to "#008000".

One could also use "lime" instead of "#00FF00" but that would break
compatibility with older versions of Tk.

Signed-off-by: Peter Hofmann <git-dev@uninformativ.de>
---
 gitk-git/gitk | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gitk-git/gitk b/gitk-git/gitk
index d93bd99..d7e922b 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -2209,7 +2209,7 @@ proc makewindow {} {
 	set h [expr {[font metrics uifont -linespace] + 2}]
 	set progresscanv .tf.bar.progress
 	canvas $progresscanv -relief sunken -height $h -borderwidth 2
-	set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
+	set progressitem [$progresscanv create rect -1 0 0 $h -fill "#00FF00"]
 	set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
 	set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
     }
@@ -2342,7 +2342,7 @@ proc makewindow {} {
     $ctext tag conf dresult -fore [lindex $diffcolors 1]
     $ctext tag conf m0 -fore red
     $ctext tag conf m1 -fore blue
-    $ctext tag conf m2 -fore green
+    $ctext tag conf m2 -fore "#00FF00"
     $ctext tag conf m3 -fore purple
     $ctext tag conf m4 -fore brown
     $ctext tag conf m5 -fore "#009090"
@@ -3226,7 +3226,7 @@ set rectmask {
        0x00, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
        0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0x00, 0x00};
 }
-image create bitmap reficon-H -background black -foreground green \
+image create bitmap reficon-H -background black -foreground "#00FF00" \
     -data $rectdata -maskdata $rectmask
 image create bitmap reficon-o -background black -foreground "#ddddff" \
     -data $rectdata -maskdata $rectmask
@@ -5909,7 +5909,7 @@ proc drawcmittext {id row col} {
     if {$id eq $nullid} {
 	set ofill red
     } elseif {$id eq $nullid2} {
-	set ofill green
+	set ofill "#00FF00"
     } elseif {$id eq $mainheadid} {
 	set ofill yellow
     } else {
@@ -6377,7 +6377,7 @@ proc drawtags {id x xt y1} {
 	} else {
 	    # draw a head or other ref
 	    if {[incr nheads -1] >= 0} {
-		set col green
+		set col "#00FF00"
 		if {$tag eq $mainhead} {
 		    set font mainfontbold
 		}
@@ -11617,7 +11617,7 @@ if {[tk windowingsystem] eq "aqua"} {
     set extdifftool "meld"
 }
 
-set colors {green red blue magenta darkgrey brown orange}
+set colors {"#00FF00" red blue magenta darkgrey brown orange}
 if {[tk windowingsystem] eq "win32"} {
     set uicolor SystemButtonFace
     set bgcolor SystemWindow
-- 
1.8.0.2

^ permalink raw reply related

* [PATCH] Remove Documentation/pt_BR/gittutorial.txt
From: Thomas Ackermann @ 2012-12-27 14:15 UTC (permalink / raw)
  To: th.acker, git


This file is rather outdated and IMHO shouldn't be there in the first place.
(If there are translations of the Git documentation they are better be kept
separate from the original documentation.)

Signed-off-by: Thomas Ackermann <th.acker@arcor.de>
---
 Documentation/pt_BR/gittutorial.txt | 675 ------------------------------------
 1 file changed, 675 deletions(-)
 delete mode 100644 Documentation/pt_BR/gittutorial.txt

diff --git a/Documentation/pt_BR/gittutorial.txt b/Documentation/pt_BR/gittutorial.txt
deleted file mode 100644
index beba065..0000000
--- a/Documentation/pt_BR/gittutorial.txt
+++ /dev/null
@@ -1,675 +0,0 @@
-gittutorial(7)
-==============
-
-NOME
-----
-gittutorial - Um tutorial de introdução ao git (para versão 1.5.1 ou mais nova)
-
-SINOPSE
---------
-git *
-
-DESCRIÇÃO
------------
-
-Este tutorial explica como importar um novo projeto para o git,
-adicionar mudanças a ele, e compartilhar mudanças com outros
-desenvolvedores.
-
-Se, ao invés disso, você está interessado primariamente em usar git para
-obter um projeto, por exemplo, para testar a última versão, você pode
-preferir começar com os primeiros dois capítulos de
-link:user-manual.html[O Manual do Usuário Git].
-
-Primeiro, note que você pode obter documentação para um comando como
-`git log --graph` com:
-
-------------------------------------------------
-$ man git-log
-------------------------------------------------
-
-ou:
-
-------------------------------------------------
-$ git help log
-------------------------------------------------
-
-Com a última forma, você pode usar o visualizador de manual de sua
-escolha; veja linkgit:git-help[1] para maior informação.
-
-É uma boa idéia informar ao git seu nome e endereço público de email
-antes de fazer qualquer operação. A maneira mais fácil de fazê-lo é:
-
-------------------------------------------------
-$ git config --global user.name "Seu Nome Vem Aqui"
-$ git config --global user.email voce@seudominio.exemplo.com
-------------------------------------------------
-
-
-Importando um novo projeto
------------------------
-
-Assuma que você tem um tarball project.tar.gz com seu trabalho inicial.
-Você pode colocá-lo sob controle de revisão git da seguinte forma:
-
-------------------------------------------------
-$ tar xzf project.tar.gz
-$ cd project
-$ git init
-------------------------------------------------
-
-Git irá responder
-
-------------------------------------------------
-Initialized empty Git repository in .git/
-------------------------------------------------
-
-Agora que você iniciou seu diretório de trabalho, você deve ter notado que um
-novo diretório foi criado com o nome de ".git".
-
-A seguir, diga ao git para gravar um instantâneo do conteúdo de todos os
-arquivos sob o diretório atual (note o '.'), com 'git-add':
-
-------------------------------------------------
-$ git add .
-------------------------------------------------
-
-Este instantâneo está agora armazenado em uma área temporária que o git
-chama de "index" ou índice. Você pode armazenar permanentemente o
-conteúdo do índice no repositório com 'git-commit':
-
-------------------------------------------------
-$ git commit
-------------------------------------------------
-
-Isto vai te pedir por uma mensagem de commit. Você agora gravou sua
-primeira versão de seu projeto no git.
-
-Fazendo mudanças
---------------
-
-Modifique alguns arquivos, e, então, adicione seu conteúdo atualizado ao
-índice:
-
-------------------------------------------------
-$ git add file1 file2 file3
-------------------------------------------------
-
-Você está agora pronto para fazer o commit. Você pode ver o que está
-para ser gravado usando 'git-diff' com a opção --cached:
-
-------------------------------------------------
-$ git diff --cached
-------------------------------------------------
-
-(Sem --cached, o comando 'git-diff' irá te mostrar quaisquer mudanças
-que você tenha feito mas ainda não adicionou ao índice.) Você também
-pode obter um breve sumário da situação com 'git-status':
-
-------------------------------------------------
-$ git status
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
-#
-#	modified:   file1
-#	modified:   file2
-#	modified:   file3
-#
-------------------------------------------------
-
-Se você precisar fazer qualquer outro ajuste, faça-o agora, e, então,
-adicione qualquer conteúdo modificado ao índice. Finalmente, grave suas
-mudanças com:
-
-------------------------------------------------
-$ git commit
-------------------------------------------------
-
-Ao executar esse comando, ele irá te pedir uma mensagem descrevendo a mudança,
-e, então, irá gravar a nova versão do projeto.
-
-Alternativamente, ao invés de executar 'git-add' antes, você pode usar
-
-------------------------------------------------
-$ git commit -a
-------------------------------------------------
-
-o que irá automaticamente notar quaisquer arquivos modificados (mas não
-novos), adicioná-los ao índices, e gravar, tudo em um único passo.
-
-Uma nota em mensagens de commit: Apesar de não ser exigido, é uma boa
-idéia começar a mensagem com uma simples e curta (menos de 50
-caracteres) linha sumarizando a mudança, seguida de uma linha em branco
-e, então, uma descrição mais detalhada. Ferramentas que transformam
-commits em email, por exemplo, usam a primeira linha no campo de
-cabeçalho "Subject:" e o resto no corpo.
-
-Git rastreia conteúdo, não arquivos
-----------------------------
-
-Muitos sistemas de controle de revisão provêem um comando `add` que diz
-ao sistema para começar a rastrear mudanças em um novo arquivo. O
-comando `add` do git faz algo mais simples e mais poderoso: 'git-add' é
-usado tanto para arquivos novos e arquivos recentemente modificados, e
-em ambos os casos, ele tira o instantâneo dos arquivos dados e armazena
-o conteúdo no índice, pronto para inclusão do próximo commit.
-
-Visualizando a história do projeto
------------------------
-
-Em qualquer ponto você pode visualizar a história das suas mudanças
-usando
-
-------------------------------------------------
-$ git log
-------------------------------------------------
-
-Se você também quiser ver a diferença completa a cada passo, use
-
-------------------------------------------------
-$ git log -p
-------------------------------------------------
-
-Geralmente, uma visão geral da mudança é útil para ter a sensação de
-cada passo
-
-------------------------------------------------
-$ git log --stat --summary
-------------------------------------------------
-
-Gerenciando "branches"/ramos
------------------
-
-Um simples repositório git pode manter múltiplos ramos de
-desenvolvimento. Para criar um novo ramo chamado "experimental", use
-
-------------------------------------------------
-$ git branch experimental
-------------------------------------------------
-
-Se você executar agora
-
-------------------------------------------------
-$ git branch
-------------------------------------------------
-
-você vai obter uma lista de todos os ramos existentes:
-
-------------------------------------------------
-  experimental
-* master
-------------------------------------------------
-
-O ramo "experimental" é o que você acaba de criar, e o ramo "master" é o
-ramo padrão que foi criado pra você automaticamente. O asterisco marca
-o ramo em que você está atualmente; digite
-
-------------------------------------------------
-$ git checkout experimental
-------------------------------------------------
-
-para mudar para o ramo experimental. Agora edite um arquivo, grave a
-mudança, e mude de volta para o ramo master:
-
-------------------------------------------------
-(edita arquivo)
-$ git commit -a
-$ git checkout master
-------------------------------------------------
-
-Verifique que a mudança que você fez não está mais visível, já que ela
-foi feita no ramo experimental e você está de volta ao ramo master.
-
-Você pode fazer uma mudança diferente no ramo master:
-
-------------------------------------------------
-(edit file)
-$ git commit -a
-------------------------------------------------
-
-neste ponto, os dois ramos divergiram, com diferentes mudanças feitas em
-cada um. Para unificar as mudanças feitas no experimental para o
-master, execute
-
-------------------------------------------------
-$ git merge experimental
-------------------------------------------------
-
-Se as mudanças não conflitarem, estará pronto. Se existirem conflitos,
-marcadores serão deixados nos arquivos problemáticos exibindo o
-conflito;
-
-------------------------------------------------
-$ git diff
-------------------------------------------------
-
-vai exibir isto. Após você editar os arquivos para resolver os
-conflitos,
-
-------------------------------------------------
-$ git commit -a
-------------------------------------------------
-
-irá gravar o resultado da unificação. Finalmente,
-
-------------------------------------------------
-$ gitk
-------------------------------------------------
-
-vai mostrar uma bela representação gráfica da história resultante.
-
-Neste ponto você pode remover seu ramo experimental com
-
-------------------------------------------------
-$ git branch -d experimental
-------------------------------------------------
-
-Este comando garante que as mudanças no ramo experimental já estão no
-ramo atual.
-
-Se você desenvolve em um ramo ideia-louca, e se arrepende, você pode
-sempre remover o ramo com
-
--------------------------------------
-$ git branch -D ideia-louca
--------------------------------------
-
-Ramos são baratos e fáceis, então isto é uma boa maneira de experimentar
-alguma coisa.
-
-Usando git para colaboração
----------------------------
-
-Suponha que Alice começou um novo projeto com um repositório git em
-/home/alice/project, e que Bob, que tem um diretório home na mesma
-máquina, quer contribuir.
-
-Bob começa com:
-
-------------------------------------------------
-bob$ git clone /home/alice/project myrepo
-------------------------------------------------
-
-Isso cria um novo diretório "myrepo" contendo um clone do repositório de
-Alice. O clone está no mesmo pé que o projeto original, possuindo sua
-própria cópia da história do projeto original.
-
-Bob então faz algumas mudanças e as grava:
-
-------------------------------------------------
-(editar arquivos)
-bob$ git commit -a
-(repetir conforme necessário)
-------------------------------------------------
-
-Quanto está pronto, ele diz a Alice para puxar as mudanças do
-repositório em /home/bob/myrepo. Ela o faz com:
-
-------------------------------------------------
-alice$ cd /home/alice/project
-alice$ git pull /home/bob/myrepo master
-------------------------------------------------
-
-Isto unifica as mudanças do ramo "master" do Bob ao ramo atual de Alice.
-Se Alice fez suas próprias mudanças no intervalo, ela, então, pode
-precisar corrigir manualmente quaisquer conflitos. (Note que o argumento
-"master" no comando acima é, de fato, desnecessário, já que é o padrão.)
-
-O comando "pull" executa, então, duas operações: ele obtém mudanças de
-um ramo remoto, e, então, as unifica no ramo atual.
-
-Note que, em geral, Alice gostaria que suas mudanças locais fossem
-gravadas antes de iniciar este "pull". Se o trabalho de Bob conflita
-com o que Alice fez desde que suas histórias se ramificaram, Alice irá
-usar seu diretório de trabalho e o índice para resolver conflitos, e
-mudanças locais existentes irão interferir com o processo de resolução
-de conflitos (git ainda irá realizar a obtenção mas irá se recusar a
-unificar --- Alice terá que se livrar de suas mudanças locais de alguma
-forma e puxar de novo quando isso acontecer).
-
-Alice pode espiar o que Bob fez sem unificar primeiro, usando o comando
-"fetch"; isto permite Alice inspecionar o que Bob fez, usando um símbolo
-especial "FETCH_HEAD", com o fim de determinar se ele tem alguma coisa
-que vale puxar, assim:
-
-------------------------------------------------
-alice$ git fetch /home/bob/myrepo master
-alice$ git log -p HEAD..FETCH_HEAD
-------------------------------------------------
-
-Esta operação é segura mesmo se Alice tem mudanças locais não gravadas.
-A notação de intervalo "HEAD..FETCH_HEAD" significa mostrar tudo que é
-alcançável de FETCH_HEAD mas exclua tudo o que é alcançável de HEAD.
-Alice já sabe tudo que leva a seu estado atual (HEAD), e revisa o que Bob
-tem em seu estado (FETCH_HEAD) que ela ainda não viu com esse comando.
-
-Se Alice quer visualizar o que Bob fez desde que suas histórias se
-ramificaram, ela pode disparar o seguinte comando:
-
-------------------------------------------------
-$ gitk HEAD..FETCH_HEAD
-------------------------------------------------
-
-Isto usa a mesma notação de intervalo que vimos antes com 'git log'.
-
-Alice pode querer ver o que ambos fizeram desde que ramificaram. Ela
-pode usar a forma com três pontos ao invés da forma com dois pontos:
-
-------------------------------------------------
-$ gitk HEAD...FETCH_HEAD
-------------------------------------------------
-
-Isto significa "mostre tudo que é alcançável de qualquer um deles, mas
-exclua tudo que é alcançável a partir de ambos".
-
-Por favor, note que essas notações de intervalo podem ser usadas tanto
-com gitk quanto com "git log".
-
-Após inspecionar o que Bob fez, se não há nada urgente, Alice pode
-decidir continuar trabalhando sem puxar de Bob. Se a história de Bob
-tem alguma coisa que Alice precisa imediatamente, Alice pode optar por
-separar seu trabalho em progresso primeiro, fazer um "pull", e, então,
-finalmente, retomar seu trabalho em progresso em cima da história
-resultante.
-
-Quando você está trabalhando em um pequeno grupo unido, não é incomum
-interagir com o mesmo repositório várias e várias vezes. Definindo um
-repositório remoto antes de tudo, você pode fazê-lo mais facilmente:
-
-------------------------------------------------
-alice$ git remote add bob /home/bob/myrepo
-------------------------------------------------
-
-Com isso, Alice pode executar a primeira parte da operação "pull" usando
-o comando 'git-fetch' sem unificar suas mudanças com seu próprio ramo,
-usando:
-
--------------------------------------
-alice$ git fetch bob
--------------------------------------
-
-Diferente da forma longa, quando Alice obteve de Bob usando um
-repositório remoto antes definido com 'git-remote', o que foi obtido é
-armazenado em um ramo remoto, neste caso `bob/master`. Então, após isso:
-
--------------------------------------
-alice$ git log -p master..bob/master
--------------------------------------
-
-mostra uma lista de todas as mudanças que Bob fez desde que ramificou do
-ramo master de Alice.
-
-Após examinar essas mudanças, Alice pode unificá-las em seu ramo master:
-
--------------------------------------
-alice$ git merge bob/master
--------------------------------------
-
-Esse `merge` pode também ser feito puxando de seu próprio ramo remoto,
-assim:
-
--------------------------------------
-alice$ git pull . remotes/bob/master
--------------------------------------
-
-Note que 'git pull' sempre unifica ao ramo atual, independente do que
-mais foi passado na linha de comando.
-
-Depois, Bob pode atualizar seu repositório com as últimas mudanças de
-Alice, usando
-
--------------------------------------
-bob$ git pull
--------------------------------------
-
-Note que ele não precisa dar o caminho do repositório de Alice; quando
-Bob clonou seu repositório, o git armazenou a localização de seu
-repositório na configuração do mesmo, e essa localização é usada
-para puxar:
-
--------------------------------------
-bob$ git config --get remote.origin.url
-/home/alice/project
--------------------------------------
-
-(A configuração completa criada por 'git-clone' é visível usando `git
-config -l`, e a página de manual linkgit:git-config[1] explica o
-significado de cada opção.)
-
-Git também mantém uma cópia limpa do ramo master de Alice sob o nome
-"origin/master":
-
--------------------------------------
-bob$ git branch -r
-  origin/master
--------------------------------------
-
-Se Bob decidir depois em trabalhar em um host diferente, ele ainda pode
-executar clones e puxar usando o protocolo ssh:
-
--------------------------------------
-bob$ git clone alice.org:/home/alice/project myrepo
--------------------------------------
-
-Alternativamente, o git tem um protocolo nativo, ou pode usar rsync ou
-http; veja linkgit:git-pull[1] para detalhes.
-
-Git pode também ser usado em um modo parecido com CVS, com um
-repositório central para o qual vários usuários empurram modificações;
-veja linkgit:git-push[1] e linkgit:gitcvs-migration[7].
-
-Explorando história
------------------
-
-A história no git é representada como uma série de commits
-interrelacionados. Nós já vimos que o comando 'git-log' pode listar
-esses commits. Note que a primeira linha de cada entrada no log também
-dá o nome para o commit:
-
--------------------------------------
-$ git log
-commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
-Author: Junio C Hamano <junkio@cox.net>
-Date:   Tue May 16 17:18:22 2006 -0700
-
-    merge-base: Clarify the comments on post processing.
--------------------------------------
-
-Nós podemos dar este nome ao 'git-show' para ver os detalhes sobre este
-commit.
-
--------------------------------------
-$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
--------------------------------------
-
-Mas há outras formas de se referir aos commits. Você pode usar qualquer
-parte inicial do nome que seja longo o bastante para identificar
-unicamente o commit:
-
--------------------------------------
-$ git show c82a22c39c	# os primeiros caracteres do nome são o bastante
-			# usualmente
-$ git show HEAD		# a ponta do ramo atual
-$ git show experimental	# a ponta do ramo "experimental"
--------------------------------------
-
-Todo commit normalmente tem um commit "pai" que aponta para o estado
-anterior do projeto:
-
--------------------------------------
-$ git show HEAD^  # para ver o pai de HEAD
-$ git show HEAD^^ # para ver o avô de HEAD
-$ git show HEAD~4 # para ver o trisavô de HEAD
--------------------------------------
-
-Note que commits de unificação podem ter mais de um pai:
-
--------------------------------------
-$ git show HEAD^1 # mostra o primeiro pai de HEAD (o mesmo que HEAD^)
-$ git show HEAD^2 # mostra o segundo pai de HEAD
--------------------------------------
-
-Você também pode dar aos commits nomes à sua escolha; após executar
-
--------------------------------------
-$ git tag v2.5 1b2e1d63ff
--------------------------------------
-
-você pode se referir a 1b2e1d63ff pelo nome "v2.5". Se você pretende
-compartilhar esse nome com outras pessoas (por exemplo, para identificar
-uma versão de lançamento), você deveria criar um objeto "tag", e talvez
-assiná-lo; veja linkgit:git-tag[1] para detalhes.
-
-Qualquer comando git que precise conhecer um commit pode receber
-quaisquer desses nomes. Por exemplo:
-
--------------------------------------
-$ git diff v2.5 HEAD	 # compara o HEAD atual com v2.5
-$ git branch stable v2.5 # inicia um novo ramo chamado "stable" baseado
-			 # em v2.5
-$ git reset --hard HEAD^ # reseta seu ramo atual e seu diretório de
-			 # trabalho a seu estado em HEAD^
--------------------------------------
-
-Seja cuidadoso com o último comando: além de perder quaisquer mudanças
-em seu diretório de trabalho, ele também remove todos os commits
-posteriores desse ramo. Se esse ramo é o único ramo contendo esses
-commits, eles serão perdidos. Também, não use 'git-reset' num ramo
-publicamente visível de onde outros desenvolvedores puxam, já que vai
-forçar unificações desnecessárias para que outros desenvolvedores limpem
-a história. Se você precisa desfazer mudanças que você empurrou, use
-'git-revert' no lugar.
-
-O comando 'git-grep' pode buscar strings em qualquer versão de seu
-projeto, então
-
--------------------------------------
-$ git grep "hello" v2.5
--------------------------------------
-
-procura por todas as ocorrências de "hello" em v2.5.
-
-Se você deixar de fora o nome do commit, 'git-grep' irá procurar
-quaisquer dos arquivos que ele gerencia no diretório corrente. Então
-
--------------------------------------
-$ git grep "hello"
--------------------------------------
-
-é uma forma rápida de buscar somente os arquivos que são rastreados pelo
-git.
-
-Muitos comandos git também recebem um conjunto de commits, o que pode
-ser especificado de várias formas. Aqui estão alguns exemplos com 'git-log':
-
--------------------------------------
-$ git log v2.5..v2.6            # commits entre v2.5 e v2.6
-$ git log v2.5..                # commits desde v2.5
-$ git log --since="2 weeks ago" # commits das últimas 2 semanas
-$ git log v2.5.. Makefile       # commits desde v2.5 que modificam
-				# Makefile
--------------------------------------
-
-Você também pode dar ao 'git-log' um "intervalo" de commits onde o
-primeiro não é necessariamente um ancestral do segundo; por exemplo, se
-as pontas dos ramos "stable" e "master" divergiram de um commit
-comum algum tempo atrás, então
-
--------------------------------------
-$ git log stable..master
--------------------------------------
-
-irá listar os commits feitos no ramo "master" mas não no ramo
-"stable", enquanto
-
--------------------------------------
-$ git log master..stable
--------------------------------------
-
-irá listar a lista de commits feitos no ramo "stable" mas não no ramo
-"master".
-
-O comando 'git-log' tem uma fraqueza: ele precisa mostrar os commits em
-uma lista. Quando a história tem linhas de desenvolvimento que
-divergiram e então foram unificadas novamente, a ordem em que 'git-log'
-apresenta essas mudanças é irrelevante.
-
-A maioria dos projetos com múltiplos contribuidores (como o kernel
-Linux, ou o próprio git) tem unificações frequentes, e 'gitk' faz um
-trabalho melhor de visualizar sua história. Por exemplo,
-
--------------------------------------
-$ gitk --since="2 weeks ago" drivers/
--------------------------------------
-
-permite a você navegar em quaisquer commits desde as últimas duas semanas
-de commits que modificaram arquivos sob o diretório "drivers". (Nota:
-você pode ajustar as fontes do gitk segurando a tecla control enquanto
-pressiona "-" ou "+".)
-
-Finalmente, a maioria dos comandos que recebem nomes de arquivo permitirão
-também, opcionalmente, preceder qualquer nome de arquivo por um
-commit, para especificar uma versão particular do arquivo:
-
--------------------------------------
-$ git diff v2.5:Makefile HEAD:Makefile.in
--------------------------------------
-
-Você pode usar 'git-show' para ver tal arquivo:
-
--------------------------------------
-$ git show v2.5:Makefile
--------------------------------------
-
-Próximos passos
-----------
-
-Este tutorial deve ser o bastante para operar controle de revisão
-distribuído básico para seus projetos. No entanto, para entender
-plenamente a profundidade e o poder do git você precisa entender duas
-idéias simples nas quais ele se baseia:
-
-  * A base de objetos é um sistema bem elegante usado para armazenar a
-    história de seu projeto--arquivos, diretórios, e commits.
-
-  * O arquivo de índice é um cache do estado de uma árvore de diretório,
-    usado para criar commits, restaurar diretórios de trabalho, e
-    armazenar as várias árvores envolvidas em uma unificação.
-
-A parte dois deste tutorial explica a base de objetos, o arquivo de
-índice, e algumas outras coisinhas que você vai precisar pra usar o
-máximo do git. Você pode encontrá-la em linkgit:gittutorial-2[7].
-
-Se você não quiser continuar com o tutorial agora nesse momento, algumas
-outras digressões que podem ser interessantes neste ponto são:
-
-  * linkgit:git-format-patch[1], linkgit:git-am[1]: Estes convertem
-    séries de commits em patches para email, e vice-versa, úteis para
-    projetos como o kernel Linux que dependem fortemente de patches
-    enviados por email.
-
-  * linkgit:git-bisect[1]: Quando há uma regressão em seu projeto, uma
-    forma de rastrear um bug é procurando pela história para encontrar o
-    commit culpado. Git bisect pode ajudar a executar uma busca binária
-    por esse commit. Ele é inteligente o bastante para executar uma
-    busca próxima da ótima mesmo no caso de uma história complexa
-    não-linear com muitos ramos unificados.
-
-  * link:everyday.html[GIT diariamente com 20 e tantos comandos]
-
-  * linkgit:gitcvs-migration[7]: Git para usuários de CVS.
-
-VEJA TAMBÉM
---------
-linkgit:gittutorial-2[7],
-linkgit:gitcvs-migration[7],
-linkgit:gitcore-tutorial[7],
-linkgit:gitglossary[7],
-linkgit:git-help[1],
-link:everyday.html[git diariamente],
-link:user-manual.html[O Manual do Usuário git]
-
-GIT
----
-Parte da suite linkgit:git[1].
-- 
1.8.0.msysgit.0


---
Thomas

^ permalink raw reply related

* [PATCH v2] log: grep author/committer using mailmap
From: Antoine Pelisse @ 2012-12-27 15:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Antoine Pelisse
In-Reply-To: <7vy5gkmr53.fsf@alter.siamese.dyndns.org>

Currently you can use mailmap to display log authors and committers
but you can't use the mailmap to find commits with mapped values.

This commit allows you to run:

    git log --use-mailmap --author mapped_name_or_email
    git log --use-mailmap --committer mapped_name_or_email

Of course it only works if the --use-mailmap option is used.

Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
---
 revision.c         |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/t4203-mailmap.sh |   18 ++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/revision.c b/revision.c
index 95d21e6..fa16b9d 100644
--- a/revision.c
+++ b/revision.c
@@ -13,6 +13,7 @@
 #include "decorate.h"
 #include "log-tree.h"
 #include "string-list.h"
+#include "mailmap.h"
 
 volatile show_early_output_fn_t show_early_output;
 
@@ -2219,6 +2220,51 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
 	return 0;
 }
 
+static int commit_rewrite_person(struct strbuf *buf, const char *what, struct string_list *mailmap)
+{
+	char *person, *endp;
+	size_t len;
+	struct strbuf name = STRBUF_INIT;
+	struct strbuf mail = STRBUF_INIT;
+	struct ident_split ident;
+
+	person = strstr(buf->buf, what);
+	if (!person)
+		goto left_intact;
+
+	person += strlen(what);
+	endp = strchr(person, '\n');
+	if (!endp)
+		goto left_intact;
+
+	len = endp - person;
+
+	if (split_ident_line(&ident, person, len))
+		goto left_intact;
+
+	strbuf_add(&name, ident.name_begin, ident.name_end - ident.name_begin);
+	strbuf_add(&mail, ident.mail_begin, ident.mail_end - ident.mail_begin);
+
+	if (map_user(mailmap, &mail, &name)) {
+		strbuf_addf(&name, " <%s>", mail.buf);
+
+		strbuf_splice(buf, ident.name_begin - buf->buf,
+			      ident.mail_end - ident.name_begin + 1,
+			      name.buf, name.len);
+
+		strbuf_release(&name);
+		strbuf_release(&mail);
+
+		return 1;
+	}
+
+left_intact:
+	strbuf_release(&name);
+	strbuf_release(&mail);
+
+	return 0;
+}
+
 static int commit_match(struct commit *commit, struct rev_info *opt)
 {
 	int retval;
@@ -2237,6 +2283,14 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
 	if (buf.len)
 		strbuf_addstr(&buf, commit->buffer);
 
+	if (opt->mailmap) {
+		if (!buf.len)
+			strbuf_addstr(&buf, commit->buffer);
+
+		commit_rewrite_person(&buf, "\nauthor ", opt->mailmap);
+		commit_rewrite_person(&buf, "\ncommitter ", opt->mailmap);
+	}
+
 	/* Append "fake" message parts as needed */
 	if (opt->show_notes) {
 		if (!buf.len)
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index db043dc..e16187f 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -248,11 +248,29 @@ Author: Other Author <other@author.xx>
 Author: Some Dude <some@dude.xx>
 Author: A U Thor <author@example.com>
 EOF
+
 test_expect_success 'Log output with --use-mailmap' '
 	git log --use-mailmap | grep Author >actual &&
 	test_cmp expect actual
 '
 
+cat >expect <<\EOF
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+EOF
+
+test_expect_success 'Grep author with --use-mailmap' '
+	git log --use-mailmap --author Santa | grep Author >actual &&
+	test_cmp expect actual
+'
+
+>expect
+
+test_expect_success 'Only grep replaced author with --use-mailmap' '
+	git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
+	test_cmp expect actual
+'
+
 # git blame
 cat >expect <<\EOF
 ^OBJI (A U Thor     DATE 1) one
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH v2] wt-status: Show ignored files in untracked dirs
From: Jeff King @ 2012-12-27 16:19 UTC (permalink / raw)
  To: Antoine Pelisse; +Cc: Junio C Hamano, git
In-Reply-To: <CALWbr2wFg_9oDoZ_BUQwAzVV+UJSqBQRrMYmt6fv=fo02RL7Zg@mail.gmail.com>

On Thu, Dec 27, 2012 at 05:14:54PM +0100, Antoine Pelisse wrote:

> > Nicely analysed.  Perhaps we would want new test pieces to define
> > the behaviour we want to see first?
> 
> I think we should.
> 
> I also thought about the use case of "committed" and ignored directory
> which is also broken to me (point 3 in the table below).

By "committed", I assume you meat that you have "dirA/unco" as an
untracked file, and "dirA/committed" as a file in the index?

> Anyway I tried to make a table to sum-up/discuss the list of behaviors
> we would like to see/test, taking Jeff mail into account.
> (warning: that requires fixed width font)
> 
> |----------------------+---------------------+---------------------------|
> | Output               | A. status --ignored | B. status --ignored -uall |
> |                      |                     | (or with potential        |
> |                      |                     | --ignored=all)            |
> |----------------------+---------------------+---------------------------|
> | 1. Untracked dirU    | Current:            | Current:                  |
> | with ignored unco.ig | Empty               | Empty                     |
> | in it                |                     |                           |
> |                      | Expected:           | Expected:                 |
> |                      | !!dirU/             | !!dirU/unco.ig            |
> |----------------------+---------------------+---------------------------|
> | 2. Untracked and     | Current (OK):       | Current:                  |
> | ignored dirU with    | !!dirU/             | !!dirU/                   |
> | file in it           |                     |                           |
> |                      |                     | Expected:                 |
> |                      |                     | !!dirU/unco               |
> |----------------------+---------------------+---------------------------|
> | 3. "Committed" dirA  | Current:            | Current:                  |
> | yet ignored          | Empty               | Empty                     |
> | with uncommitted     |                     |                           |
> | file in it           | Expected:           | Expected:                 |
> |                      | dirA/               | dirA/unco                 |
> |----------------------+---------------------+---------------------------|

Thanks for putting this together. I agree with the expected output in
each case, and I think this covers the cases we have seen (case 1 is
Michael's original report, case 2 is what I wrote in my mail, and case 3
is the one you just came up with). I can't think offhand of any others.

-Peff

^ permalink raw reply

* Re: [PATCH v2] wt-status: Show ignored files in untracked dirs
From: Antoine Pelisse @ 2012-12-27 16:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7va9t0m69o.fsf@alter.siamese.dyndns.org>

> Nicely analysed.  Perhaps we would want new test pieces to define
> the behaviour we want to see first?

I think we should.

I also thought about the use case of "committed" and ignored directory
which is also broken to me (point 3 in the table below).

Anyway I tried to make a table to sum-up/discuss the list of behaviors
we would like to see/test, taking Jeff mail into account.
(warning: that requires fixed width font)

|----------------------+---------------------+---------------------------|
| Output               | A. status --ignored | B. status --ignored -uall |
|                      |                     | (or with potential        |
|                      |                     | --ignored=all)            |
|----------------------+---------------------+---------------------------|
| 1. Untracked dirU    | Current:            | Current:                  |
| with ignored unco.ig | Empty               | Empty                     |
| in it                |                     |                           |
|                      | Expected:           | Expected:                 |
|                      | !!dirU/             | !!dirU/unco.ig            |
|----------------------+---------------------+---------------------------|
| 2. Untracked and     | Current (OK):       | Current:                  |
| ignored dirU with    | !!dirU/             | !!dirU/                   |
| file in it           |                     |                           |
|                      |                     | Expected:                 |
|                      |                     | !!dirU/unco               |
|----------------------+---------------------+---------------------------|
| 3. "Committed" dirA  | Current:            | Current:                  |
| yet ignored          | Empty               | Empty                     |
| with uncommitted     |                     |                           |
| file in it           | Expected:           | Expected:                 |
|                      | dirA/               | dirA/unco                 |
|----------------------+---------------------+---------------------------|

^ permalink raw reply

* Re: [PATCH] gitk: Replaced "green" with "#00FF00".
From: Junio C Hamano @ 2012-12-27 17:27 UTC (permalink / raw)
  To: Peter Hofmann; +Cc: git, Paul Mackerras
In-Reply-To: <20121227125916.GC7039@mobiltux>

Peter Hofmann <git-dev@uninformativ.de> writes:

> Subject: Re: [PATCH] gitk: Replaced "green" with "#00FF00".

That should be

	Subject: [PATCH] gitk: replace "green" with "#00FF00"

around here.  Instead of reporting what you did in the past tense,
you give an order to somebody to do something to make the codebase
into more desirable shape, without the final full-stop.

> The definition of "green" has changed in Tk 8.6:
>
> - http://wiki.tcl.tk/21276
> - http://www.tcl.tk/cgi-bin/tct/tip/403

Concise reference to the background information is very much
appreciated.  It would have been even nicer if you wrote one line
summary of it, e.g. "This change was to make Tk applications more in
line with Web standard colors."

> gitk looks pretty awkward with Tk 8.6. "green" is simply too dark now
> because it has changed from "#00FF00" to "#008000".

Your observation "awkward" is somewhat subjective and I am hesitant
to recommend this change without a better justification.  Given the
reasoning behind the change Tcl/Tk people made, I wouldn't be
surprised if people coming from webapp world view the "green" color
rendered by updated Tcl/Tk more natural.

Besides, if we are declaring with this patch that we will stick to
X11 colors and will not adopt W3C colors, the patch shouldn't update
only "green", but set all the other colors in stone, no?  "purple",
for example, is also different between X11 and W3C.

> One could also use "lime" instead of "#00FF00" but that would break
> compatibility with older versions of Tk.

A better solution might be to make these colors customizable.

> Signed-off-by: Peter Hofmann <git-dev@uninformativ.de>
> ---
>  gitk-git/gitk | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

Please make gitk patches against 

	url = git://ozlabs.org/~paulus/gitk.git

which is my upstream maintained by Paul Mackerras <paulus@samba.org>
(cc'ed) and keep him in the loop.

A patch against Paul's tree would have these lines

> diff --git a/gitk-git/gitk b/gitk-git/gitk
> index d93bd99..d7e922b 100755
> --- a/gitk-git/gitk
> +++ b/gitk-git/gitk

without "/gitk-git".

Thanks.

^ permalink raw reply

* Re: [PATCH v2] wt-status: Show ignored files in untracked dirs
From: Antoine Pelisse @ 2012-12-27 17:35 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20121227161920.GA28162@sigill.intra.peff.net>

> By "committed", I assume you meat that you have "dirA/unco" as an
> untracked file, and "dirA/committed" as a file in the index?

Of course,

> Thanks for putting this together. I agree with the expected output in
> each case, and I think this covers the cases we have seen (case 1 is
> Michael's original report, case 2 is what I wrote in my mail, and case 3
> is the one you just came up with). I can't think offhand of any others.

Great, so I can build some tests reflecting those behaviors while
waiting more inputs

^ permalink raw reply

* "fatal: git-write-tree: error building trees" from `git stash`
From: Alex Vandiver @ 2012-12-27 18:07 UTC (permalink / raw)
  To: git discussion list

  Heya,
I just ran into the following with `git stash`.  The set-up:

        git init
        echo "Initial" > foo
        git add .
        git commit -m 'Initial commit'
        echo "Rewrite" > foo
        git commit -am 'Second commit, rewrites content'
        echo "Stashed changes" >> foo
        git stash
        git co HEAD~
        
$ git stash pop
Auto-merging foo
CONFLICT (content): Merge conflict in foo
Recorded preimage for 'foo'

$ git stash
foo: needs merge
foo: needs merge
foo: unmerged (aeaa7e5e87cf309a7368d5d92a71c1f9e6a8c9e7)
foo: unmerged (a77fa514de2720c72c1a861de098595959a2c97a)
foo: unmerged (4a622d2b991f1a19ba7be313a46dc6f03692cd0a)
fatal: git-write-tree: error building trees
Cannot save the current index state

 - Alex

^ permalink raw reply

* Re: [PATCH v2] log: grep author/committer using mailmap
From: Junio C Hamano @ 2012-12-27 18:45 UTC (permalink / raw)
  To: Antoine Pelisse; +Cc: git
In-Reply-To: <1356622318-19523-1-git-send-email-apelisse@gmail.com>

Antoine Pelisse <apelisse@gmail.com> writes:

> Currently you can use mailmap to display log authors and committers
> but you can't use the mailmap to find commits with mapped values.
>
> This commit allows you to run:
>
>     git log --use-mailmap --author mapped_name_or_email
>     git log --use-mailmap --committer mapped_name_or_email
>
> Of course it only works if the --use-mailmap option is used.
>
> Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
> ---

Thanks.  I'll queue this on top.

-- >8 --
Subject: [PATCH] log --use-mailmap: optimize for cases without --author/--committer search

When we taught the commit_match() mechanism to pay attention to the
new --use-mailmap option, we started to unconditionally copy the
commit object to a temporary buffer, just in case we need the author
and committer lines updated via the mailmap mechanism.

It turns out that this has a rather unpleasant performance
implications.  In the linux kernel repository, running

  $ git log --author='Junio C Hamano' --pretty=short >/dev/null

under /usr/bin/time, with and without --use-mailmap (the .mailmap
file is 118 entries long, the particular author does not appear in
it), cost (with warm cache):

  [without --use-mailmap]
  5.34user 0.25system 0:05.60elapsed 100%CPU (0avgtext+0avgdata 2004832maxresident)k
  0inputs+0outputs (0major+137600minor)pagefaults 0swaps

  [with --use-mailmap]
  6.87user 0.24system 0:07.11elapsed 99%CPU (0avgtext+0avgdata 2006352maxresident)k
  0inputs+0outputs (0major+137696minor)pagefaults 0swaps

which is with about 29% overhead.  The command is doing extra work,
so the extra cost may be justified.

But it is inexcusable to pay the cost when we do not need
author/committer match.  In the same repository,

  $ git log --grep='fix menuconfig on debian lenny' --pretty=short >/dev/null

shows very similar numbers as the above:

  [without --use-mailmap]
  5.30user 0.24system 0:05.55elapsed 99%CPU (0avgtext+0avgdata 2004896maxresident)k
  0inputs+0outputs (0major+137604minor)pagefaults 0swaps

  [with --use-mailmap]
  6.82user 0.26system 0:07.07elapsed 100%CPU (0avgtext+0avgdata 2006352maxresident)k
  0inputs+0outputs (0major+137697minor)pagefaults 0swaps

The latter case is an unnecessary performance regression.  We may
want to _show_ the result with mailmap applied, but we do not have
to copy and rewrite the author/committer of all commits we try to
match if we do not query for these fields.

Trivially optimize this performace regression by limiting the
rewrites for only when we are matching with author/committer fields.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/revision.c b/revision.c
index fa16b9d..56b72f7 100644
--- a/revision.c
+++ b/revision.c
@@ -2283,7 +2283,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
 	if (buf.len)
 		strbuf_addstr(&buf, commit->buffer);
 
-	if (opt->mailmap) {
+	if (opt->grep_filter.header_list && opt->mailmap) {
 		if (!buf.len)
 			strbuf_addstr(&buf, commit->buffer);
 
-- 
1.8.1.rc3.221.g8d09d94

^ permalink raw reply related

* Re: [PATCH v2] log: grep author/committer using mailmap
From: Junio C Hamano @ 2012-12-27 18:48 UTC (permalink / raw)
  To: Antoine Pelisse; +Cc: git
In-Reply-To: <7v1uebmizx.fsf@alter.siamese.dyndns.org>

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

> Thanks.  I'll queue this on top.
>
> -- >8 --
> Subject: [PATCH] log --use-mailmap: optimize for cases without --author/--committer search

And this I will *not* queue further on top.

-- >8 --
Subject: [PATCH] [DO NOT USE] log --use-mailmap --author/--committer: further
 optimize identity rewriting

We used to always allocate a temporary buffer to search for
author/committer names even when the author/committer does not
appear in the mailmap.  Update the logic to do the allocation
on demand to reduce needless malloc()/free() calls.

It turns out that this does not affect performance at all; all the
time is spent in map_user() which is a look-up in string_list, so
let's not use this patch in the production, but it illustrates an
interesting point.

In map_identities() function, we already know who the author
recorded in the commit is, either in "author" strbuf, or in buffer
between [a_at..a_len], so we could grep_buffer() the author
regexp(s) specified from the command line right there, and combine
that result with the main grep_buffer() done for the --grep= option
at the end of the commit_match() function.

That may essentially amount to going in the totally opposite
direction from what 2d10c55 (git log: Unify header_filter and
message_filter into one., 2006-09-20) attempted to do.  We used to
have two grep expressions (one for header, the other one for body)
commit_match() runs grep_buffer() on and combined the results.
2d10c55 merged them into one grep expression by introducing a term
that matches only header elements.  But we would instead split the
"header" expression into "author" and "committer" expressions
(making it three from one) if we go that route.

In any case, I *think* the bottleneck is in map_user() so until that
is solved, such an update (or this patch) is not very useful.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c | 95 +++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 57 insertions(+), 38 deletions(-)

diff --git a/revision.c b/revision.c
index 56b72f7..4b66598 100644
--- a/revision.c
+++ b/revision.c
@@ -2220,49 +2220,73 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
 	return 0;
 }
 
-static int commit_rewrite_person(struct strbuf *buf, const char *what, struct string_list *mailmap)
+static void map_person(const char *buf, size_t len, const char *head, int headlen,
+		       struct strbuf *result, struct string_list *mailmap,
+		       int *matchofs, int *matchlen)
 {
-	char *person, *endp;
-	size_t len;
+	struct ident_split ident;
+	const char *endp, *person;
 	struct strbuf name = STRBUF_INIT;
 	struct strbuf mail = STRBUF_INIT;
-	struct ident_split ident;
 
-	person = strstr(buf->buf, what);
+	person = memmem(buf, len, head, headlen);
 	if (!person)
-		goto left_intact;
-
-	person += strlen(what);
+		return;
+	person += headlen;
 	endp = strchr(person, '\n');
 	if (!endp)
-		goto left_intact;
-
-	len = endp - person;
-
-	if (split_ident_line(&ident, person, len))
-		goto left_intact;
-
+		return;
+	*matchofs = person - buf;
+	*matchlen = endp - person;
+	if (split_ident_line(&ident, person, *matchlen))
+		return;
 	strbuf_add(&name, ident.name_begin, ident.name_end - ident.name_begin);
 	strbuf_add(&mail, ident.mail_begin, ident.mail_end - ident.mail_begin);
-
-	if (map_user(mailmap, &mail, &name)) {
-		strbuf_addf(&name, " <%s>", mail.buf);
-
-		strbuf_splice(buf, ident.name_begin - buf->buf,
-			      ident.mail_end - ident.name_begin + 1,
-			      name.buf, name.len);
-
-		strbuf_release(&name);
-		strbuf_release(&mail);
-
-		return 1;
-	}
-
-left_intact:
+	if (map_user(mailmap, &mail, &name))
+		strbuf_addf(result, "%s <%s>", name.buf, mail.buf);
 	strbuf_release(&name);
 	strbuf_release(&mail);
+}
 
-	return 0;
+static void map_identities(struct strbuf *buf, const char *buffer, struct string_list *mailmap)
+{
+	const char *eob;
+	struct strbuf author = STRBUF_INIT;
+	struct strbuf committer = STRBUF_INIT;
+	int a_at = -1, a_len, c_at = -1, c_len;
+
+	eob = strstr(buffer, "\n\n");
+	if (!eob)
+		eob = buffer + strlen(buffer);
+	map_person(buffer, eob - buffer, "\nauthor ", 8, &author, mailmap,
+		   &a_at, &a_len);
+	map_person(buffer, eob - buffer, "\ncommitter ", 11, &committer, mailmap,
+		   &c_at, &c_len);
+	if (!author.len && !committer.len)
+		goto done;
+
+	/* Now, we know we need rewriting */
+	if (!buf->len)
+		strbuf_addstr(buf, buffer);
+
+	if (c_at < 0 || !committer.len) {
+		strbuf_splice(buf, a_at, a_len, author.buf, author.len);
+	} else if (a_at < 0 || !author.len) {
+		strbuf_splice(buf, c_at, c_len, committer.buf, committer.len);
+	} else if (a_at < c_at) {
+		strbuf_splice(buf, c_at, c_len, committer.buf, committer.len);
+		strbuf_splice(buf, a_at, a_len, author.buf, author.len);
+	} else {
+		/*
+		 * The commit records committer before the author, which is malformed,
+		 * which we may want to warn about.
+		 */
+		strbuf_splice(buf, a_at, a_len, author.buf, author.len);
+		strbuf_splice(buf, c_at, c_len, committer.buf, committer.len);
+	}
+ done:
+	strbuf_release(&author);
+	strbuf_release(&committer);
 }
 
 static int commit_match(struct commit *commit, struct rev_info *opt)
@@ -2283,13 +2307,8 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
 	if (buf.len)
 		strbuf_addstr(&buf, commit->buffer);
 
-	if (opt->grep_filter.header_list && opt->mailmap) {
-		if (!buf.len)
-			strbuf_addstr(&buf, commit->buffer);
-
-		commit_rewrite_person(&buf, "\nauthor ", opt->mailmap);
-		commit_rewrite_person(&buf, "\ncommitter ", opt->mailmap);
-	}
+	if (opt->grep_filter.header_list && opt->mailmap)
+		map_identities(&buf, commit->buffer, opt->mailmap);
 
 	/* Append "fake" message parts as needed */
 	if (opt->show_notes) {
-- 
1.8.1.rc3.221.g8d09d94

^ permalink raw reply related

* Re: "fatal: git-write-tree: error building trees" from `git stash`
From: Junio C Hamano @ 2012-12-27 18:51 UTC (permalink / raw)
  To: Alex Vandiver; +Cc: git discussion list
In-Reply-To: <1356631626.13818.126.camel@umgah.localdomain>

Alex Vandiver <alex@chmrr.net> writes:

> Heya,
> I just ran into the following with `git stash`.  The set-up:
> ...
> $ git stash pop
> Auto-merging foo
> CONFLICT (content): Merge conflict in foo
> Recorded preimage for 'foo'
>
> $ git stash
> foo: needs merge
> foo: needs merge
> foo: unmerged (aeaa7e5e87cf309a7368d5d92a71c1f9e6a8c9e7)
> foo: unmerged (a77fa514de2720c72c1a861de098595959a2c97a)
> foo: unmerged (4a622d2b991f1a19ba7be313a46dc6f03692cd0a)
> fatal: git-write-tree: error building trees
> Cannot save the current index state

This is totally expected, isn't it?

You do not save state in the middle of a conflict with "git stash"
(instead, you would "git stash" away your own work in progress
before you start operation that may create and leave conflicts).

^ permalink raw reply

* Re: "fatal: git-write-tree: error building trees" from `git stash`
From: Alex Vandiver @ 2012-12-27 18:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git discussion list
In-Reply-To: <7vsj6rl456.fsf@alter.siamese.dyndns.org>

On Thu, 2012-12-27 at 10:51 -0800, Junio C Hamano wrote:
> > $ git stash
> > foo: needs merge
> > foo: needs merge
> > foo: unmerged (aeaa7e5e87cf309a7368d5d92a71c1f9e6a8c9e7)
> > foo: unmerged (a77fa514de2720c72c1a861de098595959a2c97a)
> > foo: unmerged (4a622d2b991f1a19ba7be313a46dc6f03692cd0a)
> > fatal: git-write-tree: error building trees
> > Cannot save the current index state
> 
> This is totally expected, isn't it?
> 
> You do not save state in the middle of a conflict with "git stash"
> (instead, you would "git stash" away your own work in progress
> before you start operation that may create and leave conflicts).

Apologies for not being clear.  While being unable to stash is not
unexpected, perhaps, "Cannot stash while resolving conflicts" or similar
would be more understandable to the end user than the above.
 - Alex

^ permalink raw reply

* Re: "fatal: git-write-tree: error building trees" from `git stash`
From: Jeff King @ 2012-12-27 19:05 UTC (permalink / raw)
  To: Alex Vandiver; +Cc: Junio C Hamano, git discussion list
In-Reply-To: <1356634556.13818.136.camel@umgah.localdomain>

On Thu, Dec 27, 2012 at 01:55:56PM -0500, Alex Vandiver wrote:

> On Thu, 2012-12-27 at 10:51 -0800, Junio C Hamano wrote:
> > > $ git stash
> > > foo: needs merge
> > > foo: needs merge
> > > foo: unmerged (aeaa7e5e87cf309a7368d5d92a71c1f9e6a8c9e7)
> > > foo: unmerged (a77fa514de2720c72c1a861de098595959a2c97a)
> > > foo: unmerged (4a622d2b991f1a19ba7be313a46dc6f03692cd0a)
> > > fatal: git-write-tree: error building trees
> > > Cannot save the current index state
> > 
> > This is totally expected, isn't it?
> > 
> > You do not save state in the middle of a conflict with "git stash"
> > (instead, you would "git stash" away your own work in progress
> > before you start operation that may create and leave conflicts).
> 
> Apologies for not being clear.  While being unable to stash is not
> unexpected, perhaps, "Cannot stash while resolving conflicts" or similar
> would be more understandable to the end user than the above.

Yeah, I think the outcome is reasonable, but that message is just
horrible. Something like this might be better:

diff --git a/git-stash.sh b/git-stash.sh
index 688e259..7ea425c 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -217,6 +217,12 @@ save_stash () {
 
 	stash_msg="$*"
 
+	if ! git diff-index --cached --diff-filter=U --quiet HEAD; then
+		echo >&2 "fatal: unable to stash unmerged entries:"
+		git diff-index --cached --diff-filter=U --name-status HEAD
+		exit 1
+	fi
+
 	git update-index -q --refresh
 	if no_changes
 	then

but I suspect it is not sufficient:

  1. There are other code paths that will end up in write-tree which
     should probably be protected, too.

  2. Unmerged entries are only one reason that write-tree might fail.
     It's OK not to catch them all (since ultimately write-tree will
     complain if need be), but we may want to also handle intent-to-add
     entries with a nicer message.

-Peff

^ permalink raw reply related

* Re: "fatal: git-write-tree: error building trees" from `git stash`
From: Junio C Hamano @ 2012-12-27 19:21 UTC (permalink / raw)
  To: Alex Vandiver; +Cc: git discussion list
In-Reply-To: <1356634556.13818.136.camel@umgah.localdomain>

Alex Vandiver <alex@chmrr.net> writes:

> ... "Cannot stash while resolving conflicts" or similar would be
> more understandable to the end user than the above.

Interestingly enough, the "apply" side is protected with this one
liner:

        # current index state
        c_tree=$(git write-tree) ||
                die "$(gettext "Cannot apply a stash in the middle of a merge")"

since 5fd448f (git stash: Give friendlier errors when there is
nothing to apply, 2009-08-11).  I would think something in line with
that change on the "create" side is a welcome one.

Thanks.

^ permalink raw reply


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