Git development
 help / color / mirror / Atom feed
* [PATCH] gc --aggressive: make it really aggressive
From: Johannes Schindelin @ 2007-12-06 12:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Daniel Berlin, David Miller, ismail, gcc, git, gitster
In-Reply-To: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>


The default was not to change the window or depth at all.  As suggested
by Jon Smirl, Linus Torvalds and others, default to

	--window=250 --depth=250

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	On Wed, 5 Dec 2007, Linus Torvalds wrote:

	> On Thu, 6 Dec 2007, Daniel Berlin wrote:
	> > 
	> > Actually, it turns out that git-gc --aggressive does this dumb 
	> > thing to pack files sometimes regardless of whether you 
	> > converted from an SVN repo or not.
	> 
	> Absolutely. git --aggressive is mostly dumb. It's really only 
	> useful for the case of "I know I have a *really* bad pack, and I 
	> want to throw away all the bad packing decisions I have done".
	>
	> [...]
	> 
	> So the equivalent of "git gc --aggressive" - but done *properly* 
	> - is to do (overnight) something like
	> 
	> 	git repack -a -d --depth=250 --window=250

	How about this, then?
	
 builtin-gc.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/builtin-gc.c b/builtin-gc.c
index 799c263..c6806d3 100644
--- a/builtin-gc.c
+++ b/builtin-gc.c
@@ -23,7 +23,7 @@ static const char * const builtin_gc_usage[] = {
 };
 
 static int pack_refs = 1;
-static int aggressive_window = -1;
+static int aggressive_window = 250;
 static int gc_auto_threshold = 6700;
 static int gc_auto_pack_limit = 20;
 
@@ -192,6 +192,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 
 	if (aggressive) {
 		append_option(argv_repack, "-f", MAX_ADD);
+		append_option(argv_repack, "--depth=250", MAX_ADD);
 		if (aggressive_window > 0) {
 			sprintf(buf, "--window=%d", aggressive_window);
 			append_option(argv_repack, buf, MAX_ADD);
-- 
1.5.3.7.2157.g9598e

^ permalink raw reply related

* Re: Git and GCC
From: Ismail Dönmez @ 2007-12-06 12:04 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: David Miller, dberlin, gcc, git
In-Reply-To: <Pine.LNX.4.64.0712061150590.27959@racer.site>

Thursday 06 December 2007 13:57:06 Johannes Schindelin yazmıştı:
[...]
> So I fully expect an issue like Daniel's to be resolved in a matter of
> minutes on the git list, if the OP gives us a chance.  If we are not even
> Cc'ed, you are completely right, she or he probably does not want the
> issue to be resolved.

Lets be fair about this, Ollie Wild already sent a mail about git-svn disk 
usage and there is no concrete solution yet, though it seems the bottleneck 
is known.

Regards,
ismail


-- 
Never learn by your mistakes, if you do you may never dare to try again.

^ permalink raw reply

* Re: Git and GCC
From: Johannes Schindelin @ 2007-12-06 11:57 UTC (permalink / raw)
  To: David Miller; +Cc: dberlin, ismail, gcc, git
In-Reply-To: <20071205.185203.262588544.davem@davemloft.net>

Hi,

On Wed, 5 Dec 2007, David Miller wrote:

> From: "Daniel Berlin" <dberlin@dberlin.org>
> Date: Wed, 5 Dec 2007 21:41:19 -0500
> 
> > It is true I gave up quickly, but this is mainly because i don't like 
> > to fight with my tools.
> >
> > I am quite fine with a distributed workflow, I now use 8 or so gcc 
> > branches in mercurial (auto synced from svn) and merge a lot between 
> > them. I wanted to see if git would sanely let me manage the commits 
> > back to svn.  After fighting with it, i gave up and just wrote a 
> > python extension to hg that lets me commit non-svn changesets back to 
> > svn directly from hg.
> 
> I find it ironic that you were even willing to write tools to facilitate 
> your hg based gcc workflow.  That really shows what your thinking is on 
> this matter, in that you're willing to put effort towards making hg work 
> better for you but you're not willing to expend that level of effort to 
> see if git can do so as well.

While this is true...

> This is what really eats me from the inside about your dissatisfaction 
> with git.  Your analysis seems to be a self-fullfilling prophecy, and 
> that's totally unfair to both hg and git.

... I actually appreciate people complaining -- in the meantime.  It shows 
right away what group you belong to in the "Those who can do, do, those 
who can't, complain.".

You can see that very easily on the git list, or on the #git channel on 
irc.freenode.net.  There is enough data for a study which yearns to be 
written, that shows how quickly we resolve issues with people that are 
sincerely interested in a solution.

(Of course, on the other hand, there are also quite a few cases which show 
how frustrating (for both sides) and unfruitful discussions started by a 
complaint are.)

So I fully expect an issue like Daniel's to be resolved in a matter of 
minutes on the git list, if the OP gives us a chance.  If we are not even 
Cc'ed, you are completely right, she or he probably does not want the 
issue to be resolved.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 3/2] core.whitespace: documentation updates.
From: Junio C Hamano @ 2007-12-06  9:04 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: git
In-Reply-To: <20071125215819.GD23820@fieldses.org>

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Sat, Nov 24, 2007 at 01:42:46PM -0800, Junio C Hamano wrote:
>> "J. Bruce Fields" <bfields@fieldses.org> writes:
>> 
>> > I'd still prefer this to be a gitattributes thing rather than a config
>> > variable[1].  Last time I raised this you said something to the effect
>> > of "I think you're right, let's fix that before it's merged."  Would you
>> > like me to work on that?
>> 
>> Ah, I forgot about that, and you are right.  Go wild.
>
> OK, I will go wild, but... very slowly.

How wild are you these days ;-)?  I know December is a busy time for
everybody, and I ended up doing this myself while I was writing up the
API documentation for gitattributes.

-- >8 --
[PATCH] Use gitattributes to define per-path whitespace rule

The `core.whitespace` configuration variable allows you to define what
`diff` and `apply` should consider whitespace errors for all paths in
the project (See gitlink:git-config[1]).  This attribute gives you finer
control per path.

For example, if you have these in the .gitattributes:

    frotz   whitespace
    nitfol  -whitespace
    xyzzy   whitespace=-trailing

all types of whitespace problems known to git are noticed in path 'frotz'
(i.e. diff shows them in diff.whitespace color, and apply warns about
them), no whitespace problem is noticed in path 'nitfol', and the
default types of whitespace problems except "trailing whitespace" are
noticed for path 'xyzzy'.  A project with mixed Python and C might want
to have:

    *.c    whitespace
    *.py   whitespace=-indent-with-non-tab

in its toplevel .gitattributes file.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/gitattributes.txt |   31 +++++++++++++
 Makefile                        |    2 +-
 builtin-apply.c                 |   36 +++++++++------
 cache.h                         |    4 +-
 config.c                        |   50 +--------------------
 diff.c                          |   19 +++++---
 environment.c                   |    2 +-
 t/t4019-diff-wserror.sh         |   47 +++++++++++++++++++
 t/t4124-apply-ws-rule.sh        |   20 ++++++++-
 ws.c                            |   96 +++++++++++++++++++++++++++++++++++++++
 10 files changed, 233 insertions(+), 74 deletions(-)
 create mode 100644 ws.c

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 20cf8ff..c4bcbb9 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -360,6 +360,37 @@ When left unspecified, the driver itself is used for both
 internal merge and the final merge.
 
 
