Re: Add a bugzilla website
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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/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
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/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
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
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
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
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
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
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
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/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
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
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
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
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?
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
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
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
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
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
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
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}) + ( +