Git development
 help / color / mirror / Atom feed
* Re: [PATCH 4/4] teach config parsing to read from strbuf
From: Heiko Voigt @ 2013-03-10 16:39 UTC (permalink / raw)
  To: Ramsay Jones; +Cc: Junio C Hamano, git, Jens Lehmann, Jeff King
In-Reply-To: <5138DFA3.8040308@ramsay1.demon.co.uk>

Hi,

On Thu, Mar 07, 2013 at 06:42:43PM +0000, Ramsay Jones wrote:
> Heiko Voigt wrote:
> > +int git_config_from_strbuf(config_fn_t fn, struct strbuf *strbuf, void *data)
> > +{
> > +	struct config top;
> > +	struct config_strbuf str;
> > +
> > +	str.strbuf = strbuf;
> > +	str.pos = 0;
> > +
> > +	top.data = &str;
> 
> You will definitely want to initialise 'top.name' here, rather
> than let it take whatever value happens to be at that position
> on the stack. In your editor, search for 'cf->name' and contemplate
> each such occurrence.

Good catch, thanks. The initialization seems to got lost during
refactoring. In the codepaths we call with the new strbuf function it is
only used for error reporting so I think we need to get the name from
the user of this function so the error messages are useful.

I have extended the test to demonstrate how I imagine this name could
look like.

> Does the 'include' facility work from a strbuf? Should it?

No the 'include' facility does not work here. A special handling would
need to be implemented by the caller. For us 'include' values have no
special meaning and are parsed like normal values.

AFAICS when a config file is given to git config we do not currently
respect includes. So we can just do the same behavior here for the
moment. There is no roadblock against adding it later.

> Are you happy with the error handling/reporting?

Good point, while adding the name for strbuf I noticed that we currently
die on some parsing errors. We should probably make these errors
handleable for strbufs. Currently the main usecase is to read submodule
configurations from the database and in case someone commits a broken
configuration we should be able to continue with that. Otherwise the
repository might render into an unuseable state. I will look into that.

> Do the above additions to the test-suite give you confidence
> that the code works as you intend?

Well, I am reusing most of the existing infrastructure which I assume is
tested using config files. So what I want to test here is the
integration of this new function. As you mentioned the name variable I
have now added a test for the parsing error case as well. I have
refactored the test binary to read configs from stdin so its easiert to
implement further tests from the bash part of the testsuite.

I will send out another iteration shortly.

Cheers Heiko

^ permalink raw reply

* [PATCH v2 0/4] allow more sources for config values
From: Heiko Voigt @ 2013-03-10 16:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jens Lehmann, Jeff King, Ramsay Jones

The following issues still exist:

 * Error handling: If this should be useful to interrogate configs from
   the database during git operations we need a way to recover from
   parsing errors instead of dying.

 * More tests ?

This is an update with the comments of the first iteration[1]
incorporated.

[1] http://thread.gmane.org/gmane.comp.version-control.git/217018/

Heiko Voigt (4):
  config: factor out config file stack management
  config: drop file pointer validity check in get_next_char()
  config: make parsing stack struct independent from actual data source
  teach config parsing to read from strbuf

 .gitignore             |   1 +
 Makefile               |   1 +
 cache.h                |   2 +
 config.c               | 143 ++++++++++++++++++++++++++++++++++++++-----------
 t/t1300-repo-config.sh |  24 +++++++++
 test-config.c          |  40 ++++++++++++++
 6 files changed, 180 insertions(+), 31 deletions(-)
 create mode 100644 test-config.c

-- 
1.8.2.rc0.26.gf7384c5

^ permalink raw reply

* [PATCH v2 1/4] config: factor out config file stack management
From: Heiko Voigt @ 2013-03-10 16:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jens Lehmann, Jeff King, Ramsay Jones
In-Reply-To: <20130310165642.GA1136@sandbox-ub.fritz.box>

Because a config callback may start parsing a new file, the
global context regarding the current config file is stored
as a stack. Currently we only need to manage that stack from
git_config_from_file. Let's factor it out to allow new
sources of config data.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
 config.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/config.c b/config.c
index aefd80b..2c299dc 100644
--- a/config.c
+++ b/config.c
@@ -896,6 +896,28 @@ int git_default_config(const char *var, const char *value, void *dummy)
 	return 0;
 }
 
