Re: Add a bugzilla website

2014-01-08 Thread David Aguilar
On Fri, Nov 15, 2013 at 2:34 AM,  ycollette.nos...@free.fr wrote:
 OK, thanks for these informations.
 From a user perspective, having this volume of devel mails flooding all the 
 bugs mail is very annoying.
 And following the status of a bug and the history of this bug is very hard 
 too.
 The bugzilla approach is really useful for the user who is reporting bugs: 
 all the bugs are tracked, you can see if a bug has been already filled and 
 put some additional informations if necessary.

 I will have a look at the JIRA thing.

FWIW Debian and Fedora (and possibly others) have git components in
their bugtrackers.

http://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=git

https://bugzilla.redhat.com/buglist.cgi?component=gitproduct=Fedora

It might be worth working along with one of the distros to avoid
duplicating effort.

cheers,
-- 
David
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC/PATCH 0/5] branch@{publish} shorthand

2014-01-08 Thread Jeff King
On Wed, Jan 08, 2014 at 03:05:48AM +0530, Ramkumar Ramachandra wrote:

 Agreed. I'll start working on @{publish}. It's going to take quite a
 bit of effort, because I won't actually start using it until my prompt
 is @{publish}-aware.

There's a fair bit of refactoring involved. I took a stab at it and came
up with the series below. No docs or tests, and some of the refactoring
in remote.c feels a little weird. I can't help but feel more of the
logic from git push should be shared here.

But it at least works with my rudimentary examples. I'm hoping it will
make a good starting point for you to build on. Otherwise, I may get to
it eventually, but it's not a high priority for me right now.

 Actually, I'm not sure I'd use git rebase @{pu}; for me @{pu} is
 mainly a source of information for taking apart to build a new series.

Ah, that's how I'd probably use it, too. :)

  [1/5]: sha1_name: refactor upstream_mark
  [2/5]: interpret_branch_name: factor out upstream handling
  [3/5]: branch_get: return early on error
  [4/5]: branch_get: provide per-branch pushremote pointers
  [5/5]: implement @{publish} shorthand

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] sha1_name: refactor upstream_mark

2014-01-08 Thread Jeff King
We will be adding new mark types in the future, so separate
the suffix data from the logic.

Signed-off-by: Jeff King p...@peff.net
---
 sha1_name.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index b1873d8..0c50801 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -415,12 +415,12 @@ static int ambiguous_path(const char *path, int len)
return slash;
 }
 
-static inline int upstream_mark(const char *string, int len)
+static inline int at_mark(const char *string, int len,
+ const char **suffix, int nr)
 {
-   const char *suffix[] = { @{upstream}, @{u} };
int i;
 
-   for (i = 0; i  ARRAY_SIZE(suffix); i++) {
+   for (i = 0; i  nr; i++) {
int suffix_len = strlen(suffix[i]);
if (suffix_len = len
 !memcmp(string, suffix[i], suffix_len))
@@ -429,6 +429,12 @@ static inline int upstream_mark(const char *string, int 
len)
return 0;
 }
 
+static inline int upstream_mark(const char *string, int len)
+{
+   const char *suffix[] = { @{upstream}, @{u} };
+   return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
+}
+
 static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned 
lookup_flags);
 static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf);
 
-- 
1.8.5.2.500.g8060133

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] branch_get: return early on error

2014-01-08 Thread Jeff King
Right now we simply check if ret is valid before doing
further processing. As we add more processing, this will
become more and more cumbersome. Instead, let's just check
whether ret is invalid and return early with the error.

Signed-off-by: Jeff King p...@peff.net
---
 remote.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/remote.c b/remote.c
index a89efab..a773004 100644
--- a/remote.c
+++ b/remote.c
@@ -1543,7 +1543,10 @@ struct branch *branch_get(const char *name)
ret = current_branch;
else
ret = make_branch(name, 0);
-   if (ret  ret-remote_name) {
+   if (!ret)
+   return NULL;
+
+   if (ret-remote_name) {
ret-remote = remote_get(ret-remote_name);
if (ret-merge_nr) {
int i;
-- 
1.8.5.2.500.g8060133

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] branch_get: provide per-branch pushremote pointers

2014-01-08 Thread Jeff King
When a caller uses branch_get to retrieve a struct branch,
they get the per-branch remote name and a pointer to the
remote struct. However, they have no way of knowing about
the per-branch pushremote from this interface.

Let's expose that information via fields similar to
remote and remote_name.

We have to do a little refactoring around the configuration
reading here. Instead of pushremote_name being its own
allocated string, it instead becomes a pointer to one of:

  1. The pushremote_name of the current branch, if
 configured.

  2. The globally configured remote.pushdefault, which we
 store separately as pushremote_config_default.

We can then set the branch's pushremote field by doing the
normal sequence of config fallback.

Signed-off-by: Jeff King p...@peff.net
---
 remote.c | 23 +++
 remote.h |  2 ++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/remote.c b/remote.c
index a773004..53e40e0 100644
--- a/remote.c
+++ b/remote.c
@@ -50,6 +50,7 @@ static int branches_nr;
 static struct branch *current_branch;
 static const char *default_remote_name;
 static const char *pushremote_name;
+static const char *pushremote_config_default;
 static int explicit_default_remote_name;
 
 static struct rewrites rewrites;
@@ -351,9 +352,10 @@ static int handle_config(const char *key, const char 
*value, void *cb)
explicit_default_remote_name = 1;
}
} else if (!strcmp(subkey, .pushremote)) {
+   if (git_config_string(branch-pushremote_name, key, 
value))
+   return -1;
if (branch == current_branch)
-   if (git_config_string(pushremote_name, key, 
value))
-   return -1;
+   pushremote_name = branch-pushremote_name;
} else if (!strcmp(subkey, .merge)) {
if (!value)
return config_error_nonbool(key);
@@ -385,8 +387,11 @@ static int handle_config(const char *key, const char 
*value, void *cb)
name = key + 7;
 
/* Handle remote.* variables */
-   if (!strcmp(name, pushdefault))
-   return git_config_string(pushremote_name, key, value);
+   if (!strcmp(name, pushdefault)) {
+   if (git_config_string(pushremote_config_default, key, value)  
0)
+   return -1;
+   pushremote_name = pushremote_config_default;
+   }
 
/* Handle remote.name.* variables */
if (*name == '/') {
@@ -1560,6 +1565,16 @@ struct branch *branch_get(const char *name)
}
}
}
+
+   if (ret-pushremote_name)
+   ret-pushremote = remote_get(ret-pushremote_name);
+   else if (pushremote_config_default)
+   ret-pushremote = remote_get(pushremote_config_default);
+   else if (ret-remote_name)
+   ret-pushremote = remote_get(ret-remote_name);
+   else
+   ret-pushremote = remote_get(origin);
+
return ret;
 }
 
diff --git a/remote.h b/remote.h
index 00c6a76..e5beb30 100644
--- a/remote.h
+++ b/remote.h
@@ -200,6 +200,8 @@ struct branch {
 
const char *remote_name;
struct remote *remote;
+   const char *pushremote_name;
+   struct remote *pushremote;
 
const char **merge_name;
struct refspec **merge;
-- 
1.8.5.2.500.g8060133

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] interpret_branch_name: factor out upstream handling

2014-01-08 Thread Jeff King
This function checks a few different @{}-constructs. The
early part checks for and dispatches us to helpers for each
construct, but the code for handling @{upstream} is inline.

Let's factor this out into its own function. This makes
interpret_branch_name more readable, and will make it much
simpler to add more constructs in future patches.

While we're at it, let's also break apart the refactored
code into a few helper functions. These will be useful when
we implement similar @{upstream}-like constructs.

Signed-off-by: Jeff King p...@peff.net
---
 sha1_name.c | 83 ++---
 1 file changed, 52 insertions(+), 31 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 0c50801..50df5d4 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -1052,6 +1052,54 @@ static int reinterpret(const char *name, int namelen, 
int len, struct strbuf *bu
return ret - used + len;
 }
 
+static void set_shortened_ref(struct strbuf *buf, const char *ref)
+{
+   char *s = shorten_unambiguous_ref(ref, 0);
+   strbuf_reset(buf);
+   strbuf_addstr(buf, s);
+   free(s);
+}
+
+static const char *get_upstream_branch(const char *branch_buf, int len)
+{
+   char *branch = xstrndup(branch_buf, len);
+   struct branch *upstream = branch_get(*branch ? branch : NULL);
+
+   /*
+* Upstream can be NULL only if branch refers to HEAD and HEAD
+* points to something different than a branch.
+*/
+   if (!upstream)
+   die(_(HEAD does not point to a branch));
+   if (!upstream-merge || !upstream-merge[0]-dst) {
+   if (!ref_exists(upstream-refname))
+   die(_(No such branch: '%s'), branch);
+   if (!upstream-merge) {
+   die(_(No upstream configured for branch '%s'),
+   upstream-name);
+   }
+   die(
+   _(Upstream branch '%s' not stored as a remote-tracking 
branch),
+   upstream-merge[0]-src);
+   }
+   free(branch);
+
+   return upstream-merge[0]-dst;
+}
+
+static int interpret_upstream_mark(const char *name, int namelen,
+  int at, struct strbuf *buf)
+{
+   int len;
+
+   len = upstream_mark(name + at, namelen - at);
+   if (!len)
+   return -1;
+
+   set_shortened_ref(buf, get_upstream_branch(name, at));
+   return len + at;
+}
+
 /*
  * This reads short-hand syntax that not only evaluates to a commit
  * object name, but also can act as if the end user spelled the name
@@ -1076,9 +1124,7 @@ static int reinterpret(const char *name, int namelen, int 
len, struct strbuf *bu
 int interpret_branch_name(const char *name, int namelen, struct strbuf *buf)
 {
char *cp;
-   struct branch *upstream;
int len = interpret_nth_prior_checkout(name, buf);
-   int tmp_len;
 
if (!namelen)
namelen = strlen(name);
@@ -1100,36 +1146,11 @@ int interpret_branch_name(const char *name, int 
namelen, struct strbuf *buf)
if (len  0)
return reinterpret(name, namelen, len, buf);
 
-   tmp_len = upstream_mark(cp, namelen - (cp - name));
-   if (!tmp_len)
-   return -1;
+   len = interpret_upstream_mark(name, namelen, cp - name, buf);
+   if (len  0)
+   return len;
 
-   len = cp + tmp_len - name;
-   cp = xstrndup(name, cp - name);
-   upstream = branch_get(*cp ? cp : NULL);
-   /*
-* Upstream can be NULL only if cp refers to HEAD and HEAD
-* points to something different than a branch.
-*/
-   if (!upstream)
-   die(_(HEAD does not point to a branch));
-   if (!upstream-merge || !upstream-merge[0]-dst) {
-   if (!ref_exists(upstream-refname))
-   die(_(No such branch: '%s'), cp);
-   if (!upstream-merge) {
-   die(_(No upstream configured for branch '%s'),
-   upstream-name);
-   }
-   die(
-   _(Upstream branch '%s' not stored as a remote-tracking 
branch),
-   upstream-merge[0]-src);
-   }
-   free(cp);
-   cp = shorten_unambiguous_ref(upstream-merge[0]-dst, 0);
-   strbuf_reset(buf);
-   strbuf_addstr(buf, cp);
-   free(cp);
-   return len;
+   return -1;
 }
 
 int strbuf_branchname(struct strbuf *sb, const char *name)
-- 
1.8.5.2.500.g8060133

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] implement @{publish} shorthand

2014-01-08 Thread Jeff King
In a triangular workflow, you may have a distinct
@{upstream} that you pull changes from, but publish by
default (if you typed git push) to a different remote (or
a different branch on the remote). It may sometimes be
useful to be able to quickly refer to that publishing point
(e.g., to see which changes you have that have not yet been
published).

This patch introduces the branch@{publish} shorthand (or
@{pu} to be even shorter). It refers to the tracking
branch of the remote branch to which you would push if you
were to push the named branch. That's a mouthful to explain,
so here's an example:

  $ git checkout -b foo origin/master
  $ git config remote.pushdefault github
  $ git push