+Checking whitespace errors
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`whitespace`
+^^^^^^^^^^^^
+
+The `core.whitespace` configuration variable allows you to define what
+`diff` and `apply` should consider whitespace errors for all paths in
+the project (See gitlink:git-config[1]).  This attribute gives you finer
+control per path.
+
+Set::
+
+	Notice all types of potential whitespace errors known to git.
+
+Unset::
+
+	Do not notice anything as error.
+
+Unspecified::
+
+	Use the value of `core.whitespace` configuration variable to
+	decide what to notice as error.
+
+String::
+
+	Specify a comma separate list of common whitespace problems to
+	notice in the same format as `core.whitespace` configuration
+	variable.
+
+
 EXAMPLE
 -------
 
diff --git a/Makefile b/Makefile
index 042f79e..ac6b079 100644
--- a/Makefile
+++ b/Makefile
@@ -312,7 +312,7 @@ LIB_OBJS = \
 	alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
 	color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
 	convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
-	transport.o bundle.o walker.o parse-options.o
+	transport.o bundle.o walker.o parse-options.o ws.o
 
 BUILTIN_OBJS = \
 	builtin-add.o \
diff --git a/builtin-apply.c b/builtin-apply.c
index 57efcd5..ee3ef60 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -144,6 +144,7 @@ struct patch {
 	unsigned int old_mode, new_mode;
 	int is_new, is_delete;	/* -1 = unknown, 0 = false, 1 = true */
 	int rejected;
+	unsigned ws_rule;
 	unsigned long deflate_origlen;
 	int lines_added, lines_deleted;
 	int score;
@@ -898,7 +899,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
 	return -1;
 }
 