+static int do_config_from(struct config_file *top, config_fn_t fn, void *data)
+{
+	int ret;
+
+	/* push config-file parsing state stack */
+	top->prev = cf;
+	top->linenr = 1;
+	top->eof = 0;
+	strbuf_init(&top->value, 1024);
+	strbuf_init(&top->var, 1024);
+	cf = top;
+
+	ret = git_parse_file(fn, data);
+
+	/* pop config-file parsing state stack */
+	strbuf_release(&top->value);
+	strbuf_release(&top->var);
+	cf = top->prev;
+
+	return ret;
+}
+
 int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 {
 	int ret;
@@ -905,22 +927,10 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 	if (f) {
 		config_file top;
 
-		/* push config-file parsing state stack */
-		top.prev = cf;
 		top.f = f;
 		top.name = filename;
-		top.linenr = 1;
-		top.eof = 0;
-		strbuf_init(&top.value, 1024);
-		strbuf_init(&top.var, 1024);
-		cf = &top;
-
-		ret = git_parse_file(fn, data);
-
-		/* pop config-file parsing state stack */
-		strbuf_release(&top.value);
-		strbuf_release(&top.var);
-		cf = top.prev;
+
+		ret = do_config_from(&top, fn, data);
 
 		fclose(f);
 	}
-- 
1.8.2.rc0.26.gf7384c5

^ permalink raw reply related

* [PATCH v2 2/4] config: drop file pointer validity check in get_next_char()
From: Heiko Voigt @ 2013-03-10 16:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jens Lehmann, Jeff King, Ramsay Jones
In-Reply-To: <20130310165642.GA1136@sandbox-ub.fritz.box>

The only location where cf is set in this file is in do_config_from().
This function has only one callsite which is config_from_file(). In
config_from_file() its ensured that the f member is set to non-zero.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
 config.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/config.c b/config.c
index 2c299dc..f55c43d 100644
--- a/config.c
+++ b/config.c
@@ -169,10 +169,10 @@ int git_config_from_parameters(config_fn_t fn, void *data)
 static int get_next_char(void)
 {
 	int c;
-	FILE *f;
 
 	c = '\n';
-	if (cf && ((f = cf->f) != NULL)) {
+	if (cf) {
+		FILE *f = cf->f;
 		c = fgetc(f);
 		if (c == '\r') {
 			/* DOS like systems */
-- 
1.8.2.rc0.26.gf7384c5

^ permalink raw reply related

* [PATCH v2 3/4] config: make parsing stack struct independent from actual data source
From: Heiko Voigt @ 2013-03-10 16:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jens Lehmann, Jeff King, Ramsay Jones
In-Reply-To: <20130310165642.GA1136@sandbox-ub.fritz.box>

To simplify adding other sources we extract all functions needed for
parsing into a list of callbacks. We implement those callbacks for the
current file parsing. A new source can implement its own set of callbacks.

Instead of storing the concrete FILE pointer for parsing we store a void
pointer. A new source can use this to store its custom data.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
 config.c | 63 +++++++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 43 insertions(+), 20 deletions(-)

diff --git a/config.c b/config.c
index f55c43d..fe1c0e5 100644
--- a/config.c
+++ b/config.c
@@ -10,20 +10,42 @@
 #include "strbuf.h"
 #include "quote.h"
 
-typedef struct config_file {
-	struct config_file *prev;
-	FILE *f;
+struct config_source {
+	struct config_source *prev;
+	void *data;
 	const char *name;
 	int linenr;
 	int eof;
 	struct strbuf value;
 	struct strbuf var;
-} config_file;
 
-static config_file *cf;
+	int (*fgetc)(struct config_source *c);
+	int (*ungetc)(int c, struct config_source *conf);
+	long (*ftell)(struct config_source *c);
+};
+
+static struct config_source *cf;
 
 static int zlib_compression_seen;
 
+static int config_file_fgetc(struct config_source *conf)
+{
+	FILE *f = conf->data;
+	return fgetc(f);
+}
+
+static int config_file_ungetc(int c, struct config_source *conf)
+{
+	FILE *f = conf->data;
+	return ungetc(c, f);
+}
+
+static long config_file_ftell(struct config_source *conf)
+{
+	FILE *f = conf->data;
+	return ftell(f);
+}
+
 #define MAX_INCLUDE_DEPTH 10
 static const char include_depth_advice[] =
 "exceeded maximum include depth (%d) while including\n"
@@ -172,13 +194,12 @@ static int get_next_char(void)
 
 	c = '\n';
 	if (cf) {
-		FILE *f = cf->f;
-		c = fgetc(f);
+		c = cf->fgetc(cf);
 		if (c == '\r') {
 			/* DOS like systems */
-			c = fgetc(f);
+			c = cf->fgetc(cf);
 			if (c != '\n') {
-				ungetc(c, f);
+				cf->ungetc(c, cf);
 				c = '\r';
 			}
 		}
@@ -339,7 +360,7 @@ static int get_base_var(struct strbuf *name)
 	}
 }
 
-static int git_parse_file(config_fn_t fn, void *data)
+static int git_parse_source(config_fn_t fn, void *data)
 {
 	int comment = 0;
 	int baselen = 0;
@@ -896,7 +917,7 @@ int git_default_config(const char *var, const char *value, void *dummy)
 	return 0;
 }
 
-static int do_config_from(struct config_file *top, config_fn_t fn, void *data)
+static int do_config_from_source(struct config_source *top, config_fn_t fn, void *data)
 {
 	int ret;
 
@@ -908,7 +929,7 @@ static int do_config_from(struct config_file *top, config_fn_t fn, void *data)
 	strbuf_init(&top->var, 1024);
 	cf = top;
 
-	ret = git_parse_file(fn, data);
+	ret = git_parse_source(fn, data);
 
 	/* pop config-file parsing state stack */
 	strbuf_release(&top->value);
@@ -925,12 +946,15 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 
 	ret = -1;
 	if (f) {
-		config_file top;
+		struct config_source top;
 
-		top.f = f;
+		top.data = f;
 		top.name = filename;
+		top.fgetc = config_file_fgetc;
+		top.ungetc = config_file_ungetc;
+		top.ftell = config_file_ftell;
 
-		ret = do_config_from(&top, fn, data);
+		ret = do_config_from_source(&top, fn, data);
 
 		fclose(f);
 	}
@@ -1063,7 +1087,6 @@ static int store_aux(const char *key, const char *value, void *cb)
 {
 	const char *ep;
 	size_t section_len;
-	FILE *f = cf->f;
 
 	switch (store.state) {
 	case KEY_SEEN:
@@ -1075,7 +1098,7 @@ static int store_aux(const char *key, const char *value, void *cb)
 				return 1;
 			}
 
-			store.offset[store.seen] = ftell(f);
+			store.offset[store.seen] = cf->ftell(cf);
 			store.seen++;
 		}
 		break;
@@ -1102,19 +1125,19 @@ static int store_aux(const char *key, const char *value, void *cb)
 		 * Do not increment matches: this is no match, but we
 		 * just made sure we are in the desired section.
 		 */
-		store.offset[store.seen] = ftell(f);
+		store.offset[store.seen] = cf->ftell(cf);
 		/* fallthru */
 	case SECTION_END_SEEN:
 	case START:
 		if (matches(key, value)) {
-			store.offset[store.seen] = ftell(f);
+			store.offset[store.seen] = cf->ftell(cf);
 			store.state = KEY_SEEN;
 			store.seen++;
 		} else {
 			if (strrchr(key, '.') - key == store.baselen &&
 			      !strncmp(key, store.key, store.baselen)) {
 					store.state = SECTION_SEEN;
-					store.offset[store.seen] = ftell(f);
+					store.offset[store.seen] = cf->ftell(cf);
 			}
 		}
 	}
-- 
1.8.2.rc0.26.gf7384c5

^ permalink raw reply related

* [PATCH v2 4/4] teach config parsing to read from strbuf
From: Heiko Voigt @ 2013-03-10 17:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jens Lehmann, Jeff King, Ramsay Jones
In-Reply-To: <20130310165642.GA1136@sandbox-ub.fritz.box>

This can be used to read configuration values directly from gits
database.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---
 .gitignore             |  1 +
 Makefile               |  1 +
 cache.h                |  2 ++
 config.c               | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 t/t1300-repo-config.sh | 24 ++++++++++++++++++++++++
 test-config.c          | 40 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+)
 create mode 100644 test-config.c

diff --git a/.gitignore b/.gitignore
index 6669bf0..386b7f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -178,6 +178,7 @@
 /gitweb/static/gitweb.min.*
 /test-chmtime
 /test-ctype
+/test-config
 /test-date
 /test-delta
 /test-dump-cache-tree
diff --git a/Makefile b/Makefile
index 26d3332..1a9ea10 100644
--- a/Makefile
+++ b/Makefile
@@ -541,6 +541,7 @@ PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
 TEST_PROGRAMS_NEED_X += test-chmtime
 TEST_PROGRAMS_NEED_X += test-ctype
+TEST_PROGRAMS_NEED_X += test-config
 TEST_PROGRAMS_NEED_X += test-date
 TEST_PROGRAMS_NEED_X += test-delta
 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
diff --git a/cache.h b/cache.h
index e493563..a2621fa 100644
--- a/cache.h
+++ b/cache.h
@@ -1128,6 +1128,8 @@ extern int update_server_info(int);
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int git_default_config(const char *, const char *, void *);
 extern int git_config_from_file(config_fn_t fn, const char *, void *);
+extern int git_config_from_strbuf(config_fn_t fn, const char *name,
+				  struct strbuf *strbuf, void *data);
 extern void git_config_push_parameter(const char *text);
 extern int git_config_from_parameters(config_fn_t fn, void *data);
 extern int git_config(config_fn_t fn, void *);
diff --git a/config.c b/config.c
index fe1c0e5..b8c8640 100644
--- a/config.c
+++ b/config.c
@@ -46,6 +46,37 @@ static long config_file_ftell(struct config_source *conf)
 	return ftell(f);
 }
 
+struct config_strbuf {
+	struct strbuf *strbuf;
+	int pos;
+};
+
+static int config_strbuf_fgetc(struct config_source *conf)
+{
+	struct config_strbuf *str = conf->data;
+
+	if (str->pos < str->strbuf->len)
+		return str->strbuf->buf[str->pos++];
+
+	return EOF;
+}
+
+static int config_strbuf_ungetc(int c, struct config_source *conf)
+{
+	struct config_strbuf *str = conf->data;
+
+	if (str->pos > 0)
+		return str->strbuf->buf[--str->pos];
+
+	return EOF;
+}
+
+static long config_strbuf_ftell(struct config_source *conf)
+{
+	struct config_strbuf *str = conf->data;
+	return str->pos;
+}
+
 #define MAX_INCLUDE_DEPTH 10
 static const char include_depth_advice[] =
 "exceeded maximum include depth (%d) while including\n"
@@ -961,6 +992,23 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 	return ret;
 }
 
+int git_config_from_strbuf(config_fn_t fn, const char *name, struct strbuf *strbuf, void *data)
+{
+	struct config_source top;
+	struct config_strbuf str;
+
+	str.strbuf = strbuf;
+	str.pos = 0;
+
+	top.data = &str;
+	top.name = name;
+	top.fgetc = config_strbuf_fgetc;
+	top.ungetc = config_strbuf_ungetc;
+	top.ftell = config_strbuf_ftell;
+
+	return do_config_from_source(&top, fn, data);
+}
+
 const char *git_etc_gitconfig(void)
 {
 	static const char *system_wide;
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 3c96fda..5103f66 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -1087,4 +1087,28 @@ test_expect_success 'barf on incomplete string' '
 	grep " line 3 " error
 '
 
+test_expect_success 'reading config from strbuf' '
+	cat >expect <<-\EOF &&
+	var: some.value, value: content
+	EOF
+	test-config strbuf 12345:.gitmodules >actual <<-\EOF &&
+	[some]
+		value = content
+	EOF
+	test_cmp expect actual
+'
+
+test_expect_success 'reading config from strbuf with error' '
+	touch expect.out &&
+	cat >expect.err <<-\EOF &&
+	fatal: bad config file line 2 in 12345:.gitmodules
+	EOF
+	test_must_fail test-config strbuf 12345:.gitmodules >actual.out 2>actual.err <<-\EOF &&
+	[some]
+		value = "
+	EOF
+	test_cmp expect.out actual.out &&
+	test_cmp expect.err actual.err
+'
+
 test_done
diff --git a/test-config.c b/test-config.c
new file mode 100644
index 0000000..c650837
--- /dev/null
+++ b/test-config.c
@@ -0,0 +1,40 @@
+#include "cache.h"
+
+static int config_strbuf(const char *var, const char *value, void *data)
+{
+	printf("var: %s, value: %s\n", var, value);
+
+	return 1;
+}
+
+static void die_usage(int argc, char **argv)
+{
+	fprintf(stderr, "Usage: %s strbuf <name>\n", argv[0]);
+	exit(1);
+}
+
+int main(int argc, char **argv)
+{
+	if (argc < 3)
+		die_usage(argc, argv);
+
+	if (!strcmp(argv[1], "strbuf")) {
+		struct strbuf buf = STRBUF_INIT;
+		const char *name = argv[2];
+
+		while (strbuf_fread(&buf, 1024, stdin) == 1024)
+			;
+
+		if (ferror(stdin))
+			die("An error occurred while reading from stdin");
+
+		git_config_from_strbuf(config_strbuf, name, &buf, NULL);
+		strbuf_release(&buf);
+
+		return 0;
+	}
+
+	die_usage(argc, argv);
+
+	return 1;
+}
-- 
1.8.2.rc0.26.gf7384c5

^ permalink raw reply related

* Re: Merging submodules - best merge-base
From: Heiko Voigt @ 2013-03-10 17:09 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Daniel Bratell, git
In-Reply-To: <513B7554.4020700@web.de>

On Sat, Mar 09, 2013 at 06:45:56PM +0100, Jens Lehmann wrote:
> Am 07.03.2013 19:59, schrieb Heiko Voigt:
> > On Thu, Mar 07, 2013 at 10:49:09AM +0100, Daniel Bratell wrote:
> >> Den 2013-03-06 19:12:05 skrev Heiko Voigt <hvoigt@hvoigt.net>:
> >>> So to summarize what you are requesting: You want a submodule merge be
> >>> two way in the view of the superproject and calculate the merge base
> >>> in the submodule from the two commits that are going to be merged?
> >>>
> >>> It currently sounds logical but I have to think about it further and
> >>> whether that might break other use cases.
> >>
> >> Maybe both could be legal even. The current code can't be all wrong,
> >> and this case also seems to be straightforward.
> > 
> > Ok I have thought about it further and I did not come up with a simple
> > (and stable) enough strategy that would allow your use case to merge
> > cleanly without user interaction.
> > 
> > The problem is that your are actually doing a rewind from base to both
> > tips. The fact that a rewind is there makes git suspicious and we simply
> > give up. IMO, thats the right thing to do in such a situation.
> > 
> > What should a merge strategy do? It infers from two changes what the
> > final intention might be. For submodules we can do that when the changes
> > on both sides point forward. Since thats the typical progress of
> > development. If not there is some reason for it we do not know about. So
> > the merge gives up.
> > 
> > Please see this post about why we need to forbid rewinds from the
> > initial design discussion:
> > 
> > http://article.gmane.org/gmane.comp.version-control.git/149003
> 
> I agree that rewinds are a very good reason not merge two branches using
> a fast-forward strategy, but I believe Daniel's use case is a (and maybe
> the only) valid exception to that rule: both branches contain *exactly*
> the same rewind. In that case I don't see any problem to just do a fast
> forward to S21, as both agree on the commits to rewind.

That is different than using the merge base of the two commits needing
merge. I agree that rewinding to exactly the same commits is probably a
valid exception. Will have a look into extending the submodule merge
strategy to include this case.

Cheers Heiko

^ permalink raw reply

* [RFC/PATCH] Documentation/technical/api-fswatch.txt: start with outline
From: Ramkumar Ramachandra @ 2013-03-10 20:17 UTC (permalink / raw)
  To: Git List
  Cc: Duy Nguyen, Junio C Hamano, Torsten Bögershausen, Robert Zeh,
	Jeff King, Erik Faye-Lund, Karsten Blees, Drew Northup

git operations are slow on repositories with lots of files, and lots
of tiny filesystem calls like lstat(), getdents(), open() are
reposible for this.  On the linux-2.6 repository, for instance, the
numbers for "git status" look like this:

  top syscalls sorted     top syscalls sorted
  by acc. time            by number
  ----------------------------------------------
  0.401906 40950 lstat    0.401906 40950 lstat
  0.190484 5343 getdents  0.150055 5374 open
  0.150055 5374 open      0.190484 5343 getdents
  0.074843 2806 close     0.074843 2806 close
  0.003216 157 read       0.003216 157 read

To solve this problem, we propose to build a daemon which will watch
the filesystem using inotify and report batched up events over a UNIX
socket.  Since inotify is Linux-only, we have to leave open the
possibility of writing similar daemons for other platforms.
Everything will continue to work as before if there is no helper
present.

The fswatch API introduces a generic way for git.git to request for
filesystem changes.  Different helpers (like the inotify daemon on
Linux) will be plugged into this API on different platforms.  It falls
back to using the filesystem calls.

The daemon will start up with the very first operation done on the git
repository, and will die after a specified period of repository
inactivity.  It is going to be a per-repo daemon and will write to a
socket in the repository: access control is managed by filesystem
permissions.

This design is inspired by the credential helper design.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 Documentation/technical/api-fswatch.txt | 62 +++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 Documentation/technical/api-fswatch.txt

diff --git a/Documentation/technical/api-fswatch.txt b/Documentation/technical/api-fswatch.txt
new file mode 100644
index 0000000..9c6826a
--- /dev/null
+++ b/Documentation/technical/api-fswatch.txt
@@ -0,0 +1,62 @@
+fswatch API
+===========
+
+The fswatch API provides an abstracted way of collecting information
+about filesystem changes.  A remote helper is typically a daemon which
+uses inotify to watch the filesystem, and this information is used by
+git instead of making expensive system calls like lstat(), open().
+
+Typical setup
+-------------
+
+------------
++-----------------------+
+| Git code (C)          |--- requires information about fs changes
+|.......................|
+| C fswatch API         |--- system calls ---> filesystem
++-----------------------+
+     ^             |
+     | UNIX socket |
+     |             v
++-----------------------+
+| Git fswatch helper    |--- daemon inotify-watching ---> filesystem
++-----------------------+
+------------
+
+The Git code will call the C API to obtain changes in filesystem
+information.  The API will itself call a configured helper (e.g. "git
+fswatch-notify") which may run filesystem changes, if the remote
+helper daemon was started in a previous invocation.  If the daemon is
+not already running, it is started, and the C API will fall back to
+making expensive system calls.
+
+C API
+-----
+
+The credential C API is meant to be called by Git code which needs
+information aboutx filesystem changes.  It is centered around an
+object representing the changes the filesystem since the last
+invocation.
+
+Data Structures
+~~~~~~~~~~~~~~~
+
+`struct fschanges`::
+
+	TODO
+
+
+Functions
+~~~~~~~~~
+
+TODO
+
+Example
+~~~~~~~
+
+TODO
+
+fswatch Helpers
+---------------
+
+TODO
-- 
1.8.1.5

^ permalink raw reply related

* Re: [PATCH] perf: update documentation of GIT_PERF_REPEAT_COUNT
From: Thomas Rast @ 2013-03-10 20:32 UTC (permalink / raw)
  To: Antoine Pelisse; +Cc: git, Junio C Hamano
In-Reply-To: <1362842965-3446-1-git-send-email-apelisse@gmail.com>

Antoine Pelisse <apelisse@gmail.com> writes:

> Currently the documentation of GIT_PERF_REPEAT_COUNT says the default is
> five while "perf-lib.sh" uses a value of three as a default.
>
> Update the documentation so that it is consistent with the code.
>
> Signed-off-by: Antoine Pelisse <apelisse@gmail.com>

Acked-by: Thomas Rast <trast@inf.ethz.ch>

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply

* [PATCH/RFC] Make help behaviour more consistent
From: Kevin Bracey @ 2013-03-10 17:48 UTC (permalink / raw)
  To: git; +Cc: Kevin Bracey

Previously, the command "help" and the option "-h" behaved differently
depending on whether a command was specified or not. Old user interface:

Commands with no defaults show usage: "git"           "git CMD"
To specifically request usage:        "git help"      "git CMD -h"
To get a manual page:                 "git help git"  "git help CMD"

Two significant usability flaws here:
 - If using man, "man git" to side-step "git help" is obvious. But if
   trying to use help.format=web, how to get the root html page? My
   technique was "git help XXX" and click the "git(1) suite" link at the
   bottom. "git help git" is non-obvious and apparently undocumented
   (it's not mentioned by "git", "git help", or "git help help"...).

 - Because git itself didn't support -h (and thus actually printed less
   if you specified it), the general availability of -h for commands was
   non-obvious. I didn't know about it until I started this patch.

Tidy this up, so that help and -h do not change behaviour depending on
whether a command is specified or not. New, consistent user interface:

Commands with no defaults show usage: "git"           "git CMD"
To specifically request usage:        "git -h"        "git CMD -h"
To get a manual page:                 "git help"      "git help CMD".

"git help git" is still accepted. The legacy "--help" option behaves as
before, which means "git --help" on its own is now a synonym for "git
-h", not "git help", and it remains consistent with GNU Coding
Guidelines.

So the only change to existing command behaviour is that "git help" or
"git help -w" now opens the git manual page, rather than showing common
commands.

"git -h cmd" is also accepted as a synonym for "git cmd -h", as per
Linus's rationale for treating "git cmd --help" as a synonym for "git
--help cmd".

Option list shown in command-line usage re-ordered to match the manual
page, and git and git-help manual pages edited to reflect the new help
behaviour.

Signed-off-by: Kevin Bracey <kevin@bracey.fi>
---
 Documentation/git-help.txt | 22 +++++++++-------------
 Documentation/git.txt      | 17 ++++++++---------
 builtin/help.c             |  9 +--------
 git.c                      | 40 +++++++++++++++++++++++-----------------
 4 files changed, 41 insertions(+), 47 deletions(-)

diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt
index e07b6dc..25def9f 100644
--- a/Documentation/git-help.txt
+++ b/Documentation/git-help.txt
@@ -13,19 +13,16 @@ SYNOPSIS
 DESCRIPTION
 -----------
 
-With no options and no COMMAND given, the synopsis of the 'git'
-command and a list of the most commonly used Git commands are printed
-on the standard output.
-
 If the option '--all' or '-a' is given, then all available commands are
 printed on the standard output.
 
-If a Git subcommand is named, a manual page for that subcommand is brought
+Otherwise, a manual page for Git or the specified Git command is brought
 up. The 'man' program is used by default for this purpose, but this
 can be overridden by other options or configuration variables.
 
 Note that `git --help ...` is identical to `git help ...` because the
-former is internally converted into the latter.
+former is internally converted into the latter.  Also, to supplement
+`git help`, most Git commands offer the option '-h' to print usage.
 
 OPTIONS
 -------
@@ -36,14 +33,13 @@ OPTIONS
 
 -i::
 --info::
-	Display manual page for the command in the 'info' format. The
-	'info' program will be used for that purpose.
+	Display manual page in the 'info' format. The 'info' program will
+	be used for that purpose.
 
 -m::
 --man::
-	Display manual page for the command in the 'man' format. This
-	option may be used to override a value set in the
-	'help.format' configuration variable.
+	Display manual page in the 'man' format. This option may be used to
+	override a value set in the 'help.format' configuration variable.
 +
 By default the 'man' program will be used to display the manual page,
 but the 'man.viewer' configuration variable may be used to choose
@@ -51,8 +47,8 @@ other display programs (see below).
 
 -w::
 --web::
-	Display manual page for the command in the 'web' (HTML)
-	format. A web browser will be used for that purpose.
+	Display manual page in the 'web' (HTML)	format. A web browser will
+	be used for that purpose.
 +
 The web browser can be specified using the configuration variable
 'help.browser', or 'web.browser' if the former is not set. If none of
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 9d29ed5..51cdca2 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -9,7 +9,7 @@ git - the stupid content tracker
 SYNOPSIS
 --------
 [verse]
-'git' [--version] [--help] [-c <name>=<value>]
+'git' [--version] [--help] [-h] [-c <name>=<value>]
     [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
     [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
     [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
@@ -361,16 +361,15 @@ OPTIONS
 --version::
 	Prints the Git suite version that the 'git' program came from.
 
---help::
+-h::
 	Prints the synopsis and a list of the most commonly used
-	commands. If the option '--all' or '-a' is given then all
-	available commands are printed. If a Git command is named this
-	option will bring up the manual page for that command.
+	commands. Most Git commands also provide a '-h'	option to
+	show their own synopsis.
 +
-Other options are available to control how the manual page is
-displayed. See linkgit:git-help[1] for more information,
-because `git --help ...` is converted internally into `git
-help ...`.
+For compatibility, `git --help` is also implemented. With no
+following options, it is equivalent to `git -h`. Otherwise it is
+converted internally into `git help ...`, which will open a manual
+page. See linkgit:git-help[1] for more information.
 
 -c <name>=<value>::
 	Pass a configuration parameter to the command. The value
diff --git a/builtin/help.c b/builtin/help.c
index d1d7181..ef4706a 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -432,13 +432,6 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 		return 0;
 	}
 
-	if (!argv[0]) {
-		printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
-		list_common_cmds_help();
-		printf("\n%s\n", _(git_more_info_string));
-		return 0;
-	}
-
 	setup_git_directory_gently(&nongit);
 	git_config(git_help_config, NULL);
 
@@ -447,7 +440,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 	if (help_format == HELP_FORMAT_NONE)
 		help_format = parse_help_format(DEFAULT_HELP_FORMAT);
 
-	alias = alias_lookup(argv[0]);
+	alias = argv[0] ? alias_lookup(argv[0]) : NULL;
 	if (alias && !is_git_command(argv[0])) {
 		printf_ln(_("`git %s' is aliased to `%s'"), argv[0], alias);
 		return 0;
diff --git a/git.c b/git.c
index b10c18b..82a74c5 100644
--- a/git.c
+++ b/git.c
@@ -6,10 +6,10 @@
 #include "run-command.h"
 
 const char git_usage_string[] =
-	"git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
+	"git [--version] [--help] [-h] [-c name=value]\n"
+	"           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
 	"           [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n"
 	"           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-	"           [-c name=value] [--help]\n"
 	"           <command> [<args>]";
 
 const char git_more_info_string[] =
@@ -17,6 +17,7 @@ const char git_more_info_string[] =
 
 static struct startup_info git_startup_info;
 static int use_pager = -1;
+static int show_usage;
 
 static void commit_pager_choice(void) {
 	switch (use_pager) {
@@ -40,17 +41,6 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 		if (cmd[0] != '-')
 			break;
 
-		/*
-		 * For legacy reasons, the "version" and "help"
-		 * commands can be written with "--" prepended
-		 * to make them look like flags.
-		 */
-		if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
-			break;
-
-		/*
-		 * Check remaining flags.
-		 */
 		if (!prefixcmp(cmd, "--exec-path")) {
 			cmd += 11;
 			if (*cmd == '=')
@@ -143,6 +133,25 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 			setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1);
 			if (envchanged)
 				*envchanged = 1;
+		} else if (!strcmp(cmd, "--version")) {
+			/* Alternative spelling for "git version" */
+			(*argv)[0] += 2;
+			break;
+		} else if (!strcmp(cmd, "--help")) {
+			if (*argc > 1) {
+				/* Alternative spelling for "git help XXX" */
+				(*argv)[0] += 2;
+				break;
+			} else
+				show_usage = 1;
+		} else if (!strcmp(cmd, "-h")) {
+			if (*argc > 1 && (*argv)[1][0] != '-') {
+				/* Turn "git -h cmd" into "git cmd -h" */
+				(*argv)[0] = (*argv)[1];
+				(*argv)[1] = "-h";
+				break;
+			} else
+				show_usage = 1;
 		} else {
 			fprintf(stderr, "Unknown option: %s\n", cmd);
 			usage(git_usage_string);
@@ -537,10 +546,7 @@ int main(int argc, const char **argv)
 	argv++;
 	argc--;
 	handle_options(&argv, &argc, NULL);
-	if (argc > 0) {
-		if (!prefixcmp(argv[0], "--"))
-			argv[0] += 2;
-	} else {
+	if (argc <= 0 || show_usage) {
 		/* The user didn't specify a command; give them help */
 		commit_pager_choice();
 		printf("usage: %s\n\n", git_usage_string);
-- 
1.8.2.rc3.7.g1100d09.dirty

^ permalink raw reply related

* [PATCH v2 00/23] contrib/subtree: Collected updates
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Paul Campbell

A selection of updates to git-subtree were offered to the list in May of 
last year ($gmane/196667) by Herman van Rink.

At the time the commits were available as either a single commit or a 
large collection of commits and merges to the git-subtree prior to it's
inclusion in contrib/subtree.

The following patches take a selection of these commits and rebase them 
against the tip of master.

The git-subtree tests work (make test), but they don't cover any of
the new commands added nor the use of the .gittrees file for storing
the subtree metadata.

If I could ask the original contributors to add their Signed-off-by, I
would appreciate it.

However I don't have current email addresses for four of them: Peter 
Jaros, Michael Hart, Paul Cartwright and James Roper. If anyone has 
current email address for any of these, please either forward the 
relevant patch(es) to them or let me know so I can do so.

Herman van Rink (8):
  contrib/subtree: Add prune command to OPTS_SPEC
  contrib/subtree: Remove trailing slash from prefix parameter
  contrib/subtree: Teach from-submodule to add new subtree to .gittrees
  contrib/subtree: Document pull-all and push-all
  contrib/subtree: Document from-submodule and prune commands
  contrib/subtree: Add missing commands to SYNOPSIS
  contrib/subtree: Document list command
  contrib/subtree: Convert spaces to tabs and remove some trailing
    whitespace

James Roper (1):
  contrib/subtree: Teach push to use --force option

Matt Hoffman (6):
  contrib/subtree: Teach add to store repository & branch in .gittrees
  contrib/subtree: Rename commands push_all/pull_all to
    push-all/pull-all
  contrib/subtree: Teach push and pull to use .gittrees if needed
  contrib/subtree: Replace invisible carriage return with a visible \r
  contrib/subtree: Add command diff
  contrib/subtree: Add command list

Michael Hart (1):
  contrib/subtree: Teach push to abort if split fails

Nate Jones (1):
  contrib/subtree: Add command prune

Paul Campbell (2):
  contrib/subtree: Parameters repository/branch for push/pull are
    optional
  contrib/subtree: Fix order of case switches so default case is last

Paul Cartwright (1):
  contrib/subtree: Fix typo (s/incldued/included/)

Peter Jaros (1):
  contrib/subtree: Add command from-submodule

bibendi (2):
  contrib/subtree: Teach push and pull to use .gittrees for defaults
  contrib/subtree: Add commands pull_all and push_all

 contrib/subtree/git-subtree.sh  | 203 ++++++++++++++++++++++++++++++++++++----
 contrib/subtree/git-subtree.txt |  46 +++++++--
 2 files changed, 222 insertions(+), 27 deletions(-)

-- 
1.8.2.rc1

^ permalink raw reply

* [PATCH v2 01/23] contrib/subtree: Fix typo (s/incldued/included/)
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Paul Cartwright, Paul Campbell, Dan Sabath
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Paul Cartwright <paul.cartwright@ziilabs.com>

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>
---
 contrib/subtree/git-subtree.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index 7ba853e..e0957ee 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -270,7 +270,7 @@ git-extensions repository in ~/git-extensions/:
 name
 
 You can omit the --squash flag, but doing so will increase the number
-of commits that are incldued in your local repository.
+of commits that are included in your local repository.
 
 We now have a ~/git-extensions/git-subtree directory containing code
 from the master branch of git://github.com/apenwarr/git-subtree.git
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 02/23] contrib/subtree: Add command from-submodule
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Peter Jaros, Paul Campbell, Avery Pennarun,
	Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Peter Jaros <pjaros@pivotallabs.com>

Converts a git-submodule into a git-subtree.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	.gitignore
	contrib/subtree/git-subtree.sh
	test.sh
---
 contrib/subtree/git-subtree.sh | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 8a23f58..caf4988 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -14,6 +14,7 @@ git subtree merge --prefix=<prefix> <commit>
 git subtree pull  --prefix=<prefix> <repository> <refspec...>
 git subtree push  --prefix=<prefix> <repository> <refspec...>
 git subtree split --prefix=<prefix> <commit...>
+git subtree from-submodule --prefix=<prefix>
 --
 h,help        show the help
 q             quiet
@@ -101,7 +102,7 @@ done
 command="$1"
 shift
 case "$command" in
-	add|merge|pull) default= ;;
+	add|merge|pull|from-submodule) default= ;;
 	split|push) default="--default HEAD" ;;
 	*) die "Unknown command '$command'" ;;
 esac
@@ -721,4 +722,31 @@ cmd_push()
 	fi
 }
 
+cmd_from-submodule()
+{
+	ensure_clean
+
+	local submodule_sha=$(git submodule status $prefix | cut -d ' ' -f 2)
+
+	# Remove references to submodule.
+	git config --remove-section submodule.$prefix
+	git config --file .gitmodules --remove-section submodule.$prefix
+	git add .gitmodules
+
+	# Move submodule aside.
+	local tmp_repo="$(mktemp -d /tmp/git-subtree.XXXXX)"
+	rm -r $tmp_repo
+	mv $prefix $tmp_repo
+	git rm $prefix
+
+	# Commit changes.
+	git commit -m "Remove '$prefix/' submodule"
+
+	# subtree add from submodule repo.
+	cmd_add_repository $tmp_repo HEAD
+
+	# Remove submodule repo.
+	rm -rf $tmp_repo
+}
+
 "cmd_$command" "$@"
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 03/23] contrib/subtree: Teach add to store repository & branch in .gittrees
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Matt Hoffman, Paul Campbell, Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Matt Hoffman <matt.hoffman@quantumretail.com>

The repository and branch of a subtree added with the add command is
stored in the .gittrees file.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>
---
 contrib/subtree/git-subtree.sh | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index caf4988..7b70251 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -528,6 +528,14 @@ cmd_add_repository()
 	revs=FETCH_HEAD
 	set -- $revs
 	cmd_add_commit "$@"
+  
+  # now add it to our list of repos 
+  git config -f .gittrees --unset subtree.$dir.url
+  git config -f .gittrees --add subtree.$dir.url $repository
+  git config -f .gittrees --unset subtree.$dir.path
+  git config -f .gittrees --add subtree.$dir.path $dir
+  git config -f .gittrees --unset subtree.$dir.branch
+  git config -f .gittrees --add subtree.$dir.branch $refspec
 }
 
 cmd_add_commit()
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 04/23] contrib/subtree: Teach push and pull to use .gittrees for defaults
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, bibendi, Paul Campbell, Avery Pennarun,
	Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: bibendi <bibendi@bk.ru>