Signed-off-by: Jeff King p...@peff.net
---
The implementation feels weird, like the where do we push to code
should be factored out from somewhere else. I think what we're doing
here is not _wrong_, but I don't like repeating what git push is doing
elsewhere. And I just punt on simple as a result. :)

 sha1_name.c | 76 -
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/sha1_name.c b/sha1_name.c
index 50df5d4..59ffa93 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -435,6 +435,12 @@ static inline int upstream_mark(const char *string, int 
len)
return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
 }
 
+static inline int publish_mark(const char *string, int len)
+{
+   const char *suffix[] = { @{publish} };
+   return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
+}
+
 static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned 
lookup_flags);
 static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf);
 
@@ -481,7 +487,8 @@ static int get_sha1_basic(const char *str, int len, 
unsigned char *sha1)
nth_prior = 1;
continue;
}
-   if (!upstream_mark(str + at, len - at)) {
+   if (!upstream_mark(str + at, len - at) 
+   !publish_mark(str + at, len - at)) {
reflog_len = (len-1) - (at+2);
len = at;
}
@@ -1100,6 +1107,69 @@ static int interpret_upstream_mark(const char *name, int 
namelen,
return len + at;
 }
 
+static const char *get_publish_branch(const char *name_buf, int len)
+{
+   char *name = xstrndup(name_buf, len);
+   struct branch *b = branch_get(*name ? name : NULL);
+   struct remote *remote = b-pushremote;
+   const char *dst;
+   const char *track;
+
+   free(name);
+
+   if (!remote)
+   die(_(branch '%s' has no remote for pushing), b-name);
+
+   /* Figure out what we would call it on the remote side... */
+   if (remote-push_refspec_nr)
+   dst = apply_refspecs(remote-push, remote-push_refspec_nr,
+b-refname);
+   else
+   dst = b-refname;
+   if (!dst)
+   die(_(unable to figure out how '%s' would be pushed),
+   b-name);
+
+   /* ...and then figure out what we would call that remote here */
+   track = apply_refspecs(remote-fetch, remote-fetch_refspec_nr, dst);
+   if (!track)
+   die(_(%s@{publish} has no tracking branch for '%s'),
+   b-name, dst);
+
+   return track;
+}
+
+static int interpret_publish_mark(const char *name, int namelen,
+ int at, struct strbuf *buf)
+{
+   int len;
+
+   len = publish_mark(name + at, namelen - at);
+   if (!len)
+   return -1;
+
+   switch (push_default) {
+   case PUSH_DEFAULT_NOTHING:
+   die(_(cannot use @{publish} with push.default of 'nothing'));
+
+   case PUSH_DEFAULT_UNSPECIFIED:
+   case PUSH_DEFAULT_MATCHING:
+   case PUSH_DEFAULT_CURRENT:
+   set_shortened_ref(buf, get_publish_branch(name, at));
+   break;
+
+   case PUSH_DEFAULT_UPSTREAM:
+   set_shortened_ref(buf, get_upstream_branch(name, at));
+   break;
+
+   case PUSH_DEFAULT_SIMPLE:
+   /* ??? */
+   die(@{publish} with simple unimplemented);
+   }
+
+   return at + len;
+}
+
 /*
  * This reads short-hand syntax that not only evaluates to a commit
  * object name, but also can act as if the end user spelled the name
@@ -1150,6 +1220,10 @@ int interpret_branch_name(const char *name, int namelen, 
struct strbuf *buf)
if (len  0)
return len;
 
+   len = interpret_publish_mark(name, namelen, cp - name, buf);
+   if (len  0)
+   return len;
+
return -1;
 }
 
-- 
1.8.5.2.500.g8060133
--
To unsubscribe from this list: send the line unsubscribe git in
the body of 

Re: [PATCH v3 3/5] refs: teach for_each_ref a flag to avoid recursion

2014-01-08 Thread Jeff King
On Tue, Jan 07, 2014 at 10:47:33PM -0500, Jeff King wrote:

 On Tue, Jan 07, 2014 at 06:58:50PM -0500, Jeff King wrote:
 
  +   if (flags  DO_FOR_EACH_NO_RECURSE) {
  +   struct ref_dir *subdir = get_ref_dir(entry);
  +   sort_ref_dir(subdir);
  +   retval = do_for_each_entry_in_dir(subdir, 0,
 
 Obviously this is totally wrong and inverts the point of the flag. And
 causes something like half of the test suite to fail.

And while we're on the subject of my mistakes...

The patch needs the fixup below to ensure that retval is always set,
even when we do not recurse.

I'll hold off on sending a full re-roll of the patch, in the extremely
unlikely event that there are other small errors to be fixed. :)

diff --git a/refs.c b/refs.c
index aafbae9..99c72d0 100644
--- a/refs.c
+++ b/refs.c
@@ -679,7 +679,8 @@ static int do_for_each_entry_in_dir(struct ref_dir *dir, 
int offset,
retval = do_for_each_entry_in_dir(subdir, 0,
  fn, cb_data,
  flags);
-   }
+   } else
+   retval = 0;
} else {
retval = fn(entry, cb_data);
}
@@ -732,7 +733,8 @@ static int do_for_each_entry_in_dirs(struct ref_dir *dir1,
retval = do_for_each_entry_in_dirs(
subdir1, subdir2,
fn, cb_data, flags);
-   }
+   } else
+   retval = 0;
i1++;
i2++;
} else if (!(e1-flag  REF_DIR)  !(e2-flag  
REF_DIR)) {
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/5] branch_get: provide per-branch pushremote pointers

2014-01-08 Thread Jeff King
On Wed, Jan 08, 2014 at 04:35:31AM -0500, Jeff King wrote:

 @@ -385,8 +387,11 @@ static int handle_config(const char *key, const char 
 *value, void *cb)
   name = key + 7;
  
   /* Handle remote.* variables */
 - if (!strcmp(name, pushdefault))
 - return git_config_string(pushremote_name, key, value);
 + if (!strcmp(name, pushdefault)) {
 + if (git_config_string(pushremote_config_default, key, value)  
 0)
 + return -1;
 + pushremote_name = pushremote_config_default;
 + }

This needs return 0 squashed in at the end of the conditional, of
course, to match the old behavior.

This patch passes the test suite by itself (with or without that fixup).
But oddly, it seems to fail t5531 when merged with 'next'. I can't
figure out why, though. It shouldn't affect any code that doesn't look
at branch-pushremote.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] t5531: further matching fixups

2014-01-08 Thread Jeff King
Commit 43eb920 switched one of the sub-repository in this
test to matching to prepare for a world where the default
becomes simple. However, the main repository needs a
similar change.

We did not notice any test failure when merged with b2ed944
(push: switch default from matching to simple, 2013-01-04)
because t5531.6 is trying to provoke a failure of git push
due to a submodule check. When combined with b2ed944 the
push still fails, but for the wrong reason (because our
upstream setup does not exist, not because of the submodule).

Signed-off-by: Jeff King p...@peff.net
---
On Wed, Jan 08, 2014 at 05:27:07AM -0500, Jeff King wrote:

 This patch passes the test suite by itself (with or without that fixup).
 But oddly, it seems to fail t5531 when merged with 'next'. I can't
 figure out why, though. It shouldn't affect any code that doesn't look
 at branch-pushremote.

I still don't understand the full reason for this interaction, but the
failing test is actually somewhat broken in 'next' already. This patch
fixes it, and should be done regardless of the other series.

 t/t5531-deep-submodule-push.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index 8c16e04..445bb5f 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -12,6 +12,7 @@ test_expect_success setup '
(
cd work 
git init 
+   git config push.default matching 
mkdir -p gar/bage 
(
cd gar/bage 
-- 
1.8.5.2.500.g8060133

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/5] branch_get: provide per-branch pushremote pointers

2014-01-08 Thread Jeff King
On Wed, Jan 08, 2014 at 05:27:07AM -0500, Jeff King wrote:

 This patch passes the test suite by itself (with or without that fixup).
 But oddly, it seems to fail t5531 when merged with 'next'. I can't
 figure out why, though. It shouldn't affect any code that doesn't look
 at branch-pushremote.

OK, I figured it out. My patch calls:

  remote_get(origin)

which creates an origin remote, even if one does not exist (it assumes
it to be a URL origin). Later, when we want to decide if the push is
triangular or not, we ask for:

  remote_get(NULL);

which will internally look for a remote called origin. Before my patch
there was not such a remote, and so the push could not be triangular.
After my patch, it finds the bogus remote and says this thing exists,
and is not what we are pushing to; therefore the push is triangular.

The solution is that I should not be passing the term origin to
remote_get, but rather passing NULL and relying on it to figure out the
default remote correctly. I.e.:

diff --git a/remote.c b/remote.c
index 8724388..d214fa2 100644
--- a/remote.c
+++ b/remote.c
@@ -1574,7 +1574,7 @@ struct branch *branch_get(const char *name)
else if (ret-remote_name)
ret-pushremote = remote_get(ret-remote_name);
else
-   ret-pushremote = remote_get(origin);
+   ret-pushremote = remote_get(NULL);
 
return ret;
 }

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 23/28] Support shallow fetch/clone over smart-http

2014-01-08 Thread Jeff King
On Thu, Dec 05, 2013 at 08:02:50PM +0700, Nguyễn Thái Ngọc Duy wrote:

 Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
 ---
  Documentation/gitremote-helpers.txt |  7 +++
  builtin/fetch-pack.c| 16 +---
  remote-curl.c   | 31 +--
  t/t5536-fetch-shallow.sh| 27 +++

I'm getting test failures in 'next' with GIT_TEST_HTTPD set, and they
are bisectable to this patch (actually, the moral equivalent of it, as
it looks like the commit message was tweaked along with the test number
when it was applied). The failures look like this:

  $ GIT_TEST_HTTPD=1 ./t5537-fetch-shallow.sh -v -i
  [...]
  ok 9 - fetch --update-shallow
  
  expecting success: 
  git clone --bare --no-local shallow 
$HTTPD_DOCUMENT_ROOT_PATH/repo.git 
  git clone $HTTPD_URL/smart/repo.git clone 
  (
  cd clone 
  git fsck 
  git log --format=%s origin/master actual 
  cat EOF expect 
  6
  5
  4
  3
  EOF
  test_cmp expect actual
  )
  
  Cloning into bare repository '/home/peff/compile/git/t/trash 
directory.t5537-fetch-shallow/httpd/www/repo.git'...
  remote: Counting objects: 19, done.
  remote: Compressing objects: 100% (7/7), done.
  remote: Total 19 (delta 0), reused 6 (delta 0)
  Receiving objects: 100% (19/19), done.
  Checking connectivity... done.
  Cloning into 'clone'...
  remote: Counting objects: 19, done.
  remote: Compressing objects: 100% (7/7), done.
  remote: Total 19 (delta 0), reused 19 (delta 0)
  Unpacking objects: 100% (19/19), done.
  Checking connectivity... done.
  Checking object directories: 100% (256/256), done.
  --- expect  2014-01-08 11:20:20.178546452 +
  +++ actual  2014-01-08 11:20:20.178546452 +
  @@ -1,3 +1,4 @@
  +7
   6
   5
   4
  not ok 10 - clone http repository


If you do end up tweaking the test, you may also want to fix:

 +LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5536'}
 +. $TEST_DIRECTORY/lib-httpd.sh

Since the test number got switched, it would be nice to tweak the port
number to match it, in case the real t5536 ever starts using lib-httpd.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 3/5] refs: teach for_each_ref a flag to avoid recursion