-static void check_whitespace(const char *line, int len)
+static void check_whitespace(const char *line, int len, unsigned ws_rule)
 {
 	const char *err = "Adds trailing whitespace";
 	int seen_space = 0;
@@ -910,14 +911,14 @@ static void check_whitespace(const char *line, int len)
 	 * this function.  That is, an addition of an empty line would
 	 * check the '+' here.  Sneaky...
 	 */
-	if ((whitespace_rule & WS_TRAILING_SPACE) && isspace(line[len-2]))
+	if ((ws_rule & WS_TRAILING_SPACE) && isspace(line[len-2]))
 		goto error;
 
 	/*
 	 * Make sure that there is no space followed by a tab in
 	 * indentation.
 	 */
-	if (whitespace_rule & WS_SPACE_BEFORE_TAB) {
+	if (ws_rule & WS_SPACE_BEFORE_TAB) {
 		err = "Space in indent is followed by a tab";
 		for (i = 1; i < len; i++) {
 			if (line[i] == '\t') {
@@ -935,7 +936,7 @@ static void check_whitespace(const char *line, int len)
 	 * Make sure that the indentation does not contain more than
 	 * 8 spaces.
 	 */
-	if ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
+	if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
 	    (8 < len) && !strncmp("+        ", line, 9)) {
 		err = "Indent more than 8 places with spaces";
 		goto error;
@@ -1001,7 +1002,7 @@ static int parse_fragment(char *line, unsigned long size,
 		case '-':
 			if (apply_in_reverse &&
 			    ws_error_action != nowarn_ws_error)
-				check_whitespace(line, len);
+				check_whitespace(line, len, patch->ws_rule);
 			deleted++;
 			oldlines--;
 			trailing = 0;
@@ -1009,7 +1010,7 @@ static int parse_fragment(char *line, unsigned long size,
 		case '+':
 			if (!apply_in_reverse &&
 			    ws_error_action != nowarn_ws_error)
-				check_whitespace(line, len);
+				check_whitespace(line, len, patch->ws_rule);
 			added++;
 			newlines--;
 			trailing = 0;
@@ -1318,6 +1319,10 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
 	if (offset < 0)
 		return offset;
 
+	patch->ws_rule = whitespace_rule(patch->new_name
+					 ? patch->new_name
+					 : patch->old_name);
+
 	patchsize = parse_single_patch(buffer + offset + hdrsize,
 				       size - offset - hdrsize, patch);
 
@@ -1568,7 +1573,8 @@ static void remove_last_line(const char **rbuf, int *rsize)
 	*rsize = offset + 1;
 }
 
-static int apply_line(char *output, const char *patch, int plen)
+static int apply_line(char *output, const char *patch, int plen,
+		      unsigned ws_rule)
 {
 	/*
 	 * plen is number of bytes to be copied from patch,
@@ -1593,7 +1599,7 @@ static int apply_line(char *output, const char *patch, int plen)
 	/*
 	 * Strip trailing whitespace
 	 */
-	if ((whitespace_rule & WS_TRAILING_SPACE) &&
+	if ((ws_rule & WS_TRAILING_SPACE) &&
 	    (1 < plen && isspace(patch[plen-1]))) {
 		if (patch[plen] == '\n')
 			add_nl_to_tail = 1;
@@ -1610,12 +1616,12 @@ static int apply_line(char *output, const char *patch, int plen)
 		char ch = patch[i];
 		if (ch == '\t') {
 			last_tab_in_indent = i;
-			if ((whitespace_rule & WS_SPACE_BEFORE_TAB) &&
+			if ((ws_rule & WS_SPACE_BEFORE_TAB) &&
 			    0 <= last_space_in_indent)
 			    need_fix_leading_space = 1;
 		} else if (ch == ' ') {
 			last_space_in_indent = i;
-			if ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
+			if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
 			    last_tab_in_indent < 0 &&
 			    8 <= i)
 				need_fix_leading_space = 1;
@@ -1629,7 +1635,7 @@ static int apply_line(char *output, const char *patch, int plen)
 		int consecutive_spaces = 0;
 		int last = last_tab_in_indent + 1;
 
-		if (whitespace_rule & WS_INDENT_WITH_NON_TAB) {
+		if (ws_rule & WS_INDENT_WITH_NON_TAB) {
 			/* have "last" point at one past the indent */
 			if (last_tab_in_indent < last_space_in_indent)
 				last = last_space_in_indent + 1;
@@ -1671,7 +1677,7 @@ static int apply_line(char *output, const char *patch, int plen)
 }
 
 static int apply_one_fragment(struct strbuf *buf, struct fragment *frag,
-			      int inaccurate_eof)
+			      int inaccurate_eof, unsigned ws_rule)
 {
 	int match_beginning, match_end;
 	const char *patch = frag->patch;
@@ -1730,7 +1736,7 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag,
 		case '+':
 			if (first != '+' || !no_add) {
 				int added = apply_line(new + newsize, patch,
-						       plen);
+						       plen, ws_rule);
 				newsize += added;
 				if (first == '+' &&
 				    added == 1 && new[newsize-1] == '\n')
@@ -1953,12 +1959,14 @@ static int apply_fragments(struct strbuf *buf, struct patch *patch)
 {
 	struct fragment *frag = patch->fragments;
 	const char *name = patch->old_name ? patch->old_name : patch->new_name;
+	unsigned ws_rule = patch->ws_rule;
+	unsigned inaccurate_eof = patch->inaccurate_eof;
 
 	if (patch->is_binary)
 		return apply_binary(buf, patch);
 
 	while (frag) {
-		if (apply_one_fragment(buf, frag, patch->inaccurate_eof)) {
+		if (apply_one_fragment(buf, frag, inaccurate_eof, ws_rule)) {
 			error("patch failed: %s:%ld", name, frag->oldpos);
 			if (!apply_with_reject)
 				return -1;
diff --git a/cache.h b/cache.h
index 3f42827..9cc6268 100644
--- a/cache.h
+++ b/cache.h
@@ -610,6 +610,8 @@ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, i
 #define WS_SPACE_BEFORE_TAB	02
 #define WS_INDENT_WITH_NON_TAB	04
 #define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)
-extern unsigned whitespace_rule;
+extern unsigned whitespace_rule_cfg;
+extern unsigned whitespace_rule(const char *);
+extern unsigned parse_whitespace_rule(const char *);
 
 #endif /* CACHE_H */
diff --git a/config.c b/config.c
index d5b9766..2500e0d 100644
--- a/config.c
+++ b/config.c
@@ -246,54 +246,6 @@ static unsigned long get_unit_factor(const char *end)
 	die("unknown unit: '%s'", end);
 }
 
-static struct whitespace_rule {
-	const char *rule_name;
-	unsigned rule_bits;
-} whitespace_rule_names[] = {
-	{ "trailing-space", WS_TRAILING_SPACE },
-	{ "space-before-tab", WS_SPACE_BEFORE_TAB },
-	{ "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
-};
-
-static unsigned parse_whitespace_rule(const char *string)
-{
-	unsigned rule = WS_DEFAULT_RULE;
-
-	while (string) {
-		int i;
-		size_t len;
-		const char *ep;
-		int negated = 0;
-
-		string = string + strspn(string, ", \t\n\r");
-		ep = strchr(string, ',');
-		if (!ep)
-			len = strlen(string);
-		else
-			len = ep - string;
-
-		if (*string == '-') {
-			negated = 1;
-			string++;
-			len--;
-		}
-		if (!len)
-			break;
-		for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) {
-			if (strncmp(whitespace_rule_names[i].rule_name,
-				    string, len))
-				continue;
-			if (negated)
-				rule &= ~whitespace_rule_names[i].rule_bits;
-			else
-				rule |= whitespace_rule_names[i].rule_bits;
-			break;
-		}
-		string = ep;
-	}
-	return rule;
-}
-
 int git_parse_long(const char *value, long *ret)
 {
 	if (value && *value) {
@@ -480,7 +432,7 @@ int git_default_config(const char *var, const char *value)
 	}
 
 	if (!strcmp(var, "core.whitespace")) {
-		whitespace_rule = parse_whitespace_rule(value);
+		whitespace_rule_cfg = parse_whitespace_rule(value);
 		return 0;
 	}
 
diff --git a/diff.c b/diff.c
index 6bb902f..c3a1942 100644
--- a/diff.c
+++ b/diff.c
@@ -454,6 +454,7 @@ static void diff_words_show(struct diff_words_data *diff_words)
 struct emit_callback {
 	struct xdiff_emit_state xm;
 	int nparents, color_diff;
+	unsigned ws_rule;
 	const char **label_path;
 	struct diff_words_data *diff_words;
 	int *found_changesp;
@@ -493,8 +494,8 @@ static void emit_line(const char *set, const char *reset, const char *line, int
 }
 
 static void emit_line_with_ws(int nparents,
-		const char *set, const char *reset, const char *ws,
-		const char *line, int len)
+			      const char *set, const char *reset, const char *ws,
+			      const char *line, int len, unsigned ws_rule)
 {
 	int col0 = nparents;
 	int last_tab_in_indent = -1;
@@ -511,7 +512,7 @@ static void emit_line_with_ws(int nparents,
 	for (i = col0; i < len; i++) {
 		if (line[i] == '\t') {
 			last_tab_in_indent = i;
-			if ((whitespace_rule & WS_SPACE_BEFORE_TAB) &&
+			if ((ws_rule & WS_SPACE_BEFORE_TAB) &&
 			    0 <= last_space_in_indent)
 				need_highlight_leading_space = 1;
 		}
@@ -520,7 +521,7 @@ static void emit_line_with_ws(int nparents,
 		else
 			break;
 	}
-	if ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
+	if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
 	    0 <= last_space_in_indent &&
 	    last_tab_in_indent < 0 &&
 	    8 <= (i - col0)) {
@@ -551,7 +552,7 @@ static void emit_line_with_ws(int nparents,
 	tail = len - 1;
 	if (line[tail] == '\n' && i < tail)
 		tail--;
-	if (whitespace_rule & WS_TRAILING_SPACE) {
+	if (ws_rule & WS_TRAILING_SPACE) {
 		while (i < tail) {
 			if (!isspace(line[tail]))
 				break;
@@ -578,7 +579,7 @@ static void emit_add_line(const char *reset, struct emit_callback *ecbdata, cons
 		emit_line(set, reset, line, len);
 	else
 		emit_line_with_ws(ecbdata->nparents, set, reset, ws,
-				line, len);
+				  line, len, ecbdata->ws_rule);
 }
 
 static void fn_out_consume(void *priv, char *line, unsigned long len)
@@ -994,6 +995,7 @@ struct checkdiff_t {
 	struct xdiff_emit_state xm;
 	const char *filename;
 	int lineno, color_diff;
+	unsigned ws_rule;
 };
 
 static void checkdiff_consume(void *priv, char *line, unsigned long len)
@@ -1029,7 +1031,8 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
 			if (white_space_at_end)
 				printf("white space at end");
 			printf(":%s ", reset);
-			emit_line_with_ws(1, set, reset, ws, line, len);
+			emit_line_with_ws(1, set, reset, ws, line, len,
+					  data->ws_rule);
 		}
 
 		data->lineno++;
@@ -1330,6 +1333,7 @@ static void builtin_diff(const char *name_a,
 		ecbdata.label_path = lbl;
 		ecbdata.color_diff = o->color_diff;
 		ecbdata.found_changesp = &o->found_changes;
+		ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
 		xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
 		xecfg.ctxlen = o->context;
 		xecfg.flags = XDL_EMIT_FUNCNAMES;
@@ -1423,6 +1427,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
 	data.filename = name_b ? name_b : name_a;
 	data.lineno = 0;
 	data.color_diff = o->color_diff;
+	data.ws_rule = whitespace_rule(data.filename);
 
 	if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
 		die("unable to read files to diff");
diff --git a/environment.c b/environment.c
index 624dd96..2fbbc8e 100644
--- a/environment.c
+++ b/environment.c
@@ -35,7 +35,7 @@ int pager_in_use;
 int pager_use_color = 1;
 char *editor_program;
 int auto_crlf = 0;	/* 1: both ways, -1: only when adding git objects */
-unsigned whitespace_rule = WS_DEFAULT_RULE;
+unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 
 /* This is set by setup_git_dir_gently() and/or git_default_config() */
 char *git_work_tree_cfg;
diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh
index dbc895b..67e080b 100755
--- a/t/t4019-diff-wserror.sh
+++ b/t/t4019-diff-wserror.sh
@@ -45,8 +45,24 @@ test_expect_success 'without -trail' '
 
 '
 
+test_expect_success 'without -trail (attribute)' '
+
+	git config --unset core.whitespace
+	echo "F whitespace=-trail" >.gitattributes
+	git diff --color >output
+	grep "$blue_grep" output >error
+	grep -v "$blue_grep" output >normal
+
+	grep Eight normal >/dev/null &&
+	grep HT error >/dev/null &&
+	grep With normal >/dev/null &&
+	grep No normal >/dev/null
+
+'
+
 test_expect_success 'without -space' '
 
+	rm -f .gitattributes
 	git config core.whitespace -space
 	git diff --color >output
 	grep "$blue_grep" output >error
@@ -59,8 +75,24 @@ test_expect_success 'without -space' '
 
 '
 
+test_expect_success 'without -space (attribute)' '
+
+	git config --unset core.whitespace
+	echo "F whitespace=-space" >.gitattributes
+	git diff --color >output
+	grep "$blue_grep" output >error
+	grep -v "$blue_grep" output >normal
+
+	grep Eight normal >/dev/null &&
+	grep HT normal >/dev/null &&
+	grep With error >/dev/null &&
+	grep No normal >/dev/null
+
+'
+
 test_expect_success 'with indent-non-tab only' '
 
+	rm -f .gitattributes
 	git config core.whitespace indent,-trailing,-space
 	git diff --color >output
 	grep "$blue_grep" output >error
@@ -73,4 +105,19 @@ test_expect_success 'with indent-non-tab only' '
 
 '
 
+test_expect_success 'with indent-non-tab only (attribute)' '
+
+	git config --unset core.whitespace
+	echo "F whitespace=indent,-trailing,-space" >.gitattributes
+	git diff --color >output
+	grep "$blue_grep" output >error
+	grep -v "$blue_grep" output >normal
+
+	grep Eight error >/dev/null &&
+	grep HT normal >/dev/null &&
+	grep With normal >/dev/null &&
+	grep No normal >/dev/null
+
+'
+
 test_done
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index f53ac46..85f3da2 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -112,6 +112,15 @@ test_expect_success 'whitespace=error-all, no rule' '
 
 '
 
+test_expect_success 'whitespace=error-all, no rule (attribute)' '
+
+	git config --unset core.whitespace &&
+	echo "target -whitespace" >.gitattributes &&
+	apply_patch --whitespace=error-all &&
+	diff file target
+
+'
+
 for t in - ''
 do
 	case "$t" in '') tt='!' ;; *) tt= ;; esac
@@ -121,11 +130,20 @@ do
 		for i in - ''
 		do
 			case "$i" in '') ti='#' ;; *) ti= ;; esac
-			rule=${t}trailing,${s}space,${i}indent &&
+			rule=${t}trailing,${s}space,${i}indent
+
+			rm -f .gitattributes
 			test_expect_success "rule=$rule" '
 				git config core.whitespace "$rule" &&
 				test_fix "$tt$ts$ti"
 			'
+
+			test_expect_success "rule=$rule (attributes)" '
+				git config --unset core.whitespace &&
+				echo "target whitespace=$rule" >.gitattributes &&
+				test_fix "$tt$ts$ti"
+			'
+
 		done
 	done
 done
diff --git a/ws.c b/ws.c
new file mode 100644
index 0000000..52c10ca
--- /dev/null
+++ b/ws.c
@@ -0,0 +1,96 @@
+/*
+ * Whitespace rules
+ *
+ * Copyright (c) 2007 Junio C Hamano
+ */
+
+#include "cache.h"
+#include "attr.h"
+
+static struct whitespace_rule {
+	const char *rule_name;
+	unsigned rule_bits;
+} whitespace_rule_names[] = {
+	{ "trailing-space", WS_TRAILING_SPACE },
+	{ "space-before-tab", WS_SPACE_BEFORE_TAB },
+	{ "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
+};
+
+unsigned parse_whitespace_rule(const char *string)
+{
+	unsigned rule = WS_DEFAULT_RULE;
+
+	while (string) {
+		int i;
+		size_t len;
+		const char *ep;
+		int negated = 0;
+
+		string = string + strspn(string, ", \t\n\r");
+		ep = strchr(string, ',');
+		if (!ep)
+			len = strlen(string);
+		else
+			len = ep - string;
+
+		if (*string == '-') {
+			negated = 1;
+			string++;
+			len--;
+		}
+		if (!len)
+			break;
+		for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) {
+			if (strncmp(whitespace_rule_names[i].rule_name,
+				    string, len))
+				continue;
+			if (negated)
+				rule &= ~whitespace_rule_names[i].rule_bits;
+			else
+				rule |= whitespace_rule_names[i].rule_bits;
+			break;
+		}
+		string = ep;
+	}
+	return rule;
+}
+
+static void setup_whitespace_attr_check(struct git_attr_check *check)
+{
+	static struct git_attr *attr_whitespace;
+
+	if (!attr_whitespace)
+		attr_whitespace = git_attr("whitespace", 10);
+	check[0].attr = attr_whitespace;
+}
+
+unsigned whitespace_rule(const char *pathname)
+{
+	struct git_attr_check attr_whitespace_rule;
+
+	setup_whitespace_attr_check(&attr_whitespace_rule);
+	if (!git_checkattr(pathname, 1, &attr_whitespace_rule)) {
+		const char *value;
+
+		value = attr_whitespace_rule.value;
+		if (ATTR_TRUE(value)) {
+			/* true (whitespace) */
+			unsigned all_rule = 0;
+			int i;
+			for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++)
+				all_rule |= whitespace_rule_names[i].rule_bits;
+			return all_rule;
+		} else if (ATTR_FALSE(value)) {
+			/* false (-whitespace) */
+			return 0;
+		} else if (ATTR_UNSET(value)) {
+			/* reset to default (!whitespace) */
+			return whitespace_rule_cfg;
+		} else {
+			/* string */
+			return parse_whitespace_rule(value);
+		}
+	} else {
+		return whitespace_rule_cfg;
+	}
+}
-- 
1.5.3.7-2155-g4c25

^ permalink raw reply related

* Re: [BUG/PATCH] git grep shows the same hit repeatedly for unmerged paths
From: Junio C Hamano @ 2007-12-06  8:59 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git
In-Reply-To: <4757B1B9.2050606@viscovery.net>

Johannes Sixt <j.sixt@viscovery.net> writes:

> No, it doesn't. Neither before nor after this change. (I actually thought it
>  would without this change, but I obviously was wrong.)

Sorry, my mistake.  "git grep" traditionally skips unmerged paths.

It might make sense to grep in stage #2 if a path is unmerged, just like
we use stage #2 in diff-files.

^ permalink raw reply

* Re: [BUG/PATCH] git grep shows the same hit repeatedly for unmerged paths
From: Johannes Sixt @ 2007-12-06  8:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3auggs8x.fsf@gitster.siamese.dyndns.org>

Junio C Hamano schrieb:
> Johannes Sixt <j.sixt@viscovery.net> writes:
> 
>> Junio C Hamano schrieb:
>>> When the index is unmerged, e.g.
>>>
>>> 	$ git ls-files -u
>>>         100644 faf413748eb6ccb15161a212156c5e348302b1b6 1	setup.c
>>>         100644 145eca50f41d811c4c8fcb21ed2604e6b2971aba 2	setup.c
>>>         100644 cb9558c49b6027bf225ba2a6154c4d2a52bcdbe2 3	setup.c
>>>
>>> running "git grep" for work tree files repeats hits for each unmerged
>>> stage.
>>>
>>> 	$ git grep -n -e setup_work_tree -- '*.[ch]'
>>>         setup.c:209:void setup_work_tree(void)
>>>         setup.c:209:void setup_work_tree(void)
>>>         setup.c:209:void setup_work_tree(void)
>>>
>>> This should fix it.
>> Does this change the behavior of grep --cached? IOW, listing the same hit
>> more than once when --cached is given is a feature, IMHO.
> 
> Yeah, --cached should grep for each stage.  It doesn't?

No, it doesn't. Neither before nor after this change. (I actually thought it
 would without this change, but I obviously was wrong.)

-- Hannes

^ permalink raw reply

* Re: Git and GCC
From: David Brown @ 2007-12-06  8:11 UTC (permalink / raw)
  To: Harvey Harrison
  Cc: Linus Torvalds, Daniel Berlin, David Miller, ismail, gcc, git
In-Reply-To: <1196927361.13109.1.camel@brick>

On Wed, Dec 05, 2007 at 11:49:21PM -0800, Harvey Harrison wrote:
>
>> 	git repack -a -d --depth=250 --window=250
>> 
>
>Since I have the whole gcc repo locally I'll give this a shot overnight
>just to see what can be done at the extreme end or things.

When I tried this on a very large repo, at least one with some large files
in it, git quickly exceeded my physical memory and started thrashing the
machine.  I had good results with

  git config pack.deltaCacheSize 512m
  git config pack.windowMemory 512m

of course adjusting based on your physical memory.  I think changing the
windowMemory will affect the resulting compression, so changing these
ratios might get better compression out of the result.

If you're really patient, though, you could leave the unbounded window,
hope you have enough swap, and just let it run.

Dave

^ permalink raw reply

* Re: [BUG/PATCH] git grep shows the same hit repeatedly for unmerged paths
From: Junio C Hamano @ 2007-12-06  8:08 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git
In-Reply-To: <4757A4DD.901@viscovery.net>

Johannes Sixt <j.sixt@viscovery.net> writes:

> Junio C Hamano schrieb:
>> When the index is unmerged, e.g.
>> 
>> 	$ git ls-files -u
>>         100644 faf413748eb6ccb15161a212156c5e348302b1b6 1	setup.c
>>         100644 145eca50f41d811c4c8fcb21ed2604e6b2971aba 2	setup.c
>>         100644 cb9558c49b6027bf225ba2a6154c4d2a52bcdbe2 3	setup.c
>> 
>> running "git grep" for work tree files repeats hits for each unmerged
>> stage.
>> 
>> 	$ git grep -n -e setup_work_tree -- '*.[ch]'
>>         setup.c:209:void setup_work_tree(void)
>>         setup.c:209:void setup_work_tree(void)
>>         setup.c:209:void setup_work_tree(void)
>> 
>> This should fix it.
>
> Does this change the behavior of grep --cached? IOW, listing the same hit
> more than once when --cached is given is a feature, IMHO.

Yeah, --cached should grep for each stage.  It doesn't?

^ permalink raw reply

* Re: [PATCH v4] Allow update hooks to update refs on their own.
From: Steven Grimm @ 2007-12-06  7:50 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20071206063626.GA18698@coredump.intra.peff.net>

On Dec 5, 2007, at 10:36 PM, Jeff King wrote:
> Ah, I thought his argument was "we have to send back a bit, so why not
> just send the hash we made for informational purposes? It doesn't  
> hurt,
> and maybe we can make use of it later."

Yeah, that was more or less my thinking. Keep it simple for now, but  
it seems like that information is bound to be useful at some point. In  
particular, if you don't send it down, it's really difficult to  
unambiguously get back after the fact (given that a fetch might  
contain subsequent revisions unrelated to yours.)

My v3 patch (which I will combine with a modified form of the  
documentation update now that it sounds like transmitting the SHA1  
isn't objectionable) actually sent it down twice: once in the protocol  
message and once in the human-readable push status report.

-Steve

^ permalink raw reply

* Re: Git and GCC
From: Harvey Harrison @ 2007-12-06  7:49 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Daniel Berlin, David Miller, ismail, gcc, git
In-Reply-To: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>


> 	git repack -a -d --depth=250 --window=250
> 

Since I have the whole gcc repo locally I'll give this a shot overnight
just to see what can be done at the extreme end or things.

Harvey

^ permalink raw reply

* Re: [PATCH 2/3] git config --get-colorbool
From: Eric Wong @ 2007-12-06  7:38 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20071206053059.GF5499@coredump.intra.peff.net>

Jeff King <peff@peff.net> wrote:
> [Eric Wong cc'd because of git-svn relevance]
> 
> On Wed, Dec 05, 2007 at 06:05:04PM -0800, Junio C Hamano wrote:
> 
> > This adds an option to help scripts find out color settings from
> > the configuration file.
> > 
> >     git config --get-colorbool color.diff
> > 
> > inspects color.diff variable, and exits with status 0 (i.e. success) if
> > color is to be used.  It exits with status 1 otherwise.
> 
> There is no way to differentiate between "do not use color" and "no
> value found". This makes it impossible to use this to implement the
> required "try color.diff, fallback to diff.color" behavior.
> 
> We could simply make it
> 
>   git config --get-colorbool diff
> 
> which would check both (and when diff.color support is finally dropped,
> just remove it from there).
> 
> git-svn should probably be moved to this interface (it still has the
> color.diff == true means "always" behavior), but it can't be until the
> fallback behavior is implemented.
> 
> Also, your patch doesn't seem to implement the color.pager/pager.color
> behavior, either (which is probably not important for git-add -i, but is
> used by git-svn).
> 
> Anyway, below is a totally untested (I don't even have svn installed,
> but it passes perl -wc!) patch for git-svn to use the new "true means
> auto" behavior for color.diff. It would be nice to replace this with
> a working --get-colorbool, but we should at least unify the behavior
> before v1.5.4.

Hi Jeff,

I completely agree that the color behavior should be consistent across
git-*.  So I'd like to just be able to just use --get-colorbool in
git-svn.

Your patch seems to do what it says it does, though.

> -Peff
> 
> ---
> diff --git a/git-svn.perl b/git-svn.perl
> index 9f884eb..71f6e93 100755
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -3979,7 +3979,12 @@ sub log_use_color {
>  		$dc = `git-config --get $dcvar`;
>  	}
>  	chomp($dc);
> -	if ($dc eq 'auto') {
> +	return 0 if $dc eq 'never';
> +	return 1 if $dc eq 'always';
> +	if ($dc ne 'auto') {
> +		chomp($dc = `git-config --bool --get $dcvar`);
> +	}
> +	if ($dc eq 'auto' || $dc eq 'true') {
>  		my $pc;
>  		$pc = `git-config --get color.pager`;
>  		if ($pc eq '') {
> @@ -3998,10 +4003,7 @@ sub log_use_color {
>  		}
>  		return 0;
>  	}
> -	return 0 if $dc eq 'never';
> -	return 1 if $dc eq 'always';
> -	chomp($dc = `git-config --bool --get $dcvar`);
> -	return ($dc eq 'true');
> +	return 0;
>  }
>  
>  sub git_svn_log_cmd {
> -

-- 
Eric Wong

^ permalink raw reply

* Re: [BUG/PATCH] git grep shows the same hit repeatedly for unmerged paths
From: Johannes Sixt @ 2007-12-06  7:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vsl2gk7e3.fsf@gitster.siamese.dyndns.org>

Junio C Hamano schrieb:
> When the index is unmerged, e.g.
> 
> 	$ git ls-files -u
>         100644 faf413748eb6ccb15161a212156c5e348302b1b6 1	setup.c
>         100644 145eca50f41d811c4c8fcb21ed2604e6b2971aba 2	setup.c
>         100644 cb9558c49b6027bf225ba2a6154c4d2a52bcdbe2 3	setup.c
> 
> running "git grep" for work tree files repeats hits for each unmerged
> stage.
> 
> 	$ git grep -n -e setup_work_tree -- '*.[ch]'
>         setup.c:209:void setup_work_tree(void)
>         setup.c:209:void setup_work_tree(void)
>         setup.c:209:void setup_work_tree(void)
> 
> This should fix it.

Does this change the behavior of grep --cached? IOW, listing the same hit
more than once when --cached is given is a feature, IMHO.

-- Hannes

^ permalink raw reply

* Re: Git and GCC
From: Jeff King @ 2007-12-06  7:15 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Daniel Berlin, Harvey Harrison, David Miller, ismail, gcc, git
In-Reply-To: <9e4733910712052247x116cabb4q48ebafffb93f7e03@mail.gmail.com>

On Thu, Dec 06, 2007 at 01:47:54AM -0500, Jon Smirl wrote:

> The key to converting repositories of this size is RAM. 4GB minimum,
> more would be better. git-repack is not multi-threaded. There were a
> few attempts at making it multi-threaded but none were too successful.
> If I remember right, with loads of RAM, a repack on a 450MB repository
> was taking about five hours on a 2.8Ghz Core2. But this is something
> you only have to do once for the import. Later repacks will reuse the
> original deltas.

Actually, Nicolas put quite a bit of work into multi-threading the
repack process; the results have been in master for some time, and will
be in the soon-to-be-released v1.5.4.

The downside is that the threading partitions the object space, so the
resulting size is not necessarily as small (but I don't know that
anybody has done testing on large repos to find out how large the
difference is).

-Peff

^ permalink raw reply

* [PATCH] Open external merge tool with original file extensions for all three files
From: Pini Reznik @ 2007-12-06  7:06 UTC (permalink / raw)
  To: git; +Cc: Pini Reznik

Before this fix conflicted files were open in external merge
tool with temporal extensions like REMOTE.$$ and LOCAL.$$.
This way meld was unable to recognize these files and
syntax highlighting feature was unusable.

Signed-off-by: Pini Reznik <pinir@expand.com>
---
 git-mergetool.sh |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/git-mergetool.sh b/git-mergetool.sh
index 5587c5e..2f31fa2 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -152,10 +152,11 @@ merge_file () {
 	exit 1
     fi
 
-    BACKUP="$path.BACKUP.$$"
-    LOCAL="$path.LOCAL.$$"
-    REMOTE="$path.REMOTE.$$"
-    BASE="$path.BASE.$$"
+    ext="$$$(expr "$path" : '.*\(\.[^/]*\)$')"
+    BACKUP="$path.BACKUP.$ext"
+    LOCAL="$path.LOCAL.$ext"
+    REMOTE="$path.REMOTE.$ext"
+    BASE="$path.BASE.$ext"
 
     mv -- "$path" "$BACKUP"
     cp -- "$BACKUP" "$path"
-- 
1.5.3.5

^ permalink raw reply related

* Re: Git and GCC
From: Jon Smirl @ 2007-12-06  6:47 UTC (permalink / raw)
  To: Daniel Berlin; +Cc: Harvey Harrison, David Miller, ismail, gcc, git
In-Reply-To: <4aca3dc20712052117j3ef5cf99y848d4962ae8ddf33@mail.gmail.com>

On 12/6/07, Daniel Berlin <dberlin@dberlin.org> wrote:
> > While you won't get the git svn metadata if you clone the infradead
> > repo, it can be recreated on the fly by git svn if you want to start
> > commiting directly to gcc svn.
> >
> I will give this a try :)

Back when I was working on the Mozilla repository we were able to
convert the full 4GB CVS repository complete with all history into a
450MB pack file. That work is where the git-fastimport tool came from.
But it took a month of messing with the import tools to achieve this
and Mozilla still chose another VCS (mainly because of poor Windows
support in git).

Like Linus says, this type of command will yield the smallest pack file:
 git repack -a -d --depth=250 --window=250

I do agree that importing multi-gigabyte repositories is not a daily
occurrence nor a turn-key operation. There are significant issues when
translating from one VCS to another. The lack of global branch
tracking in CVS causes extreme problems on import. Hand editing of CVS
files also caused endless trouble.

The key to converting repositories of this size is RAM. 4GB minimum,
more would be better. git-repack is not multi-threaded. There were a
few attempts at making it multi-threaded but none were too successful.
If I remember right, with loads of RAM, a repack on a 450MB repository
was taking about five hours on a 2.8Ghz Core2. But this is something
you only have to do once for the import. Later repacks will reuse the
original deltas.

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* Re: git-svn: .git/svn disk usage
From: Eric Wong @ 2007-12-06  6:47 UTC (permalink / raw)
  To: Steven Grimm; +Cc: David Voit, git
In-Reply-To: <6D1288C9-8FD7-40CB-BA0B-0032F8D2DA6A@midwinter.com>

Steven Grimm <koreth@midwinter.com> wrote:
> How about using git itself to keep some of this information? I'll just  
> throw this idea out there; might or might not make any actual sense.
> 
> Create a new "git-svn metadata" branch. This branch contains a fake  
> directory (never intended for checkout, though you could do it) that  
> has a "file" for each svn revision. The filename is just the svn  
> revision number, maybe divided into subdirectories in case you want to  
> check the branch out for debugging purposes or whatever. The contents  
> are the git commit SHA1 and whatever other metadata you want to keep  
> in the future.
> 
> The advantage of doing it this way? You can pass around svn metadata  
> using the normal git fetch/push tools, query the metadata using "git  
> show", etc. In terms of data integrity, it's as secure as anything  
> else in a git repository, much more so than a separately maintained db  
> file under .git.

I've thought of doing the way you describe in the past, too.

However, a missing ref to the tree you proposed would mean that the
metadata becomes inaccessible unless git-svn-id: lines are retained.

Right now there's a single ref for all data and metadata.  Going to
two refs would mean those two refs would always need to be in sync
with each other.

The basic idea of the git-svn-id: lines is that with the default
settings, the .rev_db files are deletable and can be regenerated from
that metadata.  git-svn will automatically re-create .rev_db files it
cannot find.

This is why the rev_db code in git-svn uses slow, synchronous writes iff
svk props or no-metadata is enabled; and fast, assynchronous writes
when the user sticks with the git-svn defaults.

> Along similar lines, a separate branch where the filenames are commit  
> SHA1s and the file contents are the stuff that currently gets written  
> into the git-svn-id: lines would mean no more need to rewrite history  
> when doing dcommit, and thus easier mixing of native git workflows and  
> interactions with an svn repository.

The current dcommit still has the advantage that commit times match
those in the SVN repository.

> It would be great if you could clone a git-svn repository and then do  
> "git svn dcommit" from the clone, secure in the knowledge that things  
> will stay consistent even if the origin gets your changes via "git svn  
> fetch" rather than from you.

It's actually doable after the [svn-remote "..."] section .git/config is
copied and the refs/remotes/* structure is cloned via git.

The [svn-remote "..."] information can be regenerated based on
git-svn-id: lines (there's no automated way to do that, currently).

-- 
Eric Wong

^ permalink raw reply

* Re: [RFC] Mirroring svn
From: Harvey Harrison @ 2007-12-06  6:45 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20071206064317.GC18698@coredump.intra.peff.net>

On Thu, 2007-12-06 at 01:43 -0500, Jeff King wrote:
> On Wed, Dec 05, 2007 at 10:22:33PM -0800, Harvey Harrison wrote:
> 
> > // fetching someone else's remote branches is not a standard thing to do
> > // so we'll need to edit our .git/config file
> > // you should have a section that looks like:
> > [remote "gcc.gnu.org"]
> > 	url = git://git.infradead.org/gcc.git
> > 	fetch = +refs/heads/*:refs/remotes/gcc.gnu.org/*
> > // infradead's mirror puts the gcc svn branches in its own namespace
> > // refs/remotes/gcc.gnu.org/*
> > // change our fetch line accordingly
> > [remote "gcc.gnu.org"]
> > 	url = git://git.infradead.org/gcc.git
> > 	fetch = +refs/remotes/gcc.gnu.org/*:refs/remotes/gcc.gnu.org/*
> 
> FWIW, if you are writing a shell recipe for other people to cut and
> paste, you can say this as:
> 
>   git config remote.gcc.gnu.org.fetch \
>     '+refs/remotes/gcc.gnu.org/*:refs/remotes/gcc.gnu.org/*'

I thought about that, but I like to encourage people to actually look at
the config file, it's pretty easy to understand.

Harvey

^ permalink raw reply

* Re: [RFC] Mirroring svn
From: Jeff King @ 2007-12-06  6:43 UTC (permalink / raw)
  To: Harvey Harrison; +Cc: git
In-Reply-To: <1196922153.10408.101.camel@brick>

On Wed, Dec 05, 2007 at 10:22:33PM -0800, Harvey Harrison wrote:

> // fetching someone else's remote branches is not a standard thing to do
> // so we'll need to edit our .git/config file
> // you should have a section that looks like:
> [remote "gcc.gnu.org"]
> 	url = git://git.infradead.org/gcc.git
> 	fetch = +refs/heads/*:refs/remotes/gcc.gnu.org/*
> // infradead's mirror puts the gcc svn branches in its own namespace
> // refs/remotes/gcc.gnu.org/*
> // change our fetch line accordingly
> [remote "gcc.gnu.org"]
> 	url = git://git.infradead.org/gcc.git
> 	fetch = +refs/remotes/gcc.gnu.org/*:refs/remotes/gcc.gnu.org/*

FWIW, if you are writing a shell recipe for other people to cut and
paste, you can say this as:

  git config remote.gcc.gnu.org.fetch \
    '+refs/remotes/gcc.gnu.org/*:refs/remotes/gcc.gnu.org/*'

-Peff

^ permalink raw reply

* Re: [PATCH/RFC] Use regex for :/ matching
From: Jeff King @ 2007-12-06  6:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7vaboogwmq.fsf@gitster.siamese.dyndns.org>

On Wed, Dec 05, 2007 at 10:33:49PM -0800, Junio C Hamano wrote:

> Making what was string match to regex using the same syntax is a
> regression, isn't it?  I do not use :/ very often myself, so I
> personally would not mind but people who are used to using :/ may get
> upset about the change.  I do not feel strongly enough for changing it
> to regex to declare such a change unilaterally.

Yes, it is a regression, which is why my initial patch was labeled RFC.
Nobody commented on that aspect, so either they don't care, or (as you
often seem to find out) they will just complain later. :)

I am fine with adding it with a new syntax, but that is going to take
some thought, so perhaps it is better left to post-1.5.4.

-Peff

^ permalink raw reply

* Re: [PATCH v4] Allow update hooks to update refs on their own.
From: Jeff King @ 2007-12-06  6:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Steven Grimm, git
In-Reply-To: <7veje0gwru.fsf@gitster.siamese.dyndns.org>

On Wed, Dec 05, 2007 at 10:30:45PM -0800, Junio C Hamano wrote:

> The rebase would be "rebase --onto W' X Z", so it is not strictly
> necessary to keep the fact that X corresponds to X', but somehow I
> thought it was necessary, and Steven's message was hinting about that:
> 
>   > If we want that status in principle, I'd argue that sending down the
>   > updated commit SHA1 is actually the right way to indicate it, because
>   > it gives the client all the information it needs to make an
>   > intelligent choice about what to do next. If you don't transmit the
>   > modified SHA1, the client will have to do another fetch to find out
>   > what rewriting was done by the server, and if another push happened in
>   > the meantime, the client will have to basically guess about which
>   > commits correspond to the ones it pushed.
> 
> (notice the last part).
> 
> So if we want to transmit minimum amount of information, we can just
> send a bit ("the ref was rewritten") back to send-pack without telling
> it what X' is (but it would not hurt to send it back either).  With that
> one bit of information, send-pack can refrain from updating tracking ref
> from Y to X.

Ah, I thought his argument was "we have to send back a bit, so why not
just send the hash we made for informational purposes? It doesn't hurt,
and maybe we can make use of it later."

I was assuming that we were interested _only_ in fixing the send-pack
issues at this time, and that the rebasing or merging part of the
workflow would be figured out later. But it is probably sensible to
consider the whole workflow to see what is necessary at each step.

-Peff

^ permalink raw reply

* Re: [PATCH/RFC] Use regex for :/ matching
From: Junio C Hamano @ 2007-12-06  6:33 UTC (permalink / raw)
  To: Jeff King; +Cc: Johannes Schindelin, git
In-Reply-To: <20071206055200.GA23309@coredump.intra.peff.net>

Jeff King <peff@peff.net> writes:

> Obviously the overall design and usage of :/ is going to take some
> thinking and is not 1.5.4 material. However, we do have it in its
> current form, and I think regex versus prefix string matching is
> orthogonal to the range issues. Should I post my rebased :/ regex patch,
> or do you want to just leave it for post-1.5.4?

Making what was string match to regex using the same syntax is a
regression, isn't it?  I do not use :/ very often myself, so I
personally would not mind but people who are used to using :/ may get
upset about the change.  I do not feel strongly enough for changing it
to regex to declare such a change unilaterally.

^ permalink raw reply

* Re: [PATCH v4] Allow update hooks to update refs on their own.
From: Junio C Hamano @ 2007-12-06  6:30 UTC (permalink / raw)
  To: Jeff King; +Cc: Steven Grimm, git
In-Reply-To: <20071206055723.GB23309@coredump.intra.peff.net>

Jeff King <peff@peff.net> writes:

> On Wed, Dec 05, 2007 at 02:19:58PM -0800, Junio C Hamano wrote:
>
>> > what rewriting was done by the server, and if another push happened in
>> > the meantime, the client will have to basically guess about which
>> > commits correspond to the ones it pushed.
>> 
>> Ok, but the output from fetch is meant to be human readable and we do
>> not promise parsability, so if we go this route (which I think you made
>> a sensible argument for) we would need a hook on the pushing end to act
>> on this (perhaps record the correspondence of pushed and rewritten sha1
>> somewhere for the hook's own use).
>
> I am not clear on what you mean. Are you saying that the send-pack code
> should _not_ recognize the "ok, but I rewrote your commit" status?
> Because that is how we will avoid updating the tracking ref, which I
> think is a good goal.
>
> Or are you saying "it's ok to understand the 'ok, but...' response and
> not update the tracking ref, but pulling the new hash from the message
> is up to a hook on the pushing side"? Which I think it reasonable.
>
> Or alternatively, "there should be a hook on the pushing side which is
> allowed to set the ref status to 'ok, but don't bother updating the
> tracking ref' or 'ok, but here is the actual thing to put in the
> tracking ref'"? Which is also fine by me.

What I meant in response to what I thought Steven was talking about was
this.

 * With Steven's patch, the sending side needs to expect what it pushes
   to be rewritten.  If it starts with this history:

    ---o---o---o---Y---o---o---X

   where Y is what its remote tracking branch points at for the
   corresponding branch, three commits were built locally since the last
   fetch, and the sender pushes X.

 * Then the receiving end rewrites the history, making the history into
   this:

		     o'--o'--X'
                    /
    ---o---o---o---Y---o---o---X

 * Before the next fetch, the sending side can continue building on top
   of X, leading to this:

		     o'--o'--X'
                    /
    ---o---o---o---Y---o---o---X---o---Z

 * Similarly other people push into the same remote, get their commits
   rewritten and remote side's history becomes like this (but the
   original sender does not know about the upper history at all yet).

		     o'--o'--X'--o'--o'--W'
                    /
    ---o---o---o---Y---o---o---X---o---Z

 * Then the original sender fetches from the remote, now the tracking
   branch points at W' (it previously pointed at Y).  You would want to
   rebase your work since the last push on top of that tracking branch.

The rebase would be "rebase --onto W' X Z", so it is not strictly
necessary to keep the fact that X corresponds to X', but somehow I
thought it was necessary, and Steven's message was hinting about that:

  > If we want that status in principle, I'd argue that sending down the
  > updated commit SHA1 is actually the right way to indicate it, because
  > it gives the client all the information it needs to make an
  > intelligent choice about what to do next. If you don't transmit the
  > modified SHA1, the client will have to do another fetch to find out
  > what rewriting was done by the server, and if another push happened in
  > the meantime, the client will have to basically guess about which
  > commits correspond to the ones it pushed.

(notice the last part).

So if we want to transmit minimum amount of information, we can just
send a bit ("the ref was rewritten") back to send-pack without telling
it what X' is (but it would not hurt to send it back either).  With that
one bit of information, send-pack can refrain from updating tracking ref
from Y to X.

In the above scenario I illustrated, it turns out that getting
correspondence between X and X' is not strictly necessary to perform a
rebase later, but maybe there is some other scenario that keeping track
of that information would be helpful.  In such a case, a hook on the
send-pack end (which currently we do not have) can be called with X and
X' as parameters (and perhaps the name of the ref and the corresponding
tracking ref) to do whatever it wants to do with that information.

Even if we do not send X' back but just one bit, having that hook would
probably be needed so that sender can record "I've pushed up to X" and
perhaps "now I cannot push out Z until I rebase" after receiving "push
was accepted but rewritten" bit.

This is all handwaving --- I suspect for this to really work, send-pack
might need a pre-send-pack hook that pays attention to such "now I
cannot push out Z until I rebase" information the previous round of push
may have left and declines to push.  Of course, the receiving end would
would probably refuse such a push because it is not a fast-forward.

^ permalink raw reply

* [RFC] Mirroring svn
From: Harvey Harrison @ 2007-12-06  6:22 UTC (permalink / raw)
  To: git

After the discussions lately regarding the gcc svn mirror.  I'm coming
up with a recipe to set up your own git-svn mirror.  Suggestions on the
following.

// Create directory and initialize git
mkdir gcc
cd gcc
git init
// add the remote site that currently mirrors gcc
// I have chosen the name gcc.gnu.org *1* as my local name to refer to
// this choose something else if you like
git remote add gcc.gnu.org git://git.infradead.org/gcc.git
// fetching someone else's remote branches is not a standard thing to do
// so we'll need to edit our .git/config file
// you should have a section that looks like:
[remote "gcc.gnu.org"]
	url = git://git.infradead.org/gcc.git
	fetch = +refs/heads/*:refs/remotes/gcc.gnu.org/*
// infradead's mirror puts the gcc svn branches in its own namespace
// refs/remotes/gcc.gnu.org/*
// change our fetch line accordingly
[remote "gcc.gnu.org"]
	url = git://git.infradead.org/gcc.git
	fetch = +refs/remotes/gcc.gnu.org/*:refs/remotes/gcc.gnu.org/*
// fetch the remote data from the mirror site
git remote update
// set up git-svn
// gcc has the standard trunk/branches/tags naming so use -s
// add a prefix so git-svn uses the metadata we just got from the
// mirror so we don't have to get everything from the svn server
// the --prefix must match whatever you chose in *1*, the trailing
// slash is important.
git svn init -s --prefix=gcc.gnu.org/ svn://gcc.gnu.org/svn/gcc
// your config should look like this now:
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "gccmirror"]
	url = git://git.infradead.org/gcc.git
	fetch = +refs/heads/*:refs/remotes/gccmirror/*
[svn-remote "svn"]
	url = svn://gcc.gnu.org/svn/gcc
	fetch = trunk:refs/remotes/gcc.gnu.org/trunk
	branches = branches/*:refs/remotes/gcc.gnu.org/*
	tags = tags/*:refs/remotes/gcc.gnu.org/tags/*
// Try and get more revisions from the svn server
// this may take a little while the first time as git-svn builds
// metadata to allow bi-directional operation
git svn fetch


Happy Hacking

Harvey Harrison

^ permalink raw reply

* Re: [PATCH 2/3] git config --get-colorbool
From: Jeff King @ 2007-12-06  6:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Eric Wong, git
In-Reply-To: <7vve7cgxmw.fsf@gitster.siamese.dyndns.org>

On Wed, Dec 05, 2007 at 10:12:07PM -0800, Junio C Hamano wrote:

> I thought about this a bit and thought that it would probably be a good
> workaround to teach "--get-colorbool that diff.color is a deprecated
> synonym to color.diff, like this.

Reasonable. Technically, one is required for status.color/color.status,
as well, though there are no users in git-core.

-Peff

^ permalink raw reply

* Re: [PATCH] Make Git accept absolute path names for files within the work tree
From: Jeff King @ 2007-12-06  6:12 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Johannes Schindelin, Robin Rosenberg, Junio C Hamano,
	Anatol Pomozov, git
In-Reply-To: <alpine.LFD.0.9999.0712041444090.13796@woody.linux-foundation.org>

On Tue, Dec 04, 2007 at 02:52:15PM -0800, Linus Torvalds wrote:

> IOW, that whole thing is simply a bug waiting to happen. The fact that it 
> apparently *always* runs whether needed or not just seems to make it worse 
> (ie if we already know our cwd, and the absolute path we have already has 
> that as a prefix, just strip it off, don't try to do anything complex, and 
> leave the complex and fragile cases for the odd-ball when the simple 
> approach doesn't work)

Fair enough. Something like this then? It gets called only as a
last-ditch (though I think the 'return path' should simply be a die
-- what is the point of getting a pathspec that isn't in the repo?).

---
diff --git a/setup.c b/setup.c
index 4ee8024..fbb956e 100644
--- a/setup.c
+++ b/setup.c
@@ -5,13 +5,17 @@ static int inside_git_dir = -1;
 static int inside_work_tree = -1;
 
 static
-const char *strip_work_tree_path(const char *prefix, int len, const char *path)
+const char *strip_work_tree_path(const char *prefix, int len, const char *path,
+		int canonicalized)
 {
 	const char *work_tree = get_git_work_tree();
 	int n = strlen(work_tree);
 
 	if (strncmp(path, work_tree, n))
-		return path;
+		return canonicalized ?
+			path :
+			strip_work_tree_path(prefix, len,
+					xstrdup(make_absolute_path(path)), 1);
 
 	if (!prefix && !path[n])
 		return path + n;
@@ -58,7 +62,7 @@ const char *prefix_path(const char *prefix, int len, const char *path)
 {
 	const char *orig = path;
 	if (is_absolute_path(path))
-		path = strip_work_tree_path(prefix, len, path);
+		path = strip_work_tree_path(prefix, len, path, 0);
 
 	for (;;) {
 		char c;

^ 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