Look in the config file .gittrees for a default repository and
refspec or commit when they are not provided on the command line.

Uses the .gittrees config file in a similar way to how git-submodule
uses the .gitmodules file.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>
---
 contrib/subtree/git-subtree.sh | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 7b70251..1aff956 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -708,21 +708,31 @@ cmd_merge()
 
 cmd_pull()
 {
-	ensure_clean
-	git fetch "$@" || exit $?
-	revs=FETCH_HEAD
-	set -- $revs
-	cmd_merge "$@"
+    if [ $# -ne 1 ]; then
+	    die "You must provide <branch>"
+	fi
+	if [ -e "$dir" ]; then
+	    ensure_clean
+	    repository=$(git config -f .gittrees subtree.$prefix.url)
+	    refspec=$1
+	    git fetch $repository $refspec || exit $?
+	    echo "git fetch using: " $repository $refspec
+	    revs=FETCH_HEAD
+	    set -- $revs
+	    cmd_merge "$@"
+	else
+	    die "'$dir' must already exist. Try 'git subtree add'."
+	fi
 }
 
 cmd_push()
 {
-	if [ $# -ne 2 ]; then
-	    die "You must provide <repository> <refspec>"
+	if [ $# -ne 1 ]; then
+	    die "You must provide <branch>"
 	fi
 	if [ -e "$dir" ]; then
-	    repository=$1
-	    refspec=$2
+	    repository=$(git config -f .gittrees subtree.$prefix.url)
+	    refspec=$1
 	    echo "git push using: " $repository $refspec
 	    git push $repository $(git subtree split --prefix=$prefix):refs/heads/$refspec
 	else
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 05/23] contrib/subtree: Add commands pull_all and push_all
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, bibendi, Paul Campbell, Peter Jaros, Avery Pennarun,
	Win Treese, Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: bibendi <bibendi@bk.ru>

For each subtree listed in .gittrees perform a push or a pull.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	contrib/subtree/git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 1aff956..ddae56e 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -12,6 +12,7 @@ git subtree add   --prefix=<prefix> <commit>
 git subtree add   --prefix=<prefix> <repository> <commit>
 git subtree merge --prefix=<prefix> <commit>
 git subtree pull  --prefix=<prefix> <repository> <refspec...>
+git subtree pull_all
 git subtree push  --prefix=<prefix> <repository> <refspec...>
 git subtree split --prefix=<prefix> <commit...>
 git subtree from-submodule --prefix=<prefix>
@@ -102,16 +103,18 @@ done
 command="$1"
 shift
 case "$command" in
-	add|merge|pull|from-submodule) default= ;;
+	add|merge|pull|from-submodule|pull_all|push_all) default= ;;
 	split|push) default="--default HEAD" ;;
 	*) die "Unknown command '$command'" ;;
 esac
 