2014-01-08 Thread Michael Haggerty
On 01/08/2014 04:47 AM, Jeff King wrote:
 On Tue, Jan 07, 2014 at 06:58:50PM -0500, Jeff King wrote:
 
 +if (flags  DO_FOR_EACH_NO_RECURSE) {
 +struct ref_dir *subdir = get_ref_dir(entry);
 +sort_ref_dir(subdir);
 +retval = do_for_each_entry_in_dir(subdir, 0,
 
 Obviously this is totally wrong and inverts the point of the flag. And
 causes something like half of the test suite to fail.
 
 Michael was nice enough to point it out to me off-list, but well, I have
 to face the brown paper bag at some point. :) In my defense, it was a
 last minute refactor before going to dinner. That is what I get for
 rushing out the series.
 
 Here's a fixed version of patch 3/5.

v2 4/5 doesn't apply cleanly on top of v3 3/5.  So I'm basing my review
on the branch you have at GitHub peff/git jk/cat-file-warn-ambiguous;
I hope it is the same.

 -- 8 --
 Subject: refs: teach for_each_ref a flag to avoid recursion
 
 The normal for_each_ref traversal descends into

You haven't changed any for_each_ref*() functions; you have only exposed
the DO_FOR_EACH_NO_RECURSE option to the (static) functions
for_each_entry*() and do_for_each_ref().  (This is part and parcel of
your decision not to expose the new functionality in the refs API.)
Please correct the line above.

 subdirectories, returning each ref it finds. However, in
 some cases we may want to just iterate over the top-level of
 a certain part of the tree.
 
 The introduction of the flags option is a little
 mysterious. We already have a flags option that gets stuck
 in a callback struct and ends up interpreted in do_one_ref.
 But the traversal itself does not currently have any flags,
 and it needs to know about this new flag.
 
 We _could_ introduce this as a completely separate flag
 parameter. But instead, we simply put both flag types into a
 single namespace, and make it available at both sites. This
 is simple, and given that we do not have a proliferation of
 flags (we have had exactly one until now), it is probably
 sufficient.
 
 Signed-off-by: Jeff King p...@peff.net
 ---
  refs.c | 61 ++---
  1 file changed, 38 insertions(+), 23 deletions(-)
 
 diff --git a/refs.c b/refs.c
 index 3926136..b70b018 100644
 --- a/refs.c
 +++ b/refs.c
 @@ -589,6 +589,8 @@ static void sort_ref_dir(struct ref_dir *dir)
  
  /* Include broken references in a do_for_each_ref*() iteration: */
  #define DO_FOR_EACH_INCLUDE_BROKEN 0x01
 +/* Do not recurse into subdirs, just iterate at a single level. */
 +#define DO_FOR_EACH_NO_RECURSE 0x02
  
  /*
   * Return true iff the reference described by entry can be resolved to
 @@ -661,7 +663,8 @@ static int do_one_ref(struct ref_entry *entry, void 
 *cb_data)
   * called for all references, including broken ones.
   */
  static int do_for_each_entry_in_dir(struct ref_dir *dir, int offset,
 - each_ref_entry_fn fn, void *cb_data)
 + each_ref_entry_fn fn, void *cb_data,
 + int flags)
  {
   int i;
   assert(dir-sorted == dir-nr);

Please update the docstring for this function, which still says that it
recurses without mentioning DO_FOR_EACH_NO_RECURSE.

 [...]
 @@ -817,7 +830,7 @@ static int is_refname_available(const char *refname, 
 const char *oldrefname,
   data.conflicting_refname = NULL;
  
   sort_ref_dir(dir);
 - if (do_for_each_entry_in_dir(dir, 0, name_conflict_fn, data)) {
 + if (do_for_each_entry_in_dir(dir, 0, name_conflict_fn, data, 0)) {
   error('%s' exists; cannot create '%s',
 data.conflicting_refname, refname);
   return 0;
 @@ -1651,7 +1664,8 @@ void warn_dangling_symref(FILE *fp, const char 
 *msg_fmt, const char *refname)
   * 0.
   */
  static int do_for_each_entry(struct ref_cache *refs, const char *base,
 -  each_ref_entry_fn fn, void *cb_data)
 +  each_ref_entry_fn fn, void *cb_data,
 +  int flags)
  {
   struct packed_ref_cache *packed_ref_cache;
   struct ref_dir *loose_dir;

A few lines after this, do_for_each_entry() calls
prime_ref_dir(loose_dir) to ensure that all of the loose references that
will be iterated over are read before the packed-refs file is checked.
It seems to me that prime_ref_dir() should also get a flags parameter to
prevent it reading more loose references than necessary, something like
this:


diff --git a/refs.c b/refs.c
index b70b018..b8b7354 100644
--- a/refs.c
+++ b/refs.c
@@ -772,13 +772,13 @@ static int do_for_each_entry_in_dirs(struct
ref_dir *dir1,
  * through all of the sub-directories. We do not even need to care about
  * sorting, as traversal order does not matter to us.
  */
-static void prime_ref_dir(struct ref_dir 

[PATCH] t5537: fix incorrect expectation in test case 10

2014-01-08 Thread Nguyễn Thái Ngọc Duy
Commit 48d25ca adds a new commit 7 to the repo that the next test case
in commit 1609488 clones from. But the next test case does not expect
this commit. For these tests, it's the bottom that's important, not
the top. Fix the expected commit list.

While at it, fix the default http port number to 5537. Otherwise when
t5536 learns to test httpd, running test in parallel may fail.

References:

48d25ca fetch: add --update-shallow to accept... - 2013-12-05
1609488 smart-http: support shallow fetch/clone - 2013-12-05

Noticed-by: Jeff King p...@peff.net
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 I obviously made a mistake with patch reordering or something. And
 embarassing because I did not run tests with GIT_TEST_HTTPD again
 before submission.

 t/t5537-fetch-shallow.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 79ce472..b0fa738 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -178,7 +178,7 @@ if test -n $NO_CURL -o -z $GIT_TEST_HTTPD; then
test_done
 fi
 
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5536'}
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5537'}
 . $TEST_DIRECTORY/lib-httpd.sh
 start_httpd
 
@@ -190,6 +190,7 @@ test_expect_success 'clone http repository' '
git fsck 
git log --format=%s origin/master actual 
cat EOF expect 
+7
 6
 5
 4
-- 
1.8.5.2.240.g8478abd

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/5] interpret_branch_name: factor out upstream handling

2014-01-08 Thread Ramkumar Ramachandra
Jeff King wrote:
  sha1_name.c | 83 
 ++---
  1 file changed, 52 insertions(+), 31 deletions(-)

Thanks. I applied this to my series as-it-is.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 0/5] branch@{publish} shorthand

2014-01-08 Thread Ramkumar Ramachandra
Jeff King wrote:
 There's a fair bit of refactoring involved. I took a stab at it and came
 up with the series below. No docs or tests, and some of the refactoring
 in remote.c feels a little weird. I can't help but feel more of the
 logic from git push should be shared here.

 But it at least works with my rudimentary examples. I'm hoping it will
 make a good starting point for you to build on. Otherwise, I may get to
 it eventually, but it's not a high priority for me right now.

Thanks; I'll see what I can do about getting it to share code with 'git push'.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] shorten_unambiguous_ref(): introduce a new local variable

2014-01-08 Thread Michael Haggerty
When filling the scanf_fmts array, use a separate variable to keep
track of the offset to avoid clobbering total_len (which we will need
in the next commit).

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/refs.c b/refs.c
index 3926136..9530480 100644
--- a/refs.c
+++ b/refs.c
@@ -3367,6 +3367,7 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
/* pre generate scanf formats from ref_rev_parse_rules[] */
if (!nr_rules) {
size_t total_len = 0;
+   size_t offset = 0;
 
/* the rule list is NULL terminated, count them first */
for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
@@ -3375,12 +3376,11 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
 
scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
 
-   total_len = 0;
+   offset = 0;
for (i = 0; i  nr_rules; i++) {
-   scanf_fmts[i] = (char *)scanf_fmts[nr_rules]
-   + total_len;
+   scanf_fmts[i] = (char *)scanf_fmts[nr_rules] + offset;
gen_scanf_fmt(scanf_fmts[i], ref_rev_parse_rules[i]);
-   total_len += strlen(ref_rev_parse_rules[i]);
+   offset += strlen(ref_rev_parse_rules[i]);
}
}
 
-- 
1.8.5.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] shorten_unambiguous_ref(): tighten up pointer arithmetic

2014-01-08 Thread Michael Haggerty
As long as we're being pathologically stingy with mallocs, we might as
well do the math right and save 6 (!) bytes.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
It is left to the reader to show how another 7 bytes could be saved
(11 bytes on a 64-bit architecture!)

It probably wouldn't kill performance to use a string_list here
instead.

 refs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/refs.c b/refs.c
index ef9cdea..63b3a71 100644
--- a/refs.c
+++ b/refs.c
@@ -3351,10 +3351,10 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
size_t total_len = 0;
size_t offset = 0;
 
-   /* the rule list is NULL terminated, count them first */
+   /* the rule list is NUL terminated, count them first */
for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
-   /* no +1 because strlen(%s)  strlen(%.*s) */
-   total_len += strlen(ref_rev_parse_rules[nr_rules]);
+   /* -2 for strlen(%.*s) - strlen(%s); +1 for NUL */
+   total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 
+ 1;
 
scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
 
-- 
1.8.5.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] Generate scanf_fmts more simply

2014-01-08 Thread Michael Haggerty
This is just a fun little thing that I noticed while poking around the
code: the function gen_scanf_fmt() can be replaced with a simple call
to snprintf().

Michael Haggerty (3):
  shorten_unambiguous_ref(): introduce a new local variable
  gen_scanf_fmt(): delete function and use snprintf() instead
  shorten_unambiguous_ref(): tighten up pointer arithmetic

 refs.c | 47 +++
 1 file changed, 15 insertions(+), 32 deletions(-)

-- 
1.8.5.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] gen_scanf_fmt(): delete function and use snprintf() instead

2014-01-08 Thread Michael Haggerty
To replace %.*s with %s, all we have to do is use snprintf()
to interpolate %s into the pattern.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 refs.c | 35 +--
 1 file changed, 9 insertions(+), 26 deletions(-)

diff --git a/refs.c b/refs.c
index 9530480..ef9cdea 100644
--- a/refs.c
+++ b/refs.c
@@ -3334,29 +3334,6 @@ cleanup:
return ret;
 }
 
-/*
- * generate a format suitable for scanf from a ref_rev_parse_rules
- * rule, that is replace the %.*s spec with a %s spec
- */
-static void gen_scanf_fmt(char *scanf_fmt, const char *rule)
-{
-   char *spec;
-
-   spec = strstr(rule, %.*s);
-   if (!spec || strstr(spec + 4, %.*s))
-   die(invalid rule in ref_rev_parse_rules: %s, rule);
-
-   /* copy all until spec */
-   strncpy(scanf_fmt, rule, spec - rule);
-   scanf_fmt[spec - rule] = '\0';
-   /* copy new spec */
-   strcat(scanf_fmt, %s);
-   /* copy remaining rule */
-   strcat(scanf_fmt, spec + 4);
-
-   return;
-}
-
 char *shorten_unambiguous_ref(const char *refname, int strict)
 {
int i;
@@ -3364,8 +3341,13 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
static int nr_rules;
char *short_name;
 
-   /* pre generate scanf formats from ref_rev_parse_rules[] */
if (!nr_rules) {
+   /*
+* Pre-generate scanf formats from ref_rev_parse_rules[].
+* Generate a format suitable for scanf from a
+* ref_rev_parse_rules rule by interpolating %s at the
+* location of the %.*s.
+*/
size_t total_len = 0;
size_t offset = 0;
 
@@ -3378,9 +3360,10 @@ char *shorten_unambiguous_ref(const char *refname, int 
strict)
 
offset = 0;
for (i = 0; i  nr_rules; i++) {
+   assert(offset  total_len);
scanf_fmts[i] = (char *)scanf_fmts[nr_rules] + offset;
-   gen_scanf_fmt(scanf_fmts[i], ref_rev_parse_rules[i]);
-   offset += strlen(ref_rev_parse_rules[i]);
+   offset += snprintf(scanf_fmts[i], total_len - offset,
+  ref_rev_parse_rules[i], 2, %s) + 1;
}
}
 
-- 
1.8.5.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/5] get_sha1: speed up ambiguous 40-hex test

2014-01-08 Thread Michael Haggerty
On 01/08/2014 12:59 AM, Jeff King wrote:
 Since 798c35f (get_sha1: warn about full or short object
 names that look like refs, 2013-05-29), a 40-hex sha1 causes
 us to call dwim_ref on the result, on the off chance that we
 have a matching ref. This can cause a noticeable slow-down
 when there are a large number of objects.  E.g., on
 linux.git:
 
   [baseline timing]
   $ best-of-five git rev-list --all --pretty=raw
   real0m3.996s
   user0m3.900s
   sys 0m0.100s
 
   [same thing, but calling get_sha1 on each commit from stdin]
   $ git rev-list --all commits
   $ best-of-five -i commits git rev-list --stdin --pretty=raw
   real0m7.862s
   user0m6.108s
   sys 0m1.760s
 
 The problem is that each call to dwim_ref individually stats
 the possible refs in refs/heads, refs/tags, etc. In the
 common case, there are no refs that look like sha1s at all.
 We can therefore do the same check much faster by loading
 all ambiguous-looking candidates once, and then checking our
 index for each object.
 
 This is technically more racy (somebody might create such a
 ref after we build our index), but that's OK, as it's just a
 warning (and we provide no guarantees about whether a
 simultaneous process ran before or after the ref was created
 anyway).