-if [ -z "$prefix" ]; then
+if [ -z "$prefix" -a "$command" != "pull_all" -a "$command" != "push_all" ]; then
 	die "You must provide the --prefix option."
 fi
 
 case "$command" in
+    pull_all);;
+    push_all);;
 	add) [ -e "$prefix" ] && 
 		die "prefix '$prefix' already exists." ;;
 	*)   [ -e "$prefix" ] || 
@@ -120,7 +123,7 @@ esac
 
 dir="$(dirname "$prefix/.")"
 
-if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" ]; then
+if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" -a "$command" != "pull_all" ]; then
 	revs=$(git rev-parse $default --revs-only "$@") || exit $?
 	dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
 	if [ -n "$dirs" ]; then
@@ -767,4 +770,20 @@ cmd_from-submodule()
 	rm -rf $tmp_repo
 }
 
+cmd_pull_all()
+{
+    git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
+        while read path; do
+            git subtree pull -P $path master || exit $?
+        done
+}
+
+cmd_push_all()
+{
+    git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
+        while read path; do
+            git subtree push -P $path master || exit $?
+        done
+}
+
 "cmd_$command" "$@"
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 06/23] contrib/subtree: Rename commands push_all/pull_all to push-all/pull-all
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, Matt Hoffman, Paul Campbell, Peter Jaros,
	Avery Pennarun, bibendi, Win Treese, Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Matt Hoffman <matt.hoffman@quantumretail.com>

Changing underscores to dashes (push_all -> push-all)

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	.gitignore
	contrib/subtree/git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index ddae56e..39d764b 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -12,7 +12,8 @@ git subtree add   --prefix=<prefix> <commit>
 git subtree add   --prefix=<prefix> <repository> <commit>
 git subtree merge --prefix=<prefix> <commit>
 git subtree pull  --prefix=<prefix> <repository> <refspec...>
-git subtree pull_all
+git subtree pull-all
+git subtree push-all
 git subtree push  --prefix=<prefix> <repository> <refspec...>
 git subtree split --prefix=<prefix> <commit...>
 git subtree from-submodule --prefix=<prefix>
@@ -103,18 +104,18 @@ done
 command="$1"
 shift
 case "$command" in
-	add|merge|pull|from-submodule|pull_all|push_all) default= ;;
+	add|merge|pull|from-submodule|pull-all|push-all) default= ;;
 	split|push) default="--default HEAD" ;;
 	*) die "Unknown command '$command'" ;;
 esac
 
-if [ -z "$prefix" -a "$command" != "pull_all" -a "$command" != "push_all" ]; then
+if [ -z "$prefix" -a "$command" != "pull-all" -a "$command" != "push-all" ]; then
 	die "You must provide the --prefix option."
 fi
 
 case "$command" in
-    pull_all);;
-    push_all);;
+    pull-all);;
+    push-all);;
 	add) [ -e "$prefix" ] && 
 		die "prefix '$prefix' already exists." ;;
 	*)   [ -e "$prefix" ] || 
@@ -123,7 +124,7 @@ esac
 
 dir="$(dirname "$prefix/.")"
 
-if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" -a "$command" != "pull_all" ]; then
+if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" -a "$command" != "pull-all" ]; then
 	revs=$(git rev-parse $default --revs-only "$@") || exit $?
 	dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
 	if [ -n "$dirs" ]; then
@@ -770,7 +771,7 @@ cmd_from-submodule()
 	rm -rf $tmp_repo
 }
 
-cmd_pull_all()
+cmd_pull-all()
 {
     git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
         while read path; do
@@ -778,7 +779,7 @@ cmd_pull_all()
         done
 }
 
-cmd_push_all()
+cmd_push-all()
 {
     git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
         while read path; do
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 07/23] contrib/subtree: Teach push and pull to use .gittrees if needed
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, Matt Hoffman, Paul Campbell, Avery Pennarun,
	bibendi, Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Matt Hoffman <matt.hoffman@quantumretail.com>

Only when a repository and/or branch are not supplied on the command
line will push and pull look for them in the .gittrees file.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>
---
 contrib/subtree/git-subtree.sh | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 39d764b..98c508b 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -712,13 +712,21 @@ cmd_merge()
 
 cmd_pull()
 {
-    if [ $# -ne 1 ]; then
-	    die "You must provide <branch>"
+  if [ $# -gt 2 ]; then
+	    die "You should provide either <refspec> or <repository> <refspec>"
 	fi
 	if [ -e "$dir" ]; then
 	    ensure_clean
-	    repository=$(git config -f .gittrees subtree.$prefix.url)
-	    refspec=$1
+      if [ $# -eq 1 ]; then 
+	      repository=$(git config -f .gittrees subtree.$prefix.url)
+	      refspec=$1
+      elif [ $# -eq 2 ]; then 
+        repository=$1
+        refspec=$2
+      else 
+	      repository=$(git config -f .gittrees subtree.$prefix.url)
+        refspec=$(git config -f .gittrees subtree.$prefix.branch)
+      fi
 	    git fetch $repository $refspec || exit $?
 	    echo "git fetch using: " $repository $refspec
 	    revs=FETCH_HEAD
@@ -731,12 +739,20 @@ cmd_pull()
 
 cmd_push()
 {
-	if [ $# -ne 1 ]; then
-	    die "You must provide <branch>"
+	if [ $# -gt 2 ]; then
+	    die "You shold provide either <refspec> or <repository> <refspec>"
 	fi
 	if [ -e "$dir" ]; then
-	    repository=$(git config -f .gittrees subtree.$prefix.url)
-	    refspec=$1
+      if [ $# -eq 1 ]; then 
+	      repository=$(git config -f .gittrees subtree.$prefix.url)
+        refspec=$1
+      elif [ $# -eq 2 ]; then 
+        repository=$1
+        refspec=$2
+      else
+	      repository=$(git config -f .gittrees subtree.$prefix.url)
+        refspec=$(git config -f .gittrees subtree.$prefix.branch)
+      fi
 	    echo "git push using: " $repository $refspec
 	    git push $repository $(git subtree split --prefix=$prefix):refs/heads/$refspec
 	else
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 08/23] contrib/subtree: Replace invisible carriage return with a visible \r
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Matt Hoffman, Paul Campbell, Avery Pennarun
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Matt Hoffman <matt.hoffman@quantumretail.com>

The ctrl-M (^M) character used for the carriage return (CR) is not visible
in all (most) text editors and is often silently converted to a new
line (NL) or CR/NL combo.

'say' is a wrapper for echo with accepts the option -e to interperet
escaped characters. \r becomes a CR, yet is not munged by text
editors.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 98c508b..8056851 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -605,7 +605,7 @@ cmd_split()
 	eval "$grl" |
 	while read rev parents; do
 		revcount=$(($revcount + 1))
-		say -n "$revcount/$revmax ($createcount)
"
+		say -ne "$revcount/$revmax ($createcount)\r"
 		debug "Processing commit: $rev"
 		exists=$(cache_get $rev)
 		if [ -n "$exists" ]; then
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 09/23] contrib/subtree: Teach push to abort if split fails
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Michael Hart, Paul Campbell, Matt Hoffman,
	Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Michael Hart <michael@adslot.com>

Added a check to ensure that split succeeds before trying to push.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>
---
 contrib/subtree/git-subtree.sh | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 8056851..ae9f87f 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -754,7 +754,12 @@ cmd_push()
         refspec=$(git config -f .gittrees subtree.$prefix.branch)
       fi
 	    echo "git push using: " $repository $refspec
-	    git push $repository $(git subtree split --prefix=$prefix):refs/heads/$refspec
+	    rev=$(git subtree split --prefix=$prefix)
+	    if [ -n "$rev" ]; then
+	        git push $repository $rev:refs/heads/$refspec
+	    else
+	        die "Couldn't push, 'git subtree split' failed."
+	    fi
 	else
 	    die "'$dir' must already exist. Try 'git subtree add'."
 	fi
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 10/23] contrib/subtree: Add command diff
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, Matt Hoffman, Paul Campbell, Peter Jaros,
	Avery Pennarun, bibendi, Wayne Walter
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Matt Hoffman <matt.hoffman@quantumretail.com>

Fetches the remote repo as a temporary git-remote then uses
git-diff-tree to do comparison before removing the temporary
git-remote.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index ae9f87f..4c3f3c0 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -16,6 +16,7 @@ git subtree pull-all
 git subtree push-all
 git subtree push  --prefix=<prefix> <repository> <refspec...>
 git subtree split --prefix=<prefix> <commit...>
+git subtree diff  --prefix=<prefix> [<repository> [<refspec>...]]
 git subtree from-submodule --prefix=<prefix>
 --
 h,help        show the help
@@ -105,8 +106,8 @@ command="$1"
 shift
 case "$command" in
 	add|merge|pull|from-submodule|pull-all|push-all) default= ;;
-	split|push) default="--default HEAD" ;;
 	*) die "Unknown command '$command'" ;;
+    split|push|diff) default="--default HEAD" ;;
 esac
 
 if [ -z "$prefix" -a "$command" != "pull-all" -a "$command" != "push-all" ]; then
@@ -737,6 +738,37 @@ cmd_pull()
 	fi
 }
 
+cmd_diff() 
+{
+    if [ -e "$dir" ]; then
+        if [ $# -eq 1 ]; then 
+            repository=$(git config -f .gittrees subtree.$prefix.url)
+            refspec=$1
+        elif [ $# -eq 2 ]; then 
+            repository=$1
+            refspec=$2
+        else
+            repository=$(git config -f .gittrees subtree.$prefix.url)
+            refspec=$(git config -f .gittrees subtree.$prefix.branch)
+        fi
+        # this is ugly, but I don't know of a better way to do it. My git-fu is weak. 
+        # git diff-tree expects a treeish, but I have only a repository and branch name.
+        # I don't know how to turn that into a treeish without creating a remote.
+        # Please change this if you know a better way! 
+        tmp_remote=__diff-tmp
+        git remote rm $tmp_remote > /dev/null 2>&1
+        git remote add -t $refspec $tmp_remote $repository > /dev/null
+        # we fetch as a separate step so we can pass -q (quiet), which isn't an option for "git remote"
+        # could this instead be "git fetch -q $repository $refspec" and leave aside creating the remote?
+        # Still need a treeish for the diff-tree command...
+        git fetch -q $tmp_remote 
+        git diff-tree -p refs/remotes/$tmp_remote/$refspec
+        git remote rm $tmp_remote > /dev/null 2>&1
+    else 
+        die "Cannot resolve directory '$dir'. Please point to an existing subtree directory to diff. Try 'git subtree add' to add a subtree."
+    fi
+}
+
 cmd_push()
 {
 	if [ $# -gt 2 ]; then
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 11/23] contrib/subtree: Add command list
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, Matt Hoffman, Paul Campbell, Peter Jaros,
	Avery Pennarun, bibendi, Win Treese
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Matt Hoffman <matt.hoffman@quantumretail.com>

Lists subtrees from the .gittrees file.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 4c3f3c0..7d08064 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -107,10 +107,10 @@ shift
 case "$command" in
 	add|merge|pull|from-submodule|pull-all|push-all) default= ;;
 	*) die "Unknown command '$command'" ;;
-    split|push|diff) default="--default HEAD" ;;
+    split|push|diff|list) default="--default HEAD" ;;
 esac
 
-if [ -z "$prefix" -a "$command" != "pull-all" -a "$command" != "push-all" ]; then
+if [ -z "$prefix" -a "$command" != "pull-all" -a "$command" != "push-all" -a "$command" != "list" ]; then
 	die "You must provide the --prefix option."
 fi
 
@@ -824,6 +824,21 @@ cmd_from-submodule()
 	rm -rf $tmp_repo
 }
 