It's not only racy WRT other processes.  If the current git process
would create a new reference, it wouldn't be reflected in the cache.

It's true that the main ref_cache doesn't invalidate itself
automatically either when a new reference is created, so it's not really
a fair complaint.  However, as we add places where the cache is
invalidated, it is easy to overlook this cache that is stuck in static
variables within a function definition and it is impossible to
invalidate it.  Might it not be better to attach the cache to the
ref_cache structure instead, and couple its lifetime to that object?

Alternatively, the cache could be created and managed on the caller
side, since the caller would know when the cache would have to be
invalidated.  Also, different callers are likely to have different
performance characteristics.  It is unlikely that the time to initialize
the cache will be amortized in most cases; in fact, rev-list --stdin
might be the *only* plausible use case.

Regarding the overall strategy: you gather all refnames that could be
confused with an SHA-1 into a sha1_array, then later look up SHA-1s in
the array to see if they are ambiguous.  This is a very special-case
optimization for SHA-1s.

I wonder whether another approach would gain almost the same amount of
performance but be more general.  We could change dwim_ref() (or a
version of it?) to read its data out of a ref_cache instead of going to
disk every time.  Then, at the cost of populating the relevant parts of
the ref_cache once, we would have fast dwim_ref() calls for all strings.

It's true that the lookups wouldn't be quite so fast--they would require
a few bisects per refname lookup (one for each level in the refname
hierarchy) and several refname lookups (one for each ref_rev_parse_rule)
for every dwim_ref() call, vs. a single bisect in your current design.
But this approach it would bring us most of the gain, it might
nevertheless be preferable.

 Here is the time after this patch, which implements the
 strategy described above:
 
   $ best-of-five -i commits git rev-list --stdin --pretty=raw
   real0m4.966s
   user0m4.776s
   sys 0m0.192s
 
 We still pay some price to read the commits from stdin, but
 notice the system time is much lower, as we are avoiding
 hundreds of thousands of stat() calls.
 
 Signed-off-by: Jeff King p...@peff.net
 ---
 I wanted to make the ref traversal as cheap as possible, hence the
 NO_RECURSE flag I added. I thought INCLUDE_BROKEN used to not open up
 the refs at all, but it looks like it does these days. I wonder if that
 is worth changing or not.