+subtree_list() 
+{
+    git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
+    while read path; do 
+        repository=$(git config -f .gittrees subtree.$path.url)
+        refspec=$(git config -f .gittrees subtree.$path.branch)
+        echo "    $path        (merged from $repository branch $refspec) "
+    done
+}
+
+cmd_list()
+{
+  subtree_list 
+}
+
 cmd_pull-all()
 {
     git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 12/23] contrib/subtree: Add command prune
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, Nate Jones, Paul Campbell, Matt Hoffman,
	Avery Pennarun, bibendi, Win Treese
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Nate Jones <nate@endot.org>

Removes entries in .gittrees where the subtree files are
no longer present on disk.

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 7d08064..0c41383 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -105,12 +105,12 @@ done
 command="$1"
 shift
 case "$command" in
-	add|merge|pull|from-submodule|pull-all|push-all) default= ;;
+    add|merge|pull|from-submodule|pull-all|push-all|prune) default= ;;
 	*) die "Unknown command '$command'" ;;
     split|push|diff|list) default="--default HEAD" ;;
 esac
 
-if [ -z "$prefix" -a "$command" != "pull-all" -a "$command" != "push-all" -a "$command" != "list" ]; then
+if [ -z "$prefix" -a "$command" != "pull-all" -a "$command" != "push-all" -a "$command" != "list" -a "$command" != "prune" ]; then
 	die "You must provide the --prefix option."
 fi
 
@@ -839,6 +839,17 @@ cmd_list()
   subtree_list 
 }
 
+cmd_prune()
+{
+    git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
+    while read path; do
+        if [ ! -e "$path" ]; then
+            echo "pruning $path"
+            git config -f .gittrees --remove-section subtree.$path
+        fi
+    done
+}
+
 cmd_pull-all()
 {
     git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 13/23] contrib/subtree: Add prune command to OPTS_SPEC
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git
  Cc: David Greene, Herman van Rink, Paul Campbell, Peter Jaros,
	Matt Hoffman, Avery Pennarun
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Herman van Rink <rink@initfour.nl>

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>

Conflicts:
	git-subtree.sh
---
 contrib/subtree/git-subtree.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 0c41383..d67fe5a 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -18,6 +18,7 @@ git subtree push  --prefix=<prefix> <repository> <refspec...>
 git subtree split --prefix=<prefix> <commit...>
 git subtree diff  --prefix=<prefix> [<repository> [<refspec>...]]
 git subtree from-submodule --prefix=<prefix>
+git subtree prune
 --
 h,help        show the help
 q             quiet
-- 
1.8.2.rc1

^ permalink raw reply related

* [PATCH v2 14/23] contrib/subtree: Remove trailing slash from prefix parameter
From: Paul Campbell @ 2013-03-10 23:41 UTC (permalink / raw)
  To: git; +Cc: David Greene, Herman van Rink, Paul Campbell, Avery Pennarun
In-Reply-To: <1362958891-26941-1-git-send-email-pcampbell@kemitix.net>

From: Herman van Rink <rink@initfour.nl>

Conflicts:
	git-subtree.sh

Signed-off-by: Paul Campbell <pcampbell@kemitix.net>
---
 contrib/subtree/git-subtree.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index d67fe5a..ae7d1fe 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -103,6 +103,9 @@ while [ $# -gt 0 ]; do
 	esac
 done
 
+# Remove trailing slash
+prefix="${prefix%/}";
+
 command="$1"
 shift
 case "$command" in
-- 
1.8.2.rc1

^ 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