What do you mean by open up the refs?  The loose reference files are
read when populating the cache.  (Was that ever different?)  But the
call to ref_resolves_to_object() in do_one_ref() is skipped when the
INCLUDE_BROKEN flag is used.

 
  refs.c  | 47 +++
  refs.h  |  2 ++
  sha1_name.c |  4 +---
  3 files changed, 50 insertions(+), 3 deletions(-)
 
 diff --git a/refs.c b/refs.c
 index ca854d6..cddd871 100644
 --- a/refs.c
 +++ b/refs.c
 @@ -4,6 +4,7 @@
  #include tag.h
  #include dir.h
  #include string-list.h
 +#include sha1-array.h
  
  /*
   * Make sure ref is something reasonable to have under .git/refs/;
 @@ -2042,6 +2043,52 @@ int dwim_log(const char *str, int len, unsigned char 
 *sha1, char **log)
   return logs_found;
  }
  
 +static int check_ambiguous_sha1_ref(const char *refname,
 + const unsigned char *sha1,
 + int flags,
 + void *data)
 +{
 + unsigned char tmp_sha1[20];
 + if (strlen(refname) == 40  

Re: [PATCH v2 5/5] get_sha1: drop object/refname ambiguity flag

2014-01-08 Thread Michael Haggerty
On 01/08/2014 01:00 AM, Jeff King wrote:
 Now that our object/refname ambiguity test is much faster
 (thanks to the previous commit), there is no reason for code
 like cat-file --batch-check to turn it off. Here are
 before and after timings with this patch (on git.git):
 
   $ git rev-list --objects --all | cut -d' ' -f1 objects
 
   [with flag]
   $ best-of-five -i objects ./git cat-file --batch-check
   real0m0.392s
   user0m0.368s
   sys 0m0.024s
 
   [without flag, without speedup; i.e., pre-25fba78]
   $ best-of-five -i objects ./git cat-file --batch-check
   real0m1.652s
   user0m0.904s
   sys 0m0.748s
 
   [without flag, with speedup]
   $ best-of-five -i objects ./git cat-file --batch-check
   real0m0.388s
   user0m0.356s
   sys 0m0.028s
 
 So the new implementation does just as well as we did with
 the flag turning the whole thing off (better actually, but
 that is within the noise).
 
 Signed-off-by: Jeff King p...@peff.net
 [...]

Very nice.  Correctness without a performance hit.

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu
http://softwareswirl.blogspot.com/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH mm/mv-file-to-no-such-dir-with-slash] mv: let 'git mv file no-such-dir/' error out on Windows, too

2014-01-08 Thread Johannes Sixt
The previous commit c57f628 (mv: let 'git mv file no-such-dir/' error out)
relies on that rename(src, dst/) fails if directory dst does not
exist (note the trailing slash). This does not work as expected on Windows:
This rename() call is successful. Insert an explicit check for this case.

This changes the error message from

   $ git mv file no-such-dir/
   fatal: renaming 'file' failed: Not a directory

to

   $ git mv file no-such-dir/
   fatal: destination directory does not exist, source=file, 
destination=no-such-dir/

Signed-off-by: Johannes Sixt j...@kdbg.org
---
 builtin/mv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/builtin/mv.c b/builtin/mv.c
index 08fbc03..21c46d1 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -214,6 +214,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
}
} else if (string_list_has_string(src_for_dst, dst))
bad = _(multiple sources for the same target);
+   else if (is_dir_sep(dst[strlen(dst) - 1]))
+   bad = _(destination directory does not exist);
else
string_list_insert(src_for_dst, dst);
 
-- 
1.8.5.2.1473.g6546919

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Ryan Biesemeyer
From a1f898fdf560e719d447a544569d5d1457307855 Mon Sep 17 00:00:00 2001
From: Ryan Biesemeyer r...@yaauie.com
Date: Wed, 8 Jan 2014 04:22:12 +
Subject: [PATCH 0/2] merge make merge state available to prepare-commit-msg hook

Since prepare-commit-msg hook is given 'merge' as an argument when a merge is
taking place, it was surprising that the merge state (MERGE_HEAD, etc.) was not
present for the hook's execution.

Make sure that the merge state is written before the prepare-commit-msg hook is
called.

Ryan Biesemeyer (2):
  merge: make prepare_to_commit responsible for write_merge_state
  merge: drop unused arg from abort_commit method signature

 builtin/merge.c| 13 +++--
 t/t7505-prepare-commit-msg-hook.sh | 22 ++
 2 files changed, 29 insertions(+), 6 deletions(-)

-- 
1.8.5




signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [PATCH] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Ryan Biesemeyer
From 9b431e5206652cf62ebb09dad4607989976e7748 Mon Sep 17 00:00:00 2001
From: Ryan Biesemeyer r...@yaauie.com
Date: Wed, 8 Jan 2014 00:46:41 +
Subject: [PATCH 1/2] merge: make prepare_to_commit responsible for
 write_merge_state

When merging, make the prepare-commit-msg hook have access to the merge
state in order to make decisions about the commit message it is preparing.

Since `abort_commit` is *only* called after `write_merge_state`, and a
successful commit *always* calls `drop_save` to clear the saved state, this
change effectively ensures that the merge state is also available to the
prepare-commit-msg hook and while the message is being edited.

Signed-off-by: Ryan Biesemeyer r...@yaauie.com
---
 builtin/merge.c|  3 ++-
 t/t7505-prepare-commit-msg-hook.sh | 22 ++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index 4941a6c..b7bfc9c 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -802,7 +802,6 @@ static void abort_commit(struct commit_list *remoteheads, 
const char *err_msg)
error(%s, err_msg);
fprintf(stderr,
_(Not committing merge; use 'git commit' to complete the 
merge.\n));
-   write_merge_state(remoteheads);
exit(1);
 }
 
@@ -816,6 +815,8 @@ N_(Please enter a commit message to explain why this merge 
is necessary,\n
 static void prepare_to_commit(struct commit_list *remoteheads)
 {
struct strbuf msg = STRBUF_INIT;
+
+   write_merge_state(remoteheads);
strbuf_addbuf(msg, merge_msg);
strbuf_addch(msg, '\n');
if (0  option_edit)
diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 3573751..89cdfe8 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -181,5 +181,27 @@ test_expect_success 'with failing hook (merge)' '
test_must_fail git merge other
 
 '
+git merge --abort # cleanup, since the merge failed.
+
+test_expect_success 'should have MERGE_HEAD (merge)' '
+
+   git checkout -B other HEAD@{1} 
+   echo more  file 
+   git add file 
+   rm -f $HOOK 
+   git commit -m other 
+   git checkout - 
+   write_script $HOOK -EOF
+   if [ -s $(git rev-parse --git-dir)/MERGE_HEAD ]; then
+   exit 0
+   else
+   exit 1
+   fi
+   EOF
+   git merge other 
+   test `git log -1 --pretty=format:%s` = Merge branch '''other''' 

+   test ! -s $(git rev-parse --git-dir)/MERGE_HEAD
+
+# '
 
 test_done
-- 
1.8.5



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [PATCH] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Ryan Biesemeyer
From a1f898fdf560e719d447a544569d5d1457307855 Mon Sep 17 00:00:00 2001
From: Ryan Biesemeyer r...@yaauie.com
Date: Wed, 8 Jan 2014 00:47:41 +
Subject: [PATCH 2/2] merge: drop unused arg from abort_commit method signature

Since abort_commit is no longer responsible for writing merge state, remove
the unused argument that was originally needed solely for writing merge state.

Signed-off-by: Ryan Biesemeyer r...@yaauie.com
---
 builtin/merge.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index b7bfc9c..c3108cf 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -795,8 +795,7 @@ static void read_merge_msg(struct strbuf *msg)
die_errno(_(Could not read from '%s'), filename);
 }
 
-static void write_merge_state(struct commit_list *);
-static void abort_commit(struct commit_list *remoteheads, const char *err_msg)
+static void abort_commit(const char *err_msg)
 {
if (err_msg)
error(%s, err_msg);
@@ -812,6 +811,7 @@ N_(Please enter a commit message to explain why this merge 
is necessary,\n
Lines starting with '%c' will be ignored, and an empty message aborts\n
the commit.\n);
 
+static void write_merge_state(struct commit_list *);
 static void prepare_to_commit(struct commit_list *remoteheads)
 {
struct strbuf msg = STRBUF_INIT;
@@ -824,15 +824,15 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
write_merge_msg(msg);
if (run_hook(get_index_file(), prepare-commit-msg,
 git_path(MERGE_MSG), merge, NULL, NULL))
-   abort_commit(remoteheads, NULL);
+   abort_commit(NULL);
if (0  option_edit) {
if (launch_editor(git_path(MERGE_MSG), NULL, NULL))
-   abort_commit(remoteheads, NULL);
+   abort_commit(NULL);
}
read_merge_msg(msg);
stripspace(msg, 0  option_edit);
if (!msg.len)
-   abort_commit(remoteheads, _(Empty commit message.));
+   abort_commit(_(Empty commit message.));
strbuf_release(merge_msg);
strbuf_addbuf(merge_msg, msg);
strbuf_release(msg);
-- 
1.8.5




signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [PATCH] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Ryan Biesemeyer

On 2014-01-08, at 20:06Z, Matthieu Moy matthieu@grenoble-inp.fr wrote:

 Ryan Biesemeyer r...@yaauie.com writes:
 
 index 3573751..89cdfe8 100755
 --- a/t/t7505-prepare-commit-msg-hook.sh
 +++ b/t/t7505-prepare-commit-msg-hook.sh
 @@ -181,5 +181,27 @@ test_expect_success 'with failing hook (merge)' '
  test_must_fail git merge other
 
 '
 +git merge --abort # cleanup, since the merge failed.
 
 Please, avoid having code outside a test_expect_* (see t/README,  - Put
 all code inside test_expect_success and other assertions.).

In this case it was not immediately clear to me how to add cleanup to an 
existing
test that dirtied the state of the test repository by leaving behind an 
in-progress
merge. I see `test_cleanup` defined in the test lib  related functions, but 
see no
examples of its use in the test suites. Could you advise? 

 
 +test_expect_success 'should have MERGE_HEAD (merge)' '
 +
 +git checkout -B other HEAD@{1} 
 +echo more  file 
 +git add file 
 +rm -f $HOOK 
 +git commit -m other 
 +git checkout - 
 +write_script $HOOK -EOF
 +if [ -s $(git rev-parse --git-dir)/MERGE_HEAD ]; then
 +exit 0
 +else
 +exit 1
 +fi
 +EOF
 
 I think you lack one  for the write_script line.

Good catch.

 There's another instance in the same file (probably where you got it
 from), you should add this to your patch series:

I'm new to the mailing-list patch submission process; how would I go about 
adding it?
Submit the cover-letter  patches again? Squash your commit into the relevant 
one of
mine?

 From c3d754a2a16d98b31d43a7e45973821ae8adc043 Mon Sep 17 00:00:00 2001
 From: Matthieu Moy matthieu@imag.fr
 Date: Wed, 8 Jan 2014 21:03:27 +0100
 Subject: [PATCH] t7505: add missing 
 
 ---
 t/t7505-prepare-commit-msg-hook.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/t/t7505-prepare-commit-msg-hook.sh 
 b/t/t7505-prepare-commit-msg-hook.sh
 index 3573751..1c95652 100755
 --- a/t/t7505-prepare-commit-msg-hook.sh
 +++ b/t/t7505-prepare-commit-msg-hook.sh
 @@ -174,7 +174,7 @@ test_expect_success 'with failing hook (merge)' '
   git add file 
   rm -f $HOOK 
   git commit -m other 
 - write_script $HOOK -EOF
 + write_script $HOOK -EOF 
   exit 1
   EOF
   git checkout - 
 -- 
 1.8.5.rc3.4.g8bd3721
 
 (a quick git grep write_script seems to show a lot of other instances,
 but no time to dig this now sorry)
 
 -- 
 Matthieu Moy
 http://www-verimag.imag.fr/~moy/

Thanks for the review.

--
Ryan Biesemeyer (@yaauie)



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [PATCH] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Jonathan Nieder
Hi,

Ryan Biesemeyer wrote:

 In this case it was not immediately clear to me how to add cleanup to an 
 existing
 test that dirtied the state of the test repository by leaving behind an 
 in-progress
 merge. I see `test_cleanup` defined in the test lib  related functions, but 
 see no
 examples of its use in the test suites. Could you advise? 

test_when_finished pushes a command to be run unconditionally
when the current test assertion finishes.

Thanks,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Jonathan Nieder
Matthieu Moy wrote:

 Jonathan's answer is an option. Another one is
[...]
 So if the cleanup goes wrong, one can notice.

test_when_finished also makes the test fail if the cleanup failed.

Another common strategy is

test_expect_success 'my exciting test' '
# this test will rely on these files being absent
rm -f a b c etc 

... rest of the test goes here ...
'

which can be a handy way for an especially picky test to protect
itself (for example with 'git clean -fdx') regardless of the state
other test assertions create for it.

This particular example (merge --abort) seems like a good use for
test_when_finished because it is about a specific test having made a
mess and needing to clean up after itself to restore sanity.

Hoping that clarifies,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-08 Thread Francesco Pretto
2014/1/8 W. Trevor King wk...@tremily.us:
 To elaborate the idea I sketched out here [2], say
 you want:

   Superproject branch  Submodule branch  Upstream branch
   ===    ===
   master   mastermaster
   super-featuremastermaster
   my-feature   my-featuremaster
   other-featureother-feature other-feature

 That's only going to work with per-superproject-branch configs for
 both the local and remote branches.  Using the same name for both
 local and remote branches does not work.


After long thoughts, I think your idea about a local branch with a
differently named remote branch looks interesting but I would be
extremely cautious to add a ' submodule.name.local-branch' now. Do
we have a similar mechanism on regular repository clones? We can clone
and switch to a branch other than master by default, but can we also
have a different remote by default? If we don't have it, we shouldn't
add it first on submodules, as there's the chance the feature never
get coupled on  the regular clones.

Also, I think you fear too much that this can't be added also later.

I think you should pursue your initial proposal of --branch means
attached to get it upstream first. It's alone, IMO, a great
improvement on submodules.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/5] implement @{publish} shorthand

2014-01-08 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 In a triangular workflow, you may have a distinct
 @{upstream} that you pull changes from, but publish by
 default (if you typed git push) to a different remote (or
 a different branch on the remote). It may sometimes be
 useful to be able to quickly refer to that publishing point
 (e.g., to see which changes you have that have not yet been
 published).

 This patch introduces the branch@{publish} shorthand (or
 @{pu} to be even shorter). It refers to the tracking

If @{u} can already be used for upstream, why not allow @{p} but
require two letters @{pu}?  Just being curious---I am not advocating
strongly for a shorter short-hand.

Or is @{p} already taken by something and my memory is not
functioning well?

 branch of the remote branch to which you would push if you
 were to push the named branch. That's a mouthful to explain,
 so here's an example:

   $ git checkout -b foo origin/master
   $ git config remote.pushdefault github
   $ git push

 Signed-off-by: Jeff King p...@peff.net
 ---
 The implementation feels weird, like the where do we push to code
 should be factored out from somewhere else. I think what we're doing
 here is not _wrong_, but I don't like repeating what git push is doing
 elsewhere. And I just punt on simple as a result. :)

  sha1_name.c | 76 
 -
  1 file changed, 75 insertions(+), 1 deletion(-)

 diff --git a/sha1_name.c b/sha1_name.c
 index 50df5d4..59ffa93 100644
 --- a/sha1_name.c
 +++ b/sha1_name.c
 @@ -435,6 +435,12 @@ static inline int upstream_mark(const char *string, int 
 len)
   return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
  }
  
 +static inline int publish_mark(const char *string, int len)
 +{
 + const char *suffix[] = { @{publish} };
 + return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
 +}
 +
  static int get_sha1_1(const char *name, int len, unsigned char *sha1, 
 unsigned lookup_flags);
  static int interpret_nth_prior_checkout(const char *name, struct strbuf 
 *buf);
  
 @@ -481,7 +487,8 @@ static int get_sha1_basic(const char *str, int len, 
 unsigned char *sha1)
   nth_prior = 1;
   continue;
   }
 - if (!upstream_mark(str + at, len - at)) {
 + if (!upstream_mark(str + at, len - at) 
 + !publish_mark(str + at, len - at)) {
   reflog_len = (len-1) - (at+2);
   len = at;
   }
 @@ -1100,6 +1107,69 @@ static int interpret_upstream_mark(const char *name, 
 int namelen,
   return len + at;
  }
  
 +static const char *get_publish_branch(const char *name_buf, int len)
 +{
 + char *name = xstrndup(name_buf, len);
 + struct branch *b = branch_get(*name ? name : NULL);
 + struct remote *remote = b-pushremote;
 + const char *dst;
 + const char *track;
 +
 + free(name);
 +
 + if (!remote)
 + die(_(branch '%s' has no remote for pushing), b-name);
 +
 + /* Figure out what we would call it on the remote side... */
 + if (remote-push_refspec_nr)
 + dst = apply_refspecs(remote-push, remote-push_refspec_nr,
 +  b-refname);
 + else
 + dst = b-refname;
 + if (!dst)
 + die(_(unable to figure out how '%s' would be pushed),
 + b-name);
 +
 + /* ...and then figure out what we would call that remote here */
 + track = apply_refspecs(remote-fetch, remote-fetch_refspec_nr, dst);
 + if (!track)
 + die(_(%s@{publish} has no tracking branch for '%s'),
 + b-name, dst);
 +
 + return track;
 +}
 +
 +static int interpret_publish_mark(const char *name, int namelen,
 +   int at, struct strbuf *buf)
 +{
 + int len;
 +
 + len = publish_mark(name + at, namelen - at);
 + if (!len)
 + return -1;
 +
 + switch (push_default) {
 + case PUSH_DEFAULT_NOTHING:
 + die(_(cannot use @{publish} with push.default of 'nothing'));
 +
 + case PUSH_DEFAULT_UNSPECIFIED:
 + case PUSH_DEFAULT_MATCHING:
 + case PUSH_DEFAULT_CURRENT:
 + set_shortened_ref(buf, get_publish_branch(name, at));
 + break;
 +
 + case PUSH_DEFAULT_UPSTREAM:
 + set_shortened_ref(buf, get_upstream_branch(name, at));
 + break;
 +
 + case PUSH_DEFAULT_SIMPLE:
 + /* ??? */
 + die(@{publish} with simple unimplemented);
 + }
 +
 + return at + len;
 +}
 +
  /*
   * This reads short-hand syntax that not only evaluates to a commit
   * object name, but also can act as if the end user spelled the name
 @@ -1150,6 +1220,10 @@ int interpret_branch_name(const char *name, int 
 namelen, struct strbuf 

Re: Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-08 Thread Francesco Pretto
2014/1/8 W. Trevor King wk...@tremily.us:
 I also prefer 'checkout' to 'head', because 'checkout'
 already exists in non-submodule Git for switching between local
 branches.


Reasons I would loosely support 'git submodule checkout'

1)  It's true that 'git submodule checkout' would also often run 'git checkout'.

Reasons, as an user, I seriously would *not* like 'git submodule checkout'
-
1) 'git submodule checkout' would also touch '.git/config' and
'.gitmodules', and I don't like much the idea of a 'checkout' command
touching config files. It looks dirty.
2) Having 'git checkout', 'git checkout --recurse-submodules' and
finally 'git submodule checkout' is too much for me.

Also, in my proposal, 'git submodule [tobedecided] --attach' would
also merge orphaned commits by default, and 'checkout' is not about
merge.

Reasons I would fervently support 'git submodule head'

1) It tells immediately that this command is about HEAD of the
submodule, and will take care of it. Newcomers would loveit if they
don't like their HEAD state;
2) head is unspecific enough to admit it can also touch
'.git/config' and '.gitmodules'.

Said this, it seems Heiko[1] proposed a similar syntax and the only
difference was about names, not behavior of the command to be added
(if we eventually take this path, ofc).

 On Wed, Jan 08, 2014 at 01:17:49AM +0100, Francesco Pretto wrote:
 # Attach the submodule HEAD to branch.
 # Also set .git/config 'submodule.module.branch' to branch
 $ git submodule head -b branch --attach module

 I prefer submodule.name.local-branch for the submodule's local
 branch name.

I think this was still part of your original misunderstanding about my
git submodule head. This command would touch 'branch' property
anyway because '-b branch' would still be the remote branch, even in
the case you have a 'local-branch' property (maybe to be coupled here
with a --local-branch local-branch switch).

Greetings,
Francesco

[1] http://marc.info/?l=gitm=138913435216349w=2
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-08 Thread W. Trevor King
On Thu, Jan 09, 2014 at 12:07:56AM +0100, Francesco Pretto wrote:
 After long thoughts, I think your idea about a local branch with a
 differently named remote branch looks interesting but I would be
 extremely cautious to add a ' submodule.name.local-branch' now. Do
 we have a similar mechanism on regular repository clones?

The default upstream branch is currently configured with
branch.name.merge.  Earlier [1], I suggested we piggyback on this
for the submodule's upstream branches, and only use
submodule.name.branch for the initial setup.  That would allow
developers to configure upstreams on a per-submodule-branch basis.  We
should probably fall back to submodule.name.branch if the submodule
does not have a branch.name.merge configured.

However, submodule.name.local-branch has nothing to do with remote
repositories or tracking branches.  It just selects the preferred
submodule branch for the superproject branch.  This will only work for
in-tree .gitmodules configs (since the contents are per-branch).  I
don't have a good idea for where local overrides would live.  We'd
want something like
branch.superproject-branch.submodule.submodule-name.local-branch:

  [branch my-feature]
remote = origin
merge = refs/heads/my-feature
[submodule submod]
local-branch = my-feature

and I don't think Git's config supports such nesting.

 We can clone and switch to a branch other than master by default,
 but can we also have a different remote by default?

Sure, the existing submodule.name.url defines the remote repository,
and the existing submodule.name.branch defines the remote branch.
The existing code even sets up remote.origin.url and
branch.name.merge (to the matching refs/heads/name) in the the
submodule's config.

 Also, I think you fear too much that this can't be added also later.

We can add submodule.name.local-branch support later, but I see no
reason not to add it on top of Jens and Jonathan's current submodule
checkout work.  With increasingly robust submodule checkout support in
the core, I expect the amount of update logic stored in
git-submodule.sh will decrease significantly.

 I think you should pursue your initial proposal of --branch means
 attached to get it upstream first. It's alone, IMO, a great
 improvement on submodules.

I can resuscitate that if folks want, but Heiko felt that my initial
consolidation didn't go far enough [2].  If it turns out that we're ok
with the current level of consolidation, would you be ok with
non-checkout submodule.name.update as the trigger [3]?  I think
that adding a halfway step between the current status and full(ish)
submodule.name.local-branch support is just going to confuse people
;).

Cheers,
Trevor

[1]: http://article.gmane.org/gmane.comp.version-control.git/240164
[2]: http://article.gmane.org/gmane.comp.version-control.git/239968
[3]: http://article.gmane.org/gmane.comp.version-control.git/239973

-- 
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy


signature.asc
Description: OpenPGP digital signature


Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-08 Thread W. Trevor King
On Thu, Jan 09, 2014 at 12:54:54AM +0100, Francesco Pretto wrote:
 2) Having 'git checkout', 'git checkout --recurse-submodules' and
 finally 'git submodule checkout' is too much for me.

Agreed.  Since 'git checkout' already exists and 'git checkout
--recurse-submodules' is close [1,2], I think that means we should
drop this and start arguing about adjusting 'git checkout
--recurse-submodules' to checkout branches as well ;).

 Also, in my proposal, 'git submodule [tobedecided] --attach' would
 also merge orphaned commits by default, and 'checkout' is not about
 merge.

And that's good.  Bailing with “you have orphaned commits, which you
should integrate them with $some_integration_command before checking
out a different branch” is better than having overlapping
responsibilities between the checkout command and the integration
command.

Cheers,
Trevor

[1]: http://thread.gmane.org/gmane.comp.version-control.git/239695
[2]: http://article.gmane.org/gmane.comp.version-control.git/240117

-- 
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy


signature.asc
Description: OpenPGP digital signature


[PATCH v2 0/4] merge: make merge state available to prepare-commit-msg hook

2014-01-08 Thread Ryan Biesemeyer
Ensure merge state is available to the prepare-commit-msg hook.

v2 patchset incorporates early feedback from the list

Matthieu Moy (1):
  t7505: add missing 

Ryan Biesemeyer (3):
  t7505: ensure cleanup after hook blocks merge
  merge: make prepare_to_commit responsible for write_merge_state
  merge: drop unused arg from abort_commit method signature

 builtin/merge.c| 13 +++--
 t/t7505-prepare-commit-msg-hook.sh | 30 ++
 2 files changed, 33 insertions(+), 10 deletions(-)

-- 
1.8.5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/4] merge: make prepare_to_commit responsible for write_merge_state

2014-01-08 Thread Ryan Biesemeyer
When merging, make the prepare-commit-msg hook have access to the merge
state in order to make decisions about the commit message it is preparing.

Since `abort_commit` is *only* called after `write_merge_state`, and a
successful commit *always* calls `drop_save` to clear the saved state, this
change effectively ensures that the merge state is also available to the
prepare-commit-msg hook and while the message is being edited.

Signed-off-by: Ryan Biesemeyer r...@yaauie.com
---
 builtin/merge.c|  3 ++-
 t/t7505-prepare-commit-msg-hook.sh | 21 +
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index 4941a6c..b7bfc9c 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -802,7 +802,6 @@ static void abort_commit(struct commit_list *remoteheads, 
const char *err_msg)
error(%s, err_msg);
fprintf(stderr,
_(Not committing merge; use 'git commit' to complete the 
merge.\n));
-   write_merge_state(remoteheads);
exit(1);
 }
 
@@ -816,6 +815,8 @@ N_(Please enter a commit message to explain why this merge 
is necessary,\n
 static void prepare_to_commit(struct commit_list *remoteheads)
 {
struct strbuf msg = STRBUF_INIT;
+
+   write_merge_state(remoteheads);
strbuf_addbuf(msg, merge_msg);
strbuf_addch(msg, '\n');
if (0  option_edit)
diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 697ecc0..7ccf870 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -183,4 +183,25 @@ test_expect_success 'with failing hook (merge)' '
   )
 '
 
+test_expect_success 'should have MERGE_HEAD (merge)' '
+
+   git checkout -B other HEAD@{1} 
+   echo more  file 
+   git add file 
+   rm -f $HOOK 
+   git commit -m other 
+   git checkout - 
+   write_script $HOOK -EOF 
+   if [ -s $(git rev-parse --git-dir)/MERGE_HEAD ]; then
+   exit 0
+   else
+   exit 1
+   fi
+   EOF
+   git merge other 
+   test `git log -1 --pretty=format:%s` = Merge branch '''other''' 

+   test ! -s $(git rev-parse --git-dir)/MERGE_HEAD
+
+'
+
 test_done
-- 
1.8.5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/4] t7505: ensure cleanup after hook blocks merge

2014-01-08 Thread Ryan Biesemeyer
Signed-off-by: Ryan Biesemeyer r...@yaauie.com
---
 t/t7505-prepare-commit-msg-hook.sh | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 1c95652..697ecc0 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -168,18 +168,19 @@ test_expect_success 'with failing hook (--no-verify)' '
 '
 
 test_expect_success 'with failing hook (merge)' '
-
-   git checkout -B other HEAD@{1} 
-   echo more  file 
-   git add file 
-   rm -f $HOOK 
-   git commit -m other 
-   write_script $HOOK -EOF 
-   exit 1
-   EOF
-   git checkout - 
-   test_must_fail git merge other
-
+  test_when_finished git merge --abort 
+  (
+   git checkout -B other HEAD@{1} 
+   echo more  file 
+   git add file 
+   rm -f $HOOK 
+   git commit -m other 
+   write_script $HOOK -EOF 
+   exit 1
+   EOF
+   git checkout - 
+   test_must_fail git merge other
+  )
 '
 
 test_done
-- 
1.8.5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/4] t7505: add missing

2014-01-08 Thread Ryan Biesemeyer
From: Matthieu Moy matthieu@imag.fr

Signed-off-by: Ryan Biesemeyer r...@yaauie.com
---
 t/t7505-prepare-commit-msg-hook.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t7505-prepare-commit-msg-hook.sh 
b/t/t7505-prepare-commit-msg-hook.sh
index 3573751..1c95652 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -174,7 +174,7 @@ test_expect_success 'with failing hook (merge)' '
git add file 
rm -f $HOOK 
git commit -m other 
-   write_script $HOOK -EOF
+   write_script $HOOK -EOF 
exit 1
EOF
git checkout - 
-- 
1.8.5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 4/4] merge: drop unused arg from abort_commit method signature

2014-01-08 Thread Ryan Biesemeyer
Since abort_commit is no longer responsible for writing merge state, remove
the unused argument that was originally needed solely for writing merge state.

Signed-off-by: Ryan Biesemeyer r...@yaauie.com
---
 builtin/merge.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index b7bfc9c..c3108cf 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -795,8 +795,7 @@ static void read_merge_msg(struct strbuf *msg)
die_errno(_(Could not read from '%s'), filename);
 }
 
-static void write_merge_state(struct commit_list *);
-static void abort_commit(struct commit_list *remoteheads, const char *err_msg)
+static void abort_commit(const char *err_msg)
 {
if (err_msg)
error(%s, err_msg);
@@ -812,6 +811,7 @@ N_(Please enter a commit message to explain why this merge 
is necessary,\n
Lines starting with '%c' will be ignored, and an empty message aborts\n
the commit.\n);
 
+static void write_merge_state(struct commit_list *);
 static void prepare_to_commit(struct commit_list *remoteheads)
 {
struct strbuf msg = STRBUF_INIT;
@@ -824,15 +824,15 @@ static void prepare_to_commit(struct commit_list 
*remoteheads)
write_merge_msg(msg);
if (run_hook(get_index_file(), prepare-commit-msg,
 git_path(MERGE_MSG), merge, NULL, NULL))
-   abort_commit(remoteheads, NULL);
+   abort_commit(NULL);
if (0  option_edit) {
if (launch_editor(git_path(MERGE_MSG), NULL, NULL))
-   abort_commit(remoteheads, NULL);
+   abort_commit(NULL);
}
read_merge_msg(msg);
stripspace(msg, 0  option_edit);
if (!msg.len)
-   abort_commit(remoteheads, _(Empty commit message.));
+   abort_commit(_(Empty commit message.));
strbuf_release(merge_msg);
strbuf_addbuf(merge_msg, msg);
strbuf_release(msg);
-- 
1.8.5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-08 Thread Francesco Pretto
2014/1/9 W. Trevor King wk...@tremily.us:

 However, submodule.name.local-branch has nothing to do with remote
 repositories or tracking branches.

My bad: this means the feature is still not entirely clear to me.


   [branch my-feature]
 remote = origin
 merge = refs/heads/my-feature
 [submodule submod]
 local-branch = my-feature

 and I don't think Git's config supports such nesting.


Aesthetically, It doesn't look very nice.


 I can resuscitate that if folks want, but Heiko felt that my initial
 consolidation didn't go far enough [2].  If it turns out that we're ok
 with the current level of consolidation, would you be ok with
 non-checkout submodule.name.update as the trigger [3]?

For me it was ok with what you did:
-
if just_cloned and config_branch
then
 !git reset --hard -q
fi
-

So yes: at the first clone 'checkout' keeps attached HEAD, while
'merge' and 'rebase' attach to the branch.
If it's not the first clone, you should take no action (and your
original patch was ok about this).

  I think
 that adding a halfway step between the current status and full(ish)
 submodule.name.local-branch support is just going to confuse people

Well, for now you got some success in confusing me with this local-branch :)

At certain point  you may ask maintainers what are the accepted
features (because all these debates should be about getting, or not
getting, endorsement about something) and finalize a patch so people
can further review.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] submodule: Respect requested branch on all clones

2014-01-08 Thread W. Trevor King
On Thu, Jan 09, 2014 at 02:09:37AM +0100, Francesco Pretto wrote:
 2014/1/9 W. Trevor King wk...@tremily.us:
[branch my-feature]
  remote = origin
  merge = refs/heads/my-feature
  [submodule submod]
  local-branch = my-feature
 
  and I don't think Git's config supports such nesting.
 
 Aesthetically, It doesn't look very nice.

The INI syntax does not lend itself to easy nesting, but I'm pretty
sure some mapping from (superproject-branch, submodule-name) to
submodule-local-branch-name is what we need for submodule checkouts.
I'm just not sure where local overides to the per-branch .gitmodules
should live.  We could turn it around, and store:

  [superproject superproject-branch]
  local-branch = submodule-local-branch-name

in .git/modules/submodule-name/config, with the UI:

  $ cd submodule
  $ git config superproject.superproject-branch.local-branch = 
submodule-branch

Not beautiful, but maybe a bit more palatable, and already supported
by Git's current config parser.  That's enough that I can work up a
patch that will hopefully clarify my position ;).

Cheers,
Trevor

-- 
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy


signature.asc
Description: OpenPGP digital signature


[PATCH] fetch: Print full url in header

2014-01-08 Thread Tom Miller
Do not remove / and .git from the end of the header url when
fetching. This affects the output of fetch and fetch --prune
making the header url more consistent with remote --verbose.

Add tests to verify that fetch and fetch --prune do not strip the
trailing characters from the header url.

Output before this patch:

$ git fetch remote-with-dot-git-and-slash
From https://github.com/git/git
   a155a5f..5512ac5  maint  - upstream/maint

Output after this patch:

$ git fetch remote-with-dot-git-and-slash
From https://github.com/git/git.git/
   a155a5f..5512ac5  maint  - upstream/maint

Signed-off-by: Tom Miller jacker...@gmail.com
---

This patch should be based on the tip of next because it is dependent
on the code from tm/fetch-prune.

Initially I thought I would stop anonymizing the header url as well.
Then I ran across this commit.

 commit 47abd85ba06ed7209d1caa3e5ac7cc6b232bece4
 Author: Andreas Ericsson a...@op5.se
 Date:   Fri Apr 17 10:20:11 2009 +0200

 fetch: Strip usernames from url's before storing them

 When pulling from a remote, the full URL including username
 is by default added to the commit message. Since it adds
 very little value but could be used by malicious people to
 glean valid usernames (with matching hostnames), we're far
 better off just stripping the username before storing the
 remote URL locally.

 Note that this patch has no lasting visible effect when
 git pull does not create a merge commit. It simply
 alters what gets written to .git/FETCH_HEAD, which is used
 by git merge to automagically create its messages.

 Signed-off-by: Andreas Ericsson a...@op5.se
 Signed-off-by: Junio C Hamano gits...@pobox.com

After reading this and trying different things with the code. I believe
it would make sense to continue to anonymize the url for output to the
terminal. I found if someone is using HTTP basic authentication and has
the username and password in the url. Then, one could unexpectedly
compromise their credentials during a fetch. I do not believe that
anyone should store their credentials in this way, but it is better safe
than sorry.

I also chose to continue to strip the trailing characters for the
FETCH_HEAD file.  I wanted the input of the mailing list to see if we
should also stop striping the trailing characters off of the url written
to FETCH_HEAD? If so, I'll do it as a seperate patch.

 builtin/fetch.c  | 15 +++
 t/t5510-fetch.sh | 29 -
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 025bc3e..01df749 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -664,8 +664,7 @@ static int store_updated_refs(const char *raw_url, const 
char *remote_name,
*what ? what : HEAD);
if (note.len) {
if (verbosity = 0  !shown_url) {
-   fprintf(stderr, _(From %.*s\n),
-   url_len, url);
+   fprintf(stderr, _(From %s\n), url);
shown_url = 1;
}
if (verbosity = 0)
@@ -723,7 +722,7 @@ static int fetch_refs(struct transport *transport, struct 
ref *ref_map)
 static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
const char *raw_url)
 {
-   int url_len, i, result = 0;
+   int result = 0;
struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, 
ref_map);
char *url;
const char *dangling_msg = dry_run
@@ -735,19 +734,11 @@ static int prune_refs(struct refspec *refs, int 
ref_count, struct ref *ref_map,
else
url = xstrdup(foreign);
 
-   url_len = strlen(url);
-   for (i = url_len - 1; url[i] == '/'  0 = i; i--)
-   ;
-
-   url_len = i + 1;
-   if (4  i  !strncmp(.git, url + i - 3, 4))
-   url_len = i - 3;
-
for (ref = stale_refs; ref; ref = ref-next) {
if (!dry_run)
result |= delete_ref(ref-name, NULL, 0);
if (verbosity = 0  !shown_url) {
-   fprintf(stderr, _(From %.*s\n), url_len, url);
+   fprintf(stderr, _(From %s\n), url);
shown_url = 1;
}
if (verbosity = 0) {
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 12674ac..882bfa1 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -614,15 +614,34 @@ test_expect_success 'all boundary commits are excluded' '
test_bundle_object_count .git/objects/pack/pack-${pack##pack

Nike Air Max 1 Dame Billig

2014-01-08 Thread Stanche
 Bare gribe muligheden.Så er der en kræver for dig at købe et enkelt par nye
varemærke sko for at spille basketball. Du har været at sætte dette par Nike
fodtøj for at spille bolde for omkring to mange år og der er helt sikkert
knæk i skoene. Som værende et spørgsmål om det,  Nike Air Max 90 Dame Tilbud
http://www.skobilligt.com/nike-air-max   at du er fodret med jagt tæerne i
tid til at træde ind i retten en gang har du en bold en gang mere. Ja det er
tid til du ændre et enkelt par nye sneakers for at deltage i basketall. Så
er denne gang der et par af god kvalitetsfodtøj passer til dine behov. Der
er ingen kræver for dig at tage meget langt mere indkomst ud af dine lommer
til at købe dette par kondisko og det vil være evigtvarende for slid og har
en flere nye justere for effektivitet. Jeg mener, at det virkelig er
ordentlig tid for dig at sige noget til dig selv. Er der ønsker at få en høj
kvalitets sneakers, at du bare kan muligvis tillade sig at men dem? Svaret
er korrekte.Sneakers har mellemlag med nylon og hele luft kvartal er dens
samlede komponent.



--
View this message in context: 
http://git.661346.n2.nabble.com/Nike-Air-Max-1-Dame-Billig-tp7601780.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Nike Air Max 1 Dame Billig

2014-01-08 Thread Stanche
Nike basketball sneakers are endorsed by common NBA players like Lebron
James, Kobe Bryant and Dwayne Wade, to name a couple of.There is absolutely
no ought to value excessive money to buy another sort of sneakers called
Nike Air Max Pure Game. You can find some mid sole and manual upper for Air
Max Pure Game and it is the very same as Air Max Quarter. Additionally, 
Nike Air Max 1 Sale http://www.trainerscheap.co.uk/nike-air-max   there
are the very best skills for applying to produce this shoe.Because then Nike
has released 23 various versions on the Air Jordan basketball shoe, in
varying colour schemes, including the Nike Jumpman footwear worn by school
basketball teams, including the North Carolina Tarheels. Air Jordans are
marked by Jordan's Jumpman logo. 



--
View this message in context: 
http://git.661346.n2.nabble.com/Nike-Air-Max-1-Dame-Billig-tp7601780p7601781.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Verifiable git archives?

2014-01-08 Thread Andy Lutomirski
It's possible, in principle, to shove enough metadata into the output
of 'git archive' to allow anyone to verify (without cloning the repo)
to verify that the archive is a correct copy of a given commit.  Would
this be considered a useful feature?

Presumably there would be a 'git untar' command that would report
failure if it fails to verify the archive contents.

This could be as simple as including copies of the commit object and
all relevant tree objects and checking all of the hashes when
untarring.

(Even better: allow subsets of the repository to be archived and
verified as well.)

--Andy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Nike Free 5.0 Sko Billigt

2014-01-08 Thread Stanche
Du kan finde masser af Nike sko, som er tilgængelige over hele og hvis din
søgning for Nike vandreture sneakers, de har god top kvalitet vandresko, som
er fremragende til vandreture. Her er nogle fra Nike sko.I sommerlejr Nike
disciplin Hockey vil atleter træne under formynderskab fra de største
trænere og atleter i sporten. Disse nøje udvalgte specialister er der at
inspirere og træne atleter at fuldføre smartere ved at styrke teknik, skaber
selvtillid og gøre dem anerkende deres nøjagtige sandsynligvis som værende
en field hockey player. Bestemt en af mennesker dele af fløde er normalt at
være beliggende sted Nike 'kryds' på skoen begynder ud,  Nike Air Max Thea
http://www.tilbudskodk.com/nike-air-max   med en ekstra portion creme på
området foran på skoen hurtigt forud for bunden af sko tunge.Sko sål er
dybest set sort, men med pletter af creme på den.Selv om ikke udtrykkeligt
mærket som værende en stor dunk, er Nike 9782 så stor som de alle kommer.
Denne højde er opnået inden for et tidsrum af måder. For startere, omfatter
Nike Dunk 9782 virkelig en forhøjet sål, således at den laveste del af
fodtøj vigtigste fysik er altid kan identificeres i det mindste af en tomme
over jorden - takket være den høje sole. Hvis du er helt sikkert en ung felt
hockey spiller jagt for at forbedre dit spil, kan Nike Shox Turbo6 mænds
hvidguld meget vel være det ideelle sted for dig.



--
View this message in context: 
http://git.661346.n2.nabble.com/Nike-Free-5-0-Sko-Billigt-tp7601783.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Nike Free 5.0 Sko Billigt

2014-01-08 Thread Stanche
 Eftersom avgiften inom stövlar är bara inte riktigt så liten, hur kan vi
skaffa billiga air max 2011 sneakers skor? För dem som är lyckliga gott om,
du kan köpa billiga stövlar på rea.Men inte alla har denna typ av bra
utsikter. Endast en liten mängd befolkning har denna behandling. För
personer som vill köpa den ekonomiska skor,  Nike Free 5.0 Dam
http://www.freeskorse.com/nike-free   kan du utforska det inne på nätet.Du
hittar massor av Nike distributörer och återförsäljare som du bara kan
uppnå. Och ifall du inte hittar den 1 som du bara hade sökt för, kan du få
Nike skor på internet. Du hittar massor av Nike skor som kan erbjudas över
platsen och om din söker för Nike vandring sneakers, de har bra kvalitet
vandring skor som är förvisso utmärkt för vandring. Här är några av Nike
skor.Nike disciplin Hockey sommaren kommer att säsong läger idrottare träna
under ledning på den största tränare och idrottare i sporten.



--
View this message in context: 
http://git.661346.n2.nabble.com/Nike-Free-5-0-Sko-Billigt-tp7601783p7601784.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v3 0/4] Preferred local submodule branches

2014-01-08 Thread W. Trevor King
From: W. Trevor King wk...@tremily.us

In another branch of the submodule thread Francesco kicked off, I
mentioned that we could store the preferred local submodule branch on
a per-superbranch level if we used the
.git/modules/submodule-name/config for local overrides [1].  Here's
a patch series that greatly extends my v2 submodule: Respect
requested branch on all clones series [2] to also support automatic,
recursive submodule checkouts, as I outlined here [3].  After this
series, I can get through:

  # create the subproject
  mkdir subproject 
  (
cd subproject 
git init 
echo 'Hello, world'  README 
git add README 
git commit -m 'Subproject v1'
  ) 
  # create the superproject
  mkdir superproject
  (
cd superproject 
git init 
git submodule add ../subproject submod 
git config -f .gitmodules submodule.submod.update merge 
git commit -am 'Superproject v1' 
( # 'submodule update' doesn't look in .gitmodules (yet [4]) for a
  # default update mode.  Copy submodule.submod.update over to
  # .git/config
  git submodule init
)
  ) 
  # start a feature branch on the superproject
  (
cd superproject 
#git checkout -b my-feature --recurse-submodules 
( # 'git submodule checkout --recurse-submodules' doesn't exist yet, so...
  git checkout -b my-feature 
  git submodule checkout -b --gitmodules
) 
(
  cd submod 
  echo 'Add the subproject side of this feature'  my-feature 
  git add my-feature 
  git commit -m 'Add my feature to the subproject'
) 
echo 'Add the superproject side of this feature'  my-feature 
git add my-feature 
git commit -am 'Add the feature to the superproject'
  ) 
  # meanwhile, the subproject has been advancing
  (
cd subproject 
echo 'Goodbye, world'  README 
git commit -am 'Subproject v2'
  ) 
  # we need to get that critical advance into the superproject quick!
  (
cd superproject 
# update the master branch
#git checkout --recurse-submodules master
( # 'git checkout --recurse-submodules' doesn't exist yet [5,6].
  # Even with that patch, 'git checkout' won't respect
  # submodule.name.local-branch without further work.
  git checkout master 
  git submodule checkout
) 
git submodule update --remote 
git commit -am 'Catch submod up with Subproject v2' 
# update the my-feature branch
#git checkout --recurse-submodules my-feature 
( # 'git checkout --recurse-submodules' doesn't exist yet [5,6].
  git checkout my-feature 
  git submodule checkout
) 
git submodule update --remote 
git commit -am 'Catch submod up with Subproject v2' 
# what does the history look like?
(
  cd submod 
  git --no-pager log --graph --date-order --oneline --decorate --all
  # *   16d9e3e (HEAD, my-feature) Merge commit 
'f5e134d5747ee4a206e96d8c017f92f5b29a07f3' into my-feature
  # |\  
  # | * f5e134d (origin/master, origin/HEAD, master) Subproject v2
  # * | 0a1cd07 Add my feature to the subproject
  # |/  
  # * c2d32ba Subproject v1
) 
printf 'master: ' 
git ls-tree master submod 
# master: 16 commit f5e134d5747ee4a206e96d8c017f92f5b29a07f3  submod
printf 'my-feature: ' 
git ls-tree my-feature submod
# my-feature: 16 commit 16d9e3ea2fb57e7a166587203abdb328f90895d1  submod
  )
  git --version
  # git version 1.8.5.2.237.g01c62c6

I think the first three patches are fairly solid.  The last one gets
through the above script, but I'd need a more thorough test suite
before I trusted it.  I tried to be detailed in the commit messages,
but of course, we'd want some user-facing documentation if we actually
merged something like this series.  I'm sending it to the list mostly
to explain my current views and re-focus debate [1].

[1]: http://article.gmane.org/gmane.comp.version-control.git/240240
[2]: http://article.gmane.org/gmane.comp.version-control.git/239967
[3]: http://article.gmane.org/gmane.comp.version-control.git/240192
[4]: http://article.gmane.org/gmane.comp.version-control.git/239246
[5]: http://thread.gmane.org/gmane.comp.version-control.git/239695
[6]: http://article.gmane.org/gmane.comp.version-control.git/240117

Cheers,
Trevor

W. Trevor King (4):
  submodule: Add helpers for configurable local branches
  submodule: Teach 'update' to preserve local branches
  submodule: Teach 'add' about a configurable local-branch
  submodule: Add a new 'checkout' command

 git-submodule.sh | 152 ++-
 1 file changed, 138 insertions(+), 14 deletions(-)

-- 
1.8.5.2.237.g01c62c6

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v3 3/4] submodule: Teach 'add' about a configurable local-branch

2014-01-08 Thread W. Trevor King
From: W. Trevor King wk...@tremily.us

This patch teaches 'git submodule add' to look for a preferred
local-branch, and to checkout that branch after the initial clone.
The local branch will always point at the commit checked out by the
internal 'git clone' operation.  For example:

  $ git submodule add git://example.com/subproject.git submod

will checkout the branch pointed to by the cloned repository's HEAD,
and call the local branch 'master'.

  $ git submodule add -b my-feature git://example.com/subproject.git submod

will checkout the branch pointed to by the cloned repository's
my-feature, and *still* call the local branch 'master'.

'git submodule add' does not always make an initial clone (e.g. if a
git repository already exists at the target path).  In cases where
'git submodule add' does not clone a repository, we just leave the
local branch alone.

This commit also shifts the post-clone branch checkout logic from
cmd_add to module_clone, so it can be shared with cmd_update.  The
previous code only checked out the requested branch in cmd_add but not
in cmd_update; this left the user on a detached HEAD after an update
initially cloned, and subsequent updates kept the HEAD detached,
unless the user moved to the desired branch himself.  Now, unless the
user explicitly asks to work on a detached HEAD, subsequent updates
all happen on the specified branch, which matches the end-user
expectation much better.
---
 git-submodule.sh | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index c5ea7bd..7cee0bf 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -339,7 +339,19 @@ module_clone()
echo gitdir: $rel/$a $sm_path/.git
 
rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')
-   (clear_local_git_env; cd $sm_path  GIT_WORK_TREE=. git config 
core.worktree $rel/$b)
+   superproject_branch=$(get_current_branch)
+   default_local_branch=$(get_submodule_config $sm_name local-branch)
+   (
+   clear_local_git_env
+   cd $sm_path 
+   GIT_WORK_TREE=. git config core.worktree $rel/$b 
+   local_branch=$(get_local_branch ${superproject_branch} 
${default_local_branch}) 
+   # ash fails to wordsplit ${branch:+-b $branch...}
+   case $branch in
+   '') git checkout -f -q -B $local_branch ;;
+   ?*) git checkout -f -q -B $local_branch origin/$branch ;;
+   esac
+   ) || die $(eval_gettext Unable to checkout submodule '\$sm_path')
 }
 
 isnumber()
@@ -503,15 +515,6 @@ Use -f if you really want to add it. 2
fi
fi
module_clone $sm_path $sm_name $realrepo $reference 
$depth || exit
-   (
-   clear_local_git_env
-   cd $sm_path 
-   # ash fails to wordsplit ${branch:+-b $branch...}
-   case $branch in
-   '') git checkout -f -q ;;
-   ?*) git checkout -f -q -B $branch origin/$branch ;;
-   esac
-   ) || die $(eval_gettext Unable to checkout submodule 
'\$sm_path')
fi
git config submodule.$sm_name.url $realrepo
 
-- 
1.8.5.2.237.g01c62c6

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v3 1/4] submodule: Add helpers for configurable local branches

2014-01-08 Thread W. Trevor King
From: W. Trevor King wk...@tremily.us

There are three branches that submodule folks usually care about:

1. The linked $sha1 in the superproject (set explicitly for every
   superproject commit, and thus for every superproject branch).
2. The remote-tracking submodule.name.branch that tracks a branch in
   upstream submodule.name.url repository.
3. The submodule's locally checked out branch, which we currently let
   the developer setup by hand, which is integrated with one of the
   other two branches by non-checkout update modes.

Git is currently a bit weak on conveniently handling branch #3.  Just
use what the developer has setup works well for many basic workflows,
but falls short for:

* Cloning-updates, where we currently always setup a detached HEAD.
  This is easy to fix if you accept submodule.name.branch or the
  branch pointed to by the cloned repository's HEAD as a guess, but
  this conflates branch #2 and branch #3, which may confuse users.

* Workflows where the preferred #3 branch depends on the superproject
  branch.  For example, if the remote subproject has only a master
  branch, but the local superproject needs to develop several
  submodule feature branches simultaneously, you can have a situation
  like this:

Superproject branch  Submodule branch  Subproject branch
===    =
master   mastermaster
feature-1feature-1 master
feature-2feature-2 master
feature-3feature-2 master

In order to checkout the appropriate submodule branch for a given
superproject branch, we need a way to specify the preferred submodule
branch for a given superproject branch.  This commit adds two helper
functions:

* get_current_branch, to determine which superproject branch you're
  on, and
* get_local_branch, to determine the preferred submodule branch for
  that superproject branch.

The lookup chain for the local-branch is:

1. superproject.superproject-branch.local-branch in the submodule's
   config (superproject/.git/modules/submodule-name/config).  This
   is where the developer can store local per-superproject-branch
   overrides (e.g. if they wanted to use submodule branch feature-1
   with superproject branch feature-3).
2. submodule.submodule-name.local-branch in the superproject's
   config.  This is where the developer can store local
   cross-superproject-branch overrides (e.g. if they wanted to use
   submodule branch master for any superproject branch that didn't
   have a per-superproject-branch override).
3. submodule.submodule-name.local-branch in the superproject's
   .gitmodules file.  Because the gitmodules file is stored in the
   superproject's versioned tree, it is automatically
   superproject-branch-specific.  For example:

 $ git cat-file -p feature-1:.gitmodules
 ...
 [submodule submod]
 ...
 local-branch = feature-1
 $ git cat-file -p feature-3:.gitmodules
 ...
 [submodule submod]
 ...
 local-branch = feature-2

   this is where the project-wide defaults are setup and shared
   between developers.
4. The default local-branch is 'master'.

The new get_local_branch function handles the first step in this
chain.  The next two steps are already covered by the existing
get_submodule_config.
---
 git-submodule.sh | 33 +
 1 file changed, 33 insertions(+)

diff --git a/git-submodule.sh b/git-submodule.sh
index 2677f2e..56fc3f1 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -220,6 +220,39 @@ get_submodule_config () {
printf '%s' ${value:-$default}
 }
 
+#
+# Print a submodule's configured local branch name
+#
+# $1 = superproject branch
+# $2 = default (from the superproject's .gitmodules)
+#
+# To be called from the submodule root directory.
+#
+get_local_branch ()
+{
+   superproject_branch=$1
+   default=${2:-master}
+   if test -z ${superproject_branch}
+   then
+   value=
+   else
+   value=$(git config 
superproject.$superproject_branch.local-branch)
+   fi
+   printf '%s' ${value:-$default}
+}
+
+#
+# Print the currently checked out branch of the current repository
+#
+# $1 = default
+#
+get_current_branch ()
+{
+   default=$1
+   branch=$(git rev-parse --abbrev-ref HEAD 2/dev/null) ||
+   branch=
+   printf '%s' ${branch:-$default}
+}
 
 #
 # Map submodule path to submodule name
-- 
1.8.5.2.237.g01c62c6

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v3 4/4] submodule: Add a new 'checkout' command

2014-01-08 Thread W. Trevor King
From: W. Trevor King wk...@tremily.us

This borrows a good deal of the cmd_foreach logic to iterate through
submodules (potentially recursively), checking out the preferred local
branch for each submodule (as appropriate for the current superproject
branch).  Ideally, this logic would be bundled into the forthcoming:

  $ git checkout --recurse-submodules

logic that Jens Lehmann and Jonathan Nieder are working up in C.
Until that happens, you can simulate that checkout behaviour with:

  $ git checkout some-branch
  $ git submodule checkout --recursive

The relevant superproject branch used to determine the preferred
submodule branch is the submodules immediate parent, not the top-level
superproject.  For example, with the following submodule inheritance:

  superproject (branch super-1)
  `-- midproject (branch mid-1)
  `-- subproject (branch sub-1)

The .gitmodules configs should look like (assuming there are no local
overrides):

  $ git cat-file -p super-1:.gitmodules
  ...
  [submodule midproject]
   ...
   local-branch = mid-1
  $ cd midproject
  $ git cat-file -p mid-1:.gitmodules
  ...
  [submodule subproject]
   ...
   local-branch = sub-1

The super-1 branch need not even exist in the midproject repository.

This commit handles branch switches inside existing submodules.
Handling (or even detecting) submodules that are created and destroyed
or moving submodules that change path between the initial and final
superproject branch is put off to future patches.

I also added minimal support for initial branch creation.  Create your
initial branch with:

  $ git checkout -b my-feature
  $ git submodule checkout --recursive -b --gitmodules

which will create new 'my-feature' branches in each submodule (or die
trying).  It will also save 'my-feature' to the superproject's
.gitmodules' submodule.name.local-branch for future checkouts.
After setting up a branch like this, future checkouts (from some other
branch) will look like:

  $ git checkout my-feature
  $ git submodule checkout --recursive
---
 git-submodule.sh | 90 +++-
 1 file changed, 89 insertions(+), 1 deletion(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index 7cee0bf..16cebb1 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -6,6 +6,7 @@
 
 dashless=$(basename $0 | sed -e 's/-/ /')
 USAGE=[--quiet] add [-b branch] [-f|--force] [--name name] [--reference 
repository] [--] repository [path]
+   or: $dashless [--quiet] checkout [--recursive] [-b|-B] [--gitmodules] [--] 
[path...]
or: $dashless [--quiet] status [--cached] [--recursive] [--] [path...]
or: $dashless [--quiet] init [--] [path...]
or: $dashless [--quiet] deinit [-f|--force] [--] path...
@@ -36,6 +37,10 @@ update=
 prefix=
 custom_name=
 depth=
+create_new_branch=
+checkout_options=
+save_in_gitmodules=
+default_local_branch=master
 
 # The function takes at most 2 arguments. The first argument is the
 # URL that navigates to the submodule origin repo. When relative, this URL
@@ -532,6 +537,89 @@ Use -f if you really want to add it. 2
 }
 
 #
+# Checkout the appropriate local branch for each submodule
+#
+cmd_checkout()
+{
+   # parse $args after submodule ... checkout.
+   while test $# -ne 0
+   do
+   case $1 in
+   -q|--quiet)
+   GIT_QUIET=1
+   ;;
+   --recursive)
+   recursive=1
+   ;;
+   -b|-B)
+   checkout_options=${checkout_options} $1
+   create_new_branch=1
+   ;;
+   --gitmodules)
+   save_in_gitmodules=1
+   ;;
+   --)
+   shift
+   break
+   ;;
+   -*)
+   usage
+   ;;
+   *)
+   break
+   ;;
+   esac
+   shift
+   done
+
+   toplevel=$(pwd)
+
+   superproject_branch=$(get_current_branch)
+   if test -n $create_new_branch
+   then
+   default_local_branch=${superproject_branch}
+   fi
+
+   # dup stdin so that it can be restored when running the external
+   # command in the subshell (and a recursive call to this function)
+   exec 30
+
+   module_list $@ |
+   while read mode sha1 stage sm_path
+   do
+   die_if_unmatched $mode
+   name=$(module_name $sm_path) || exit
+   displaypath=$(relative_path $prefix$sm_path)
+   if test -e $sm_path/.git
+   then
+   say $(eval_gettext Entering '\$displaypath')
+   name=$(module_name $sm_path)
+   super_local_branch=$(get_submodule_config $name 
local-branch ${default_local_branch})
+   (
+