* [PATCH 2/2] Documentation/Makefile: add *.pdf to `clean' target
From: Emilio G. Cota @ 2011-08-08 8:33 UTC (permalink / raw)
To: gitster; +Cc: git, Emilio G. Cota
In-Reply-To: <1312792385-19149-1-git-send-email-cota@braap.org>
From: "Emilio G. Cota" <cota@braap.org>
user-manual.pdf is not removed by `make clean'; fix it.
Signed-off-by: Emilio G. Cota <cota@braap.org>
---
Documentation/Makefile | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 36989b7..18c71d7 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -232,6 +232,7 @@ cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
clean:
$(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7
$(RM) *.texi *.texi+ *.texi++ git.info gitman.info
+ $(RM) *.pdf
$(RM) howto-index.txt howto/*.html doc.dep
$(RM) technical/api-*.html technical/api-index.txt
$(RM) $(cmds_txt) *.made
--
1.7.6
^ permalink raw reply related
* [PATCH 1/2] Documentation: ignore *.pdf files
From: Emilio G. Cota @ 2011-08-08 8:33 UTC (permalink / raw)
To: gitster; +Cc: git, Emilio G. Cota
From: "Emilio G. Cota" <cota@braap.org>
user-manual.pdf is generated by the build and therefore
should be ignored by git.
Signed-off-by: Emilio G. Cota <cota@braap.org>
---
Documentation/.gitignore | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
index 1c3a9fe..d62aebd 100644
--- a/Documentation/.gitignore
+++ b/Documentation/.gitignore
@@ -3,6 +3,7 @@
*.[1-8]
*.made
*.texi
+*.pdf
git.info
gitman.info
howto-index.txt
--
1.7.6
^ permalink raw reply related
* Re: RFC: repository of handy git aliases?
From: Jakub Narębski @ 2011-08-08 9:45 UTC (permalink / raw)
To: Jon Seymour; +Cc: Git Mailing List
In-Reply-To: <CAH3AnrpSeWytri-bHEi_9qkAKG1fjL0pVuYFOrrmZumJ6dv_wg@mail.gmail.com>
On 8/8/11, Jon Seymour <jon.seymour@gmail.com> wrote:
> I was wondering if there is any interest in establishing a wiki page
> or gist repository of git aliases that people find useful?
https://git.wiki.kernel.org/index.php/Aliases
--
Jakub Narebski
^ permalink raw reply
* Re: RFC: repository of handy git aliases?
From: Jon Seymour @ 2011-08-08 10:22 UTC (permalink / raw)
To: Jakub Narębski; +Cc: Git Mailing List
In-Reply-To: <CANQwDwfwvaYQt+ck8ky0obyeAa--Wwtdme3UC4vNMFkSiBMq9g@mail.gmail.com>
On Mon, Aug 8, 2011 at 7:45 PM, Jakub Narębski <jnareb@gmail.com> wrote:
> On 8/8/11, Jon Seymour <jon.seymour@gmail.com> wrote:
>> I was wondering if there is any interest in establishing a wiki page
>> or gist repository of git aliases that people find useful?
>
> https://git.wiki.kernel.org/index.php/Aliases
>
Ah, thanks. I added this link
Aliases - for list of handy tools implemented as git aliases.
to:
https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#See_also
since that is where I expected to find a link when I looked. (Of
course, I should have searched, but I didn't!)
jon.
^ permalink raw reply
* Re: RFC: repository of handy git aliases?
From: Jon Seymour @ 2011-08-08 10:43 UTC (permalink / raw)
To: Jakub Narębski; +Cc: Git Mailing List
In-Reply-To: <CAH3AnrqEfu1jeCo55bJxLDK8845PsLoZtoT0iWkMUtt1+K9X-w@mail.gmail.com>
On Mon, Aug 8, 2011 at 8:22 PM, Jon Seymour <jon.seymour@gmail.com> wrote:
> On Mon, Aug 8, 2011 at 7:45 PM, Jakub Narębski <jnareb@gmail.com> wrote:
>> On 8/8/11, Jon Seymour <jon.seymour@gmail.com> wrote:
I've also added this...
Listing the tips of branches in pu that are not in master
===========================================
Suppose you have two aliases defined like so:
[alias]
oneline = !/usr/bin/xargs -L1 git log --decorate --max-count=1 --oneline
tips = "!_() { t=$(git rev-list --no-merges --max-count=1
\"$@\"); if test -n \"$t\"; then echo $t; _ \"$@\" ^$t; fi; }; _"
Then:
git tips origin/pu ^origin/next | git oneline
might show something like this:
9dcca58 filter-branch.sh: de-dent usage string
704c335 On Cygwin support both UNIX and DOS style path-names
1c460f9 t3030: fix accidental success in symlink rename
9e81372 test-path-utils: Add subcommand "prefix_path"
ad733bd revert: Propagate errors upwards from do_pick_commit
76cf946 fixup! xdiff/xhistogram: rework handling of recursed results
df6a9c7 fixup! describe: Refresh the index when run with --dirty
c9f57a0 squash! ls-files: fix pathspec display on error
a1288bc add--interactive: add option to autosplit hunks
365b78a t5800: point out that deleting branches does not work
c997182 limit "contains" traversals based on commit generation
914b6fb doc/fast-import: document feature import-marks-if-exists
b792c06 branch -v: honor core.abbrev
b166408 mergetool: Don't assume paths are unmerged
b29d76f merge: mark the final "Merge made by..." message for l10n
942cf39 receive-pack: Allow server to refuse pushes with too many objects
which is a list of the tips of branches that are in pu, but not in next.
^ permalink raw reply
* Re: RFC: repository of handy git aliases?
From: Jon Seymour @ 2011-08-08 10:45 UTC (permalink / raw)
To: Jakub Narębski; +Cc: Git Mailing List
In-Reply-To: <CAH3AnrrNPBNNNr7Lm2-vnqOisxWorF4FS32H+LBaybWF3KdnGg@mail.gmail.com>
On Mon, Aug 8, 2011 at 8:43 PM, Jon Seymour <jon.seymour@gmail.com> wrote:
> On Mon, Aug 8, 2011 at 8:22 PM, Jon Seymour <jon.seymour@gmail.com> wrote:
>> On Mon, Aug 8, 2011 at 7:45 PM, Jakub Narębski <jnareb@gmail.com> wrote:
>>> On 8/8/11, Jon Seymour <jon.seymour@gmail.com> wrote:
>
> I've also added this...
>
> Listing the tips of branches in pu that are not in master
> ===========================================
>
master -> next
^ permalink raw reply
* Re: Suppressing auto-cc for specific addresses
From: Daniel Mack @ 2011-08-08 10:58 UTC (permalink / raw)
To: David Aguilar; +Cc: Greg KH, git@vger.kernel.org
In-Reply-To: <D95ADFD4-2504-4BE6-BCD4-7B916F6F2FEB@gmail.com>
On Mon, Aug 8, 2011 at 12:56 PM, David Aguilar <davvid@gmail.com> wrote:
> git send-email has a --[no-]signed-off-by-cc option and configuration
> variable. --
I know, but that's not the point. It about having a certain address
metioned in a ^Cc: line inside the patch and suppress sending off
emails to that specific address. And --suppress-cc currently only
allows categories to be set, not addresses.
Daniel
^ permalink raw reply
* Re: When i run git difftool, git did not use difftool.bc3.cmd,why?
From: David Aguilar @ 2011-08-08 11:08 UTC (permalink / raw)
To: jelly; +Cc: Git讨论组(无须订阅)
In-Reply-To: <9c0c497.f7f.131a1fb4855.Coremail.sinojelly@163.com>
On Aug 6, 2011, at 7:03 PM, jelly <sinojelly@163.com> wrote:
>> When i run git difftool, git did not use difftool.bc3.cmd,why?>Even i write a wrong exe file name bcomp1.exe, git still use bcompare.
> I found the reason.
> because bc3 is a special name, git call bcompare internal.change the name bc3, it works fine.
That's right. We have difftool.<tool>.path for this use case. It lets you redefine the path to the tool (e.g. bcompare).
^ permalink raw reply
* Re: I suggest that git commit support -A option, just like hg does.thanks.
From: Michael Witten @ 2011-08-08 14:04 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Miles Bader, Marc Weber, git
In-Reply-To: <7vfwlc1ox1.fsf@alter.siamese.dyndns.org>
On Mon, Aug 8, 2011 at 04:56, Junio C Hamano <gitster@pobox.com> wrote:
> So far, nobody stepped up to do it, though. I have been taking it as a
> sign that "commit -A" is not one of the commonly desired features but is
> probably closer to your "odd/unusual". It's up to the user/developer
> community to change that ;-)
With regard to anything that can be changed for the better, the vast
majority of people shrug their shoulders, groan, and use what's
already available to them.
^ permalink raw reply
* Re: [PATCH 10/14] http: use hostname in credential description
From: Ted Zlatanov @ 2011-08-08 14:37 UTC (permalink / raw)
To: git
In-Reply-To: <20110722221337.GA15753@sigill.intra.peff.net>
On Fri, 22 Jul 2011 16:13:38 -0600 Jeff King <peff@peff.net> wrote:
JK> I admit I don't have any data beyond my own experiences. GitHub tends
JK> towards the concept of a single identity, and it has some group
JK> management. I don't know about other sites, though. Do you have any
JK> specific examples in mind?
I have not yet needed multiple user names on a single Git server, so I
think it's OK to make that case less convenient to favor the more common
single user name case.
Ted
^ permalink raw reply
* Re: [PATCH 05/48] t6039: Add tests for content issues with modify/rename/directory conflicts
From: Elijah Newren @ 2011-08-08 15:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jgfouca
In-Reply-To: <7vvcuzdusv.fsf@alter.siamese.dyndns.org>
Hi,
Thanks for the many detailed reviews. I've spent much of the weekend
(and before) trying to go through and clean things up, and am still
working on it. There are some things to comment on outside of the
series re-roll I am putting together...
On Mon, Jul 18, 2011 at 5:37 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Could you add a description for this? Your description on 06/48 is
> beautifly done. Here is my attempt.
...
Done. :-) It'll be in the reroll I submit.
> I think I said this in my earlier review, and this is not limited to 05/48
> but also applies to 03/48 and 04/48 as well, but there won't be perfect
> rename detection, and the rename detection logic could change (improve)
> over time. Ideally, I think the test should declare either case as a
> success: (1) detection succeeds and avoids unnecessary conflict, or (2)
> rename is missed and conflict is reported, but otherwise there is no data
> loss. If it expects only one but not the other, any time the rename logic
> is improved, the behaviour could change between (1) and (2) and it will
> cause a false positive "breakage" of these tests.
The same could be said for all the rename tests, but I'm a bit worried
about doing this, particularly for the set of tests I added. I came
up with my testcases by carefully reviewing the code looking for ways
I could trigger problems (which were almost never covered by an
existing regression test), plus trying a few small modifications of
any tests I did come up with. The tests I added that involve renames
really are specifically designed to test renaming situations. If
rename detection logic is modified in a way that affects these tests,
and these tests aren't updated, then we are turning some useful unique
tests into mere duplication of simpler tests we have elsewhere.
If you are worried that these tests lack robustness in the face of
rename-detection changes, perhaps we should modify the tests to use
file contents that are more likely to continue being detected as
renames (e.g. longer lines or maybe more of them)? Or, maybe add an
earlier check in the test to independently verify that the rename is
detected?
^ permalink raw reply
* [PATCH] Support specific color for a specific remote branches
From: Aviv Eyal @ 2011-08-08 15:49 UTC (permalink / raw)
To: git; +Cc: Aviv Eyal
Program 'show branch -a' supports different colors for 'local' and 'remote' branches.
When tracking more then one remote, all branches have the same color.
This change lets the user define a color for each remote, providing better visual distinction for different remotes.
Signed-off-by: Aviv Eyal <avivey@gmail.com>
---
Since my C days are now ancient history, I'm worried I might leak some char*s down there. Also,
I might have missed some apis that would have made this patch smaller.
I'm using a sorted list as a dictionary (Remote name -> Color), which is not too elegant but
probably 'good enough', considering I expect it to be a very small (<3) list.
Aviv.
Documentation/config.txt | 6 ++
builtin/branch.c | 119 +++++++++++++++++++++++++++++++++++++---------
2 files changed, 102 insertions(+), 23 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 0658ffb..efdb61f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -700,6 +700,7 @@ color.branch.<slot>::
`current` (the current branch), `local` (a local branch),
`remote` (a remote-tracking branch in refs/remotes/), `plain` (other
refs).
+ See also `remote.<name>.color`.
+
The value for these configuration variables is a list of colors (at most
two) and attributes (at most one), separated by spaces. The colors
@@ -1658,6 +1659,11 @@ remote.<name>.mirror::
If true, pushing to this remote will automatically behave
as if the `\--mirror` option was given on the command line.
+remote.<name>.color:
+ If set, the `branch` command will use the colors specified here
+ for the names of all branches tracking this remote. Colors
+ specified here take precedent over `color.branch.remote` config.
+
remote.<name>.skipDefaultUpdate::
If true, this remote will be skipped by default when updating
using linkgit:git-fetch[1] or the `update` subcommand of
diff --git a/builtin/branch.c b/builtin/branch.c
index 3142daa..85e6920 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -15,6 +15,7 @@
#include "branch.h"
#include "diff.h"
#include "revision.h"
+#include "string-list.h"
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -46,6 +47,9 @@ enum color_branch {
BRANCH_COLOR_CURRENT = 4
};
+// this string_list is used as a basic dictionary.
+struct string_list custom_colors = STRING_LIST_INIT_DUP;
+
static enum merge_filter {
NO_FILTER = 0,
SHOW_NOT_MERGED,
@@ -68,6 +72,52 @@ static int parse_branch_color_slot(const char *var, int ofs)
return -1;
}
+static char *strclone(const char *start, int len)
+{
+ char *result = malloc((len + 1) * sizeof(char));
+ if (!result)
+ return NULL;
+ strncpy(result, start, len);
+ result[len] = '\0';
+ return result;
+}
+
+static int git_branch_config_custom_color_remote(const char *var, const char *value)
+{
+ struct string_list_item *item;
+ char *name, *color;
+ name = strclone(var + 7, strlen(var) - 13); // "remote."=7, "remote..color"=13.
+ if (!name)
+ return 0;
+ color = malloc(COLOR_MAXLEN * sizeof(char));
+ if (!color) {
+ free(name);
+ return 0;
+ }
+ item = string_list_insert(&custom_colors, name);
+ color_parse(value, var, color);
+ item->util = color;
+ return 0;
+}
+
+static char *git_branch_get_custom_color_remote(const char *name)
+{
+ int name_len;
+ char* repo_name;
+ struct string_list_item *custom;
+ name_len = strchr(name, '/') - name;
+ repo_name = strclone(name, name_len);
+ if (!repo_name)
+ return NULL;
+
+ custom = string_list_lookup(&custom_colors, repo_name);
+ free(repo_name);
+ if (custom)
+ return (char*) custom->util;
+ return NULL;
+}
+
+
static int git_branch_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "color.branch")) {
@@ -83,14 +133,10 @@ static int git_branch_config(const char *var, const char *value, void *cb)
color_parse(value, var, branch_colors[slot]);
return 0;
}
- return git_color_default_config(var, value, cb);
-}
+ if (!prefixcmp(var, "remote.") && !suffixcmp(var, ".color"))
+ return git_branch_config_custom_color_remote(var, value);
-static const char *branch_get_color(enum color_branch ix)
-{
- if (branch_use_color > 0)
- return branch_colors[ix];
- return "";
+ return git_color_default_config(var, value, cb);
}
static int branch_merged(int kind, const char *name,
@@ -354,6 +400,43 @@ static int ref_cmp(const void *r1, const void *r2)
return strcmp(c1->name, c2->name);
}
+static const char *branch_get_color(struct ref_item *item, int current)
+{
+ int index;
+ char *color;
+
+ if (branch_use_color <= 0)
+ return "";
+
+ if (!item)
+ index = BRANCH_COLOR_RESET;
+ else if (current)
+ index = BRANCH_COLOR_CURRENT;
+ else switch (item->kind) {
+ case REF_LOCAL_BRANCH:
+ index = BRANCH_COLOR_LOCAL;
+ break;
+ case REF_REMOTE_BRANCH:
+ index = BRANCH_COLOR_REMOTE;
+ color = git_branch_get_custom_color_remote(item->name);
+ if (color)
+ return color;
+ break;
+ default:
+ index = BRANCH_COLOR_PLAIN;
+ break;
+ }
+
+ return branch_colors[index];
+}
+
+static const char *branch_get_color_reset()
+{
+ if (branch_use_color <= 0)
+ return "";
+ return branch_colors[BRANCH_COLOR_RESET];
+}
+
static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
int show_upstream_ref)
{
@@ -424,18 +507,6 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
if (!matches_merge_filter(commit))
return;
- switch (item->kind) {
- case REF_LOCAL_BRANCH:
- color = BRANCH_COLOR_LOCAL;
- break;
- case REF_REMOTE_BRANCH:
- color = BRANCH_COLOR_REMOTE;
- break;
- default:
- color = BRANCH_COLOR_PLAIN;
- break;
- }
-
c = ' ';
if (current) {
c = '*';
@@ -444,12 +515,12 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
strbuf_addf(&name, "%s%s", prefix, item->name);
if (verbose)
- strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
+ strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(item, current),
maxwidth, name.buf,
- branch_get_color(BRANCH_COLOR_RESET));
+ branch_get_color_reset());
else
- strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color),
- name.buf, branch_get_color(BRANCH_COLOR_RESET));
+ strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(item, current),
+ name.buf, branch_get_color_reset());
if (item->dest)
strbuf_addf(&out, " -> %s", item->dest);
@@ -712,5 +783,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
} else
usage_with_options(builtin_branch_usage, options);
+ string_list_clear(&custom_colors, 1);
+
return 0;
}
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH 3/5] setup_revisions: remember whether a ref was positive or not
From: Johannes Schindelin @ 2011-08-08 16:22 UTC (permalink / raw)
To: Junio C Hamano
Cc: Sverre Rabbelier, Jonathan Nieder, Jeff King, Git List,
Daniel Barkalow, Ramkumar Ramachandra, Dmitry Ivankov
In-Reply-To: <7vy5zabbz7.fsf@alter.siamese.dyndns.org>
Hi Junio,
On Wed, 3 Aug 2011, Junio C Hamano wrote:
> Sverre Rabbelier <srabbelier@gmail.com> writes:
>
> > On Sun, Jul 24, 2011 at 21:23, Junio C Hamano <gitster@pobox.com> wrote:
> >> Sverre Rabbelier <srabbelier@gmail.com> writes:
> >>
> >>> void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
> >>> {
> >>> - add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
> >>> + add_pending_object_with_mode(revs, obj, name, S_IFINVALID, 0);
> >>> }
> >>
> >> This seems utterly broken. For example, fmt-merge-msg.c adds "^HEAD"
> >> and of course the flags on the object is UNINTERESTING. Has all the
> >> callers of add_pending_object() been verified? Why is it passing an
> >> unconditional 0 and not !!(obj->flags & UNINTERESTING) or something?
If you do that, you're back to start. Since obj has not the faintest clue
whether the pending object was added from a negative or a positive ref.
And yes, all the callers have been verified: I don't want them to change.
I only need to catch the callers inside the revision machinery's argument
parsing, since that is what I need anyway, to traverse the objects later
on. And rather than reimplementing the wheel^Wargument parsing, I'd like
to reuse what is already there and just forgets the single bit of
information I need.
The other users of the argument parsing can change their callers if
necessary, when they also need the information about whether a ref was
positive/negative.
> > If I understand correctly (and it's not unlikely that I don't), the
> > 'flags' field is used to store the actual flags (not just a boolean).
> > Would the following be appropriate?
> >
> > + add_pending_object_with_mode(revs, obj, name, S_IFINVALID, obj->flags);
>
> I would think that the information you are trying to convey is more in
> line with the spirit of "name" field, not "mode".
No, it is a flag. The parsed argument is a negative ref. It has a name
(not including the "^") and it has a flag ("negative").
The mode is indeed only relevant for non-commitishs: If you look where a
pending object is added _with_ a mode other than S_IFINVALID, it is only
when calling get_sha1_with_mode(). That function indirectly calls
get_sha1_with_context_1() which sets the mode to ce_mode. In other words,
the mode is the file mode when specifying a blob/tree as <ref>:<path>. All
commits (and tags) have a mode set to S_IFINVALID.
> [...]
>
> Wouldn't it be wonderful if the revision machinery left richer clue in
> each element of the pending object array while parsing, so that the caller
> does not have to guess?
That is what we are trying to solve, and rather than to reuse the "mode" I
thought that it'd be wiser to add new "flags".
Many of the richer clues you refer to could be expressed as such flags,
including the problem I need to address.
For the only itch I have is to get remote-hg working nicely for me, and
Sverre said I can only have that if fast-export is running correctly, i.e.
updating all the refs, even if some other ref already points at the same
commit.
> In addition to a single "mode" integer, which says if it is supposed to
> be a tree or a blob, we could allocate a single structure that records
> something like this:
>
> struct parsed_rev {
> enum {
> SHA1, REF, RANGE, SYMMETRIC_RANGE, REFLOG_ENT, ...
> // there are others like OBJ^!, OBJ@!, ...
> } kind;
> const char *string;
> union {
> struct {
> const char *real_ref;
> } ref;
> struct {
> struct parsed_rev *bottom;
> struct parsed_rev *top;
> } range;
> ...
> } u;
> };
Is this not a little bit of a big, huge, tremendous overkill? All I need
right now is a simple flag. Let's not cross bridges at which we haven't
arrived for another 50 miles yet.
Or in other words: I'd rather stay with a simple, elegant, minimal patch
that solves the problem at hand while not preventing future enhancements.
Also remember that the pending objects array is used for the complete
object traversal. If you make that bigger you might end up with a
substantial increase in memory consumption (which made me think of
reusing the "mode", but then I thought about the possible side effects in
the future and rejected that idea).
The only way to convince me to do that complicated stuff is by
blackmailing me, stating that I cannot have a working remote-hg without
doing all this nested/union/self-referential struct work I don't need.
Ciao,
Johannes
^ permalink raw reply
* Re: [PATCH v2 4/4] upload-archive: use start_command instead of fork
From: René Scharfe @ 2011-08-08 17:10 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Jeff King, Erik Faye-Lund, Junio C Hamano, git
In-Reply-To: <4E3EEF3B.80908@kdbg.org>
Am 07.08.2011 22:02, schrieb Johannes Sixt:
> Am 06.08.2011 11:40, schrieb René Scharfe:
>> So here's an ugly patch to implement an internal passthrough filter to
>> avoid newline conversions. It makes the tar filter command (gzip etc.)
>> write to a pipe instead of directly to a file.
>
> *If* we are working around the CRLF conversion issue in git itself,
> wouldn't it be much simpler to just:
>
> diff --git a/archive-tar.c b/archive-tar.c
> index 20af005..da3d98a 100644
> --- a/archive-tar.c
> +++ b/archive-tar.c
> @@ -364,9 +364,9 @@ void init_tar_archiver(void)
> int i;
> register_archiver(&tar_archiver);
>
> - tar_filter_config("tar.tgz.command", "gzip -cn", NULL);
> + tar_filter_config("tar.tgz.command", "gzip -cn | cat", NULL);
> tar_filter_config("tar.tgz.remote", "true", NULL);
> - tar_filter_config("tar.tar.gz.command", "gzip -cn", NULL);
> + tar_filter_config("tar.tar.gz.command", "gzip -cn | cat", NULL);
> tar_filter_config("tar.tar.gz.remote", "true", NULL);
> git_config(git_tar_config, NULL);
> for (i = 0; i < nr_tar_filters; i++) {
>
> (provided that 'cat' magically does not suffer from the same problem,
> and I do think that it does not.)
The external cat can indeed be used. We'd need to do that for user
supplied commands as well, though, like this (ugh):
diff --git a/archive-tar.c b/archive-tar.c
index 20af005..eaa9a1c 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -326,6 +326,9 @@ static int write_tar_filter_archive(const struct archiver *ar,
die("BUG: tar-filter archiver called with no filter defined");
strbuf_addstr(&cmd, ar->data);
+#ifdef WIN32
+ strbuf_addstr(&cmd, " | cat");
+#endif
if (args->compression_level >= 0)
strbuf_addf(&cmd, " -%d", args->compression_level);
> Anyway, I think it would be better to address the problem on the msysgit
> side. Perhaps by providing a gzip of a different vintage (e.g. a
> self-compiled one) that does not suffer from the CRLF conversion issue.
Users would probably also need sanitized versions of bzip2 and xz, and
perhaps more.
If MSYS could be asked to refrain from switching file descriptors to text
mode, e.g. by setting an environment variable, we could solve the issue
in a generic way instead.
René
^ permalink raw reply related
* Re: [RFC] helping smart-http/stateless-rpc fetch race
From: Junio C Hamano @ 2011-08-08 17:13 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <7vbow01ols.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Shawn Pearce <spearce@spearce.org> writes:
>
>> Why a new --allow-non-tip flag? Why not always do this with the
>> existing --stateless-rpc flag?
>
> It certainly would be much easier from implementation point of view, but I
> did it that way for two and half reasons:
>
> (1) It might make sense to give admins who run upload-pack not behind
> smart-http an option to allow fetching from a non-tip; and
>
> (2) It also might make sense to let admins who do run upload-pack behind
> smart-http force re-fetching when the race is encountered.
>
> and the remaining half-reason was that I was too lazy to think things
> through to refute the above two "might make sense" and convince myself
> that they should instead be "is not necessary".
I still haven't convinced myself but here is a simplified one without the
new option (hence no need to touch the smart-http infrastructure).
-- >8 --
Subject: [PATCH] helping smart-http/stateless-rpc fetch race
A request to fetch from a client over smart HTTP protocol is served in
multiple steps. In the first round, the server side shows the set of refs
it has and their values, and the client picks from them and sends "I want
to fetch the history leading to these commits".
When the server tries to respond to this second request, its refs may have
progressed by a push from elsewhere. By design, we do not allow fetching
objects that are not at the tip of an advertised ref, and the server
rejects such a request. The client needs to try again, which is not ideal
especially for a busy server.
Teach upload-pack (which is the workhorse driven by git-daemon and smart
http server interface) that it is OK for a smart-http client to ask for
commits that are not at the tip of any advertised ref, as long as they are
reachable from advertised refs.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
upload-pack.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 99 insertions(+), 9 deletions(-)
diff --git a/upload-pack.c b/upload-pack.c
index ce5cbbe..30cf941 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -10,6 +10,7 @@
#include "revision.h"
#include "list-objects.h"
#include "run-command.h"
+#include "sigchain.h"
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
@@ -498,11 +499,96 @@ static int get_common_commits(void)
}
}
+static void check_non_tip(void)
+{
+ static const char *argv[] = {
+ "rev-list", "--stdin", NULL,
+ };
+ static struct child_process cmd;
+ struct object *o;
+ char namebuf[42]; /* ^ + SHA-1 + LF */
+ int i;
+
+ /* In the normal in-process case non-tip request can never happen */
+ if (!stateless_rpc)
+ goto error;
+
+ cmd.argv = argv;
+ cmd.git_cmd = 1;
+ cmd.no_stderr = 1;
+ cmd.in = -1;
+ cmd.out = -1;
+
+ if (start_command(&cmd))
+ goto error;
+
+ /*
+ * If rev-list --stdin encounters an unknown commit, it
+ * terminates, which will cause SIGPIPE in the write loop
+ * below.
+ */
+ sigchain_push(SIGPIPE, SIG_IGN);
+
+ namebuf[0] = '^';
+ namebuf[41] = '\n';
+ for (i = get_max_object_index(); 0 < i; ) {
+ o = get_indexed_object(--i);
+ if (!(o->flags & OUR_REF))
+ continue;
+ memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
+ if (write_in_full(cmd.in, namebuf, 42) < 0)
+ goto error;
+ }
+ namebuf[40] = '\n';
+ for (i = 0; i < want_obj.nr; i++) {
+ o = want_obj.objects[i].item;
+ if (o->flags & OUR_REF)
+ continue;
+ memcpy(namebuf, sha1_to_hex(o->sha1), 40);
+ if (write_in_full(cmd.in, namebuf, 41) < 0)
+ goto error;
+ }
+ close(cmd.in);
+
+ sigchain_pop(SIGPIPE);
+
+ /*
+ * The commits out of the rev-list are not ancestors of
+ * our ref.
+ */
+ i = read_in_full(cmd.out, namebuf, 1);
+ if (i)
+ goto error;
+ close(cmd.out);
+
+ /*
+ * rev-list may have died by encountering a bad commit
+ * in the history, in which case we do want to bail out
+ * even when it showed no commit.
+ */
+ if (finish_command(&cmd))
+ goto error;
+
+ /* All the non-tip ones are ancestors of what we advertised */
+ return;
+
+error:
+ /* Pick one of them (we know there at least is one) */
+ for (i = 0; i < want_obj.nr; i++) {
+ o = want_obj.objects[i].item;
+ if (!(o->flags & OUR_REF))
+ break;
+ }
+ die("git upload-pack: not our ref %s",
+ sha1_to_hex(o->sha1));
+}
+
static void receive_needs(void)
{
struct object_array shallows = OBJECT_ARRAY_INIT;
static char line[1000];
int len, depth = 0;
+ int has_non_tip = 0;
shallow_nr = 0;
if (debug_fd)
@@ -559,26 +645,30 @@ static void receive_needs(void)
if (strstr(line+45, "include-tag"))
use_include_tag = 1;
- /* We have sent all our refs already, and the other end
- * should have chosen out of them; otherwise they are
- * asking for nonsense.
- *
- * Hmph. We may later want to allow "want" line that
- * asks for something like "master~10" (symbolic)...
- * would it make sense? I don't know.
- */
o = lookup_object(sha1_buf);
- if (!o || !(o->flags & OUR_REF))
+ if (!o)
die("git upload-pack: not our ref %s",
sha1_to_hex(sha1_buf));
if (!(o->flags & WANTED)) {
o->flags |= WANTED;
+ if (!(o->flags & OUR_REF))
+ has_non_tip = 1;
add_object_array(o, NULL, &want_obj);
}
}
if (debug_fd)
write_str_in_full(debug_fd, "#E\n");
+ /*
+ * We have sent all our refs already, and the other end
+ * should have chosen out of them. When we are operating
+ * in the stateless RPC mode, however, their choice may
+ * have been based on the set of older refs advertised
+ * by another process that handled the initial request.
+ */
+ if (has_non_tip)
+ check_non_tip();
+
if (!use_sideband && daemon_mode)
no_progress = 1;
--
1.7.6.409.ge7a85
^ permalink raw reply related
* Re: [PATCH 10/14] http: use hostname in credential description
From: Junio C Hamano @ 2011-08-08 17:16 UTC (permalink / raw)
To: Jeff King; +Cc: git, spearce
In-Reply-To: <20110722221337.GA15753@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> I expect those cases to be even less common, of course, but it's nice
> that it's straightforward to support them.
>
>> > I tried to optimize for the common case (many repos under one identity)
>> > than the uncommon (many identities under one host).
>>
>> As I am not convinced if this statement is true.
>
> I admit I don't have any data beyond my own experiences. GitHub tends
> towards the concept of a single identity, and it has some group
> management. I don't know about other sites, though. Do you have any
> specific examples in mind?
I think I heard Shawn talk about Gerrit installations where multiple
instances that serve separate userbases are behind a shared Apache
front-end that would be problematic with this limitation.
^ permalink raw reply
* Re: [PATCH 3/5] setup_revisions: remember whether a ref was positive or not
From: Junio C Hamano @ 2011-08-08 17:47 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Sverre Rabbelier, Jonathan Nieder, Jeff King, Git List,
Daniel Barkalow, Ramkumar Ramachandra, Dmitry Ivankov
In-Reply-To: <alpine.DEB.1.00.1108081748060.7748@s15462909.onlinehome-server.info>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Hi Junio,
>
> On Wed, 3 Aug 2011, Junio C Hamano wrote:
>
>> Sverre Rabbelier <srabbelier@gmail.com> writes:
>>
>> > On Sun, Jul 24, 2011 at 21:23, Junio C Hamano <gitster@pobox.com> wrote:
>> >> Sverre Rabbelier <srabbelier@gmail.com> writes:
>> >>
>> >>> void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
>> >>> {
>> >>> - add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
>> >>> + add_pending_object_with_mode(revs, obj, name, S_IFINVALID, 0);
>> >>> }
> ...
> If you do that, you're back to start. Since obj has not the faintest clue
> whether the pending object was added from a negative or a positive ref.
But the point is that this codepath does not have a faintest clue whether
the "obj" parameter is something the end user actively asked for (which
might have been marked as uninteresting for other reasons, namely, because
it is reachable from other negative refs). So passing unconditional 0 is
just as bad.
>> Wouldn't it be wonderful if the revision machinery left richer clue in
>> each element of the pending object array while parsing, so that the caller
>> does not have to guess?
>
> That is what we are trying to solve, and rather than to reuse the "mode" I
> thought that it'd be wiser to add new "flags".
I never thought about nor suggested touching "mode" ;-) It does not have
enough width for the necessary information.
> Many of the richer clues you refer to could be expressed as such flags,
> including the problem I need to address.
>
>> In addition to a single "mode" integer, which says if it is supposed to
>> be a tree or a blob, we could allocate a single structure that records...
>
> Is this not a little bit of a big, huge, tremendous overkill?
As long as you can show your "flags" can (be extended to) express the same
richness to solve sample problems I mentioned in my response, as well as
your immediate issue, I wouldn't insist implementing a parsed struct/union
that may be a more (and unnecessarily) verbose way to say the same thing.
> Or in other words: I'd rather stay with a simple, elegant, minimal patch
> that solves the problem at hand while not preventing future enhancements.
We are on the same page, but what I read from the patch didn't show a
clear way forward to extend the "flags" to allow the stuff I mentioned
(and the stuff I didn't but obviously fall into the same category of "we
wish revision parsing machinery left us richer information").
> Also remember that the pending objects array is used for the complete
> object traversal.
My reading and rememberance of the code around add_parents_to_list() must
be quite different from yours. It is not 2006 anymore.
We didn't even have a separate pending object list type until 1f1e895 (Add
"named object array" concept, 2006-06-19) and used the same object_list,
whose element size _did_ matter as you mention. But that commit allowed us
to give elements on the pending list that came directly from the end user
richer semantics than those of the object_list that we discover during the
traversal, and that is why back at e5709a4 (add add_object_array_with_mode,
2007-04-22) we gave more information to it without having to fatten
object_list elements.
> The only way to convince me to do that complicated stuff is by
> blackmailing me, stating that I cannot have a working remote-hg without
> doing all this nested/union/self-referential struct work I don't need.
I would be reluctant to accept a myopic hack that is only good for one
caller and that needs to be ripped out and re-done, especially when we
already know other issues that can be solved cleanly if you go a little
further in the initial round.
As I said, I am not married to the verbose struct/union representation
(the only reason I showed that verbosity was because it allowed me to do
away without having to enumerate all the syntax sugars we already
support); if your "flags" can express the same thing (it may needs to
become a bitfield with enough width, but I highly suspect that you would
also need at least a component that says "this is the string the user gave
us --- the user said 'master', not 'master^0', for example) and is a lot
more compact, that is definitely we want to go with.
Thanks.
^ permalink raw reply
* Re: [PATCH 07/48] t6039: Ensure rename/rename conflicts leave index and workdir in sane state
From: Elijah Newren @ 2011-08-08 17:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jgfouca
In-Reply-To: <7vaacbb1jn.fsf@alter.siamese.dyndns.org>
On Mon, Jul 18, 2011 at 5:40 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> +# Test for all kinds of things that can go wrong with rename/rename (2to1):
>> +# Commit A: new files: a & b
>> +# Commit B: rename a->c, modify b
>> +# Commit C: rename b->c, modify a
>> +#
>> +# Merging of B & C should NOT be clean. Questions:
>> +# * Both a & b should be removed by the merge; are they?
>> +# * The two c's should contain modifications to a & b; do they?
>> +# * The index should contain two files, both for c; does it?
>> +# * The working copy should have two files, both of form c~<unique>; does it?
>> +# * Nothing else should be present. Is anything?
>
> What is the most useful thing to leave in the index and in the working
> tree for the person who needs to resolve such a merge using the working
> tree, starting from B and merging C? The above "Questions" lists what the
> current code might try to do but I am not sure if it is really useful. For
> example, in the index, you would have to stuff two stage #1 entries ("a"
> from A and "b" from A) for path "c", with stage #2 ("c" from B) and stage
> #3 ("c" from C) entries, and represent what B tried to do to "a" (in the
> above you said "rename a->c" but it does not have to be a rename without
> content change) and what C tried to do to "b" in the half-conflicted
> result that is in a single file "c". Because the result are totally
> unrelated files (one side wants a variant of original "a" there, the other
> side wants a variant of "b"), such a half-merge result is totally useless
> to help the person to come up with anything.
>
> Also renaming "c" to "c~<unique>", if they do not have corresponding
> entries in the index to let you check with "git diff", would make the
> result _harder_ to use, not easier. So if you are going to rename "c" to
> "c-B" and "c-C", at least it would make much more sense to have in the
> index:
>
> - "c-B", with stage #1 ("a" from A), stage #2 ("c" from B) and stage #3
> ("a" from C);
> - "c-C", with stage #1 ("b" from A), stage #2 ("b" from B) and stage #3
> ("c" from C); and
> - No "a" nor "b" in the index nor in the working tree.
>
> no?
>
> That way, you could run "git diff" to get what happened to the two
> variants of "a" and "b" at the content level, and decide to clean things
> up with:
>
> $ git diff ;# view content level merge
> $ edit c-B c-C; git add c-B c-C
> $ git mv c-B c-some-saner-name
> $ git mv c-C c-another-saner-name
> $ edit other files that refer to c like Makefile
> $ git commit
That sounds very interesting. My first thought is that you'd have to
do the same thing in the case of a D/F conflict, but I notice that
later in the patch series you asked for exactly that. The idea
certainly has potential, though I might need to think it through a
little more.
> To take it one step further to the extreme, it might give us a more
> reasonable and useful conflicted state if we deliberately dropped some
> information instead in a case like this, e.g.:
>
> - We may want to have "a" at stage #1 (from A) in the index;
> - No "a" remains in the working tree;
> - "b" at stage #1 (from A), stage #2 (from B) and stage #3 ("c" from C);
> - "b" in the working tree a conflicted-merge of the above three;
> - "c" at stage #1 ("a" from A), stage #2 (from B), and stage #3 ("a" from
> C); and
> - "c" in the working tree a conflicted-merge of the above three.
>
> Note that unlike the current merge-recursive that tries to come up with a
> temporary pathname to store both versions of C, this would ignore "mv b c"
> on the A->C branch, and make the conflicted tentative merge asymmetric
> (merging B into C and merging C into B would give different conflicts),
> but I suspect that the asymmetry may not hurt us.
>
> Whether the merger wants to keep "c" that was derived from "a" (in line
> with the HEAD) or "c" that was derived from "b" (in line with MERGE_HEAD),
> if the result were to keep both files in some shape, the content level
> edit, renaming of at least one side, and adjusting other files that refer
> to it, are all required anyway, e.g.
>
> $ git diff ;# view content level merge
> $ edit b c; git add b c
> $ edit other files that refer to c line Makefile (the content C's
> change wants is now in "b").
> $ git commit
>
> would be a way to pick "c" as "c-some-saner-name" and "b" as
> "c-another-saner-name" in the previous workflow, but needs much less
> typing. The complexity of the workflow would be the same if the final
> resolution is to take what one side did and dropping the other's work,
> I think.
I think the asymmetry is slightly confusing and could become
problematic. If we decide to turn on break detection, then we would
hit problems in a scenario such as:
Commit A: files a, b are present
Commit B: rename a->c, add an unrelated a
Commit C: rename b->c, add an unrelated b
In that case, "undoing" the rename as you suggest gives us a conflict
with other content that was added at the path.
Also, as mentioned above, D/F conflicts hit similar cases where we
need to rename the path in the working copy. If we try to handle them
similarly to how you are suggesting for the rename/rename(2to1) case,
we can do so in some cases but hit problems in others. For example,
take a rename/delete conflict with D/F conflicts:
Commit A: file a is present
Commit B: rename a -> df, possibly also modifying it
Commit C: delete a, add files a/foo and df/bar
We can't use either the path 'df' or 'a' for recording the content. I
think the rules become too confusing for "selectively undoing renames"
and it'd be easier to just use <bad-dest-path>~<unique> in all cases.
However, I think your suggestion to move index stage information to
these uniquely renamed paths could probably work and may be useful.
^ permalink raw reply
* Re: [PATCH 09/48] t6036: criss-cross with weird content can fool git into clean merge
From: Elijah Newren @ 2011-08-08 18:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jgfouca
In-Reply-To: <7vaacbdus4.fsf@alter.siamese.dyndns.org>
On Mon, Jul 18, 2011 at 5:38 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Elijah Newren <newren@gmail.com> writes:
>
>> +# Commit E: file with contents:
>> +# <<<<<<< Temporary merge branch 1
>> +# C
>> +# =======
>> +# B
>> +# >>>>>>> Temporary merge branch 2
>> +#
>> +# Now, when we merge commits D & E, does git detect the conflict?
>
> This is way too artificial that I personally feel not worth worrying
> about.
I wasn't going to try to do anything to fix it. Should I drop this
patch from the series or is it worth keeping around for completeness?
^ permalink raw reply
* Re: [PATCH] Support specific color for a specific remote branches
From: Junio C Hamano @ 2011-08-08 18:08 UTC (permalink / raw)
To: Aviv Eyal; +Cc: git
In-Reply-To: <1312818553-25042-1-git-send-email-avivey@gmail.com>
Aviv Eyal <avivey@gmail.com> writes:
> +remote.<name>.color:
> + If set, the `branch` command will use the colors specified here
> + for the names of all branches tracking this remote. Colors
> + specified here take precedent over `color.branch.remote` config.
> +static char *strclone(const char *start, int len)
> +{
Hmm, don't we have xmemdupz() for this?
> + char *result = malloc((len + 1) * sizeof(char));
> + if (!result)
> + return NULL;
> + strncpy(result, start, len);
> + result[len] = '\0';
> + return result;
> +}
> +
> +static int git_branch_config_custom_color_remote(const char *var, const char *value)
> +{
> + struct string_list_item *item;
> + char *name, *color;
> + name = strclone(var + 7, strlen(var) - 13); // "remote."=7, "remote..color"=13.
No // comments please.
> + if (!name)
> + return 0;
> + color = malloc(COLOR_MAXLEN * sizeof(char));
At least use xmalloc(); also isn't sizeof(char) by definition 1?
> + if (!color) {
> + free(name);
> + return 0;
> + }
> + item = string_list_insert(&custom_colors, name);
> + color_parse(value, var, color);
> + item->util = color;
It may be just a style thing, but I'd rather see this caller call
color_parse() first, and after letting that function validate the end-user
input, call string_list_insert().
Also what happens when there are two entries that talk about the same
remote branch in the configuration? Such a configuration is not an error;
your ~/.gitconfig may say one thing for remote.origin.master and your
repository specific .git/config may override it for a particular
repository.
> + return 0;
> +}
> +
> +static char *git_branch_get_custom_color_remote(const char *name)
> +{
> + int name_len;
> + char* repo_name;
> + struct string_list_item *custom;
> + name_len = strchr(name, '/') - name;
Who said a remote name is terminated with (and cannot contain) a slash?
Shouldn't this code be consulting the configuration file to learn the
remote mapping, e.g.
[remote "frotz"]
fetch = +refs/heads/*:refs/remotes/nitfol/*
so that remote branches from "frotz" remote, that happen to be stored
under refs/remotes/nitfol/ hierarchy, are painted in the correct color?
^ permalink raw reply
* Re: [PATCH 10/48] t6036: tests for criss-cross merges with various directory/file conflicts
From: Elijah Newren @ 2011-08-08 19:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jgfouca
In-Reply-To: <7v39i3b1jg.fsf@alter.siamese.dyndns.org>
On Mon, Jul 18, 2011 at 5:40 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> +test_expect_failure 'git detects conflict and handles merge of D & E1 correctly' '
>> + git reset --hard &&
>> + git reset --hard &&
>> + git clean -fdqx &&
>> + git checkout D^0 &&
>
> Why do you need to reset twice? Superstition (you have a commented one
> introduced later in the series --- perhaps this shows a bug in reset)?
I could have sworn that when I first created these tests last
September that the double reset was needed to get back to a clean
state. I can't seem to duplicate the issue now, though I do see some
"error" messages printed on the first reset despite the reset working
successfully. I'll drop the extra one. *shrug*
[I'm not ignoring the many other good comments you made on this patch;
they just got incorporated into code and comment changes for the next
version of the series I send out.]
^ permalink raw reply
* [PATCH v2 0/2] submodule: move gitdir into superproject
From: Fredrik Gustafsson @ 2011-08-08 19:17 UTC (permalink / raw)
To: git; +Cc: iveqy, jens.lehmann, hvoigt, gitster
Move git-dir for submodules into $GIT_DIR/modules/[name_of_submodule] of
the superproject. This is a step towards being able to delete submodule
directories without loosing the information from their .git directory
as that is now stored outside the submodules work tree.
This is done relying on the already existent .git-file functionality.
Tests that rely on .git being a directory have been fixed.
This is the second iteration of this patchseries. The first can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/177582
Fredrik Gustafsson (2):
rev-parse: add option --is-well-formed-git-dir [path]
Move git-dir for submodules
Documentation/git-rev-parse.txt | 4 ++
builtin/rev-parse.c | 8 +++
cache.h | 1 +
git-submodule.sh | 49 ++++++++++++++++--
setup.c | 7 +++
t/t7400-submodule-basic.sh | 4 +-
t/t7403-submodule-sync.sh | 5 +-
t/t7406-submodule-update.sh | 107 +++++++++++++++++++++++++++++++++++++++
t/t7407-submodule-foreach.sh | 103 +++++++++++++++++++------------------
t/t7408-submodule-reference.sh | 4 +-
10 files changed, 231 insertions(+), 61 deletions(-)
--
1.7.6.398.g47bcd.dirty
^ permalink raw reply
* [PATCH v2 2/2] Move git-dir for submodules
From: Fredrik Gustafsson @ 2011-08-08 19:17 UTC (permalink / raw)
To: git; +Cc: iveqy, jens.lehmann, hvoigt, gitster
In-Reply-To: <1312831022-12868-1-git-send-email-iveqy@iveqy.com>
Move git-dir for submodules into $GIT_DIR/modules/[name_of_submodule] of
the superproject. This is a step towards being able to delete submodule
directories without loosing the information from their .git directory
as that is now stored outside the submodules work tree.
This is done relying on the already existent .git-file functionality.
When adding or updating a submodule whose git directory is found under
$GIT_DIR/modules/[name_of_submodule], don't clone it again but simply
point the .git-file to it and remove the now stale index file from it.
Tests that rely on .git being a directory have been fixed.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
git-submodule.sh | 49 ++++++++++++++++--
t/t7406-submodule-update.sh | 107 ++++++++++++++++++++++++++++++++++++++++
t/t7407-submodule-foreach.sh | 6 +-
t/t7408-submodule-reference.sh | 4 +-
4 files changed, 156 insertions(+), 10 deletions(-)
diff --git a/git-submodule.sh b/git-submodule.sh
index bc1d3fa..ace6c1d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -122,14 +122,53 @@ module_clone()
path=$1
url=$2
reference="$3"
+ gitdir=
+ gitdir_base=
+ name=$(module_name "$path")
+ if test -z "$name"
+ then
+ name="$path"
+ fi
+ base_path=$(dirname "$path")
+
+ gitdir=$(git rev-parse --git-dir)
+ gitdir_base="$gitdir/modules/$base_path"
+ gitdir="$gitdir/modules/$path"
+
+ case $gitdir in
+ /*)
+ a="$(cd_to_toplevel && pwd)/"
+ b=$gitdir
+ while [ "$b" ] && [ "${a%%/*}" = "${b%%/*}" ]
+ do
+ a=${a#*/} b=${b#*/};
+ done
+
+ rel="$a$name"
+ rel=`echo $rel | sed -e 's|[^/]*|..|g'`
+ rel_gitdir="$rel/$b"
+ ;;
+ *)
+ rel=`echo $name | sed -e 's|[^/]*|..|g'`
+ rel_gitdir="$rel/$gitdir"
+ ;;
+ esac
- if test -n "$reference"
+ if test -d "$gitdir"
then
- git-clone "$reference" -n "$url" "$path"
+ mkdir -p "$path"
+ echo "gitdir: $rel_gitdir" >"$path/.git"
+ rm -f "$gitdir/index"
else
- git-clone -n "$url" "$path"
- fi ||
- die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
+ mkdir -p "$gitdir_base"
+ if test -n "$reference"
+ then
+ git-clone "$reference" -n "$url" "$path" --separate-git-dir "$gitdir"
+ else
+ git-clone -n "$url" "$path" --separate-git-dir "$gitdir"
+ fi ||
+ die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
+ fi
}
#
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index c679f36..1ae6b4e 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -408,6 +408,7 @@ test_expect_success 'submodule update exit immediately in case of merge conflict
test_cmp expect actual
)
'
+
test_expect_success 'submodule update exit immediately after recursive rebase error' '
(cd super &&
git checkout master &&
@@ -442,4 +443,110 @@ test_expect_success 'submodule update exit immediately after recursive rebase er
test_cmp expect actual
)
'
+
+test_expect_success 'add different submodules to the same path' '
+ (cd super &&
+ git submodule add ../submodule s1 &&
+ test_must_fail git submodule add ../merging s1
+ )
+'
+
+test_expect_success 'submodule add places git-dir in superprojects git-dir' '
+ (cd super &&
+ mkdir deeper &&
+ git submodule add ../submodule deeper/submodule &&
+ (cd deeper/submodule &&
+ git log > ../../expected
+ ) &&
+ (cd .git/modules/deeper/submodule &&
+ git log > ../../../../actual
+ ) &&
+ test_cmp actual expected
+ )
+'
+
+test_expect_success 'submodule update places git-dir in superprojects git-dir' '
+ (cd super &&
+ git commit -m "added submodule"
+ ) &&
+ git clone super super2 &&
+ (cd super2 &&
+ git submodule init deeper/submodule &&
+ git submodule update &&
+ (cd deeper/submodule &&
+ git log > ../../expected
+ ) &&
+ (cd .git/modules/deeper/submodule &&
+ git log > ../../../../actual
+ ) &&
+ test_cmp actual expected
+ )
+'
+
+test_expect_success 'submodule add places git-dir in superprojects git-dir recursive' '
+ (cd super2 &&
+ (cd deeper/submodule &&
+ git submodule add ../submodule subsubmodule &&
+ (cd subsubmodule &&
+ git log > ../../../expected
+ ) &&
+ git commit -m "added subsubmodule" &&
+ git push
+ ) &&
+ (cd .git/modules/deeper/submodule/modules/subsubmodule &&
+ git log > ../../../../../actual
+ ) &&
+ git add deeper/submodule &&
+ git commit -m "update submodule" &&
+ git push &&
+ test_cmp actual expected
+ )
+'
+
+test_expect_success 'submodule update places git-dir in superprojects git-dir recursive' '
+ mkdir super_update_r &&
+ (cd super_update_r &&
+ git init --bare
+ ) &&
+ mkdir subsuper_update_r &&
+ (cd subsuper_update_r &&
+ git init --bare
+ ) &&
+ mkdir subsubsuper_update_r &&
+ (cd subsubsuper_update_r &&
+ git init --bare
+ ) &&
+ git clone subsubsuper_update_r subsubsuper_update_r2 &&
+ (cd subsubsuper_update_r2 &&
+ test_commit "update_subsubsuper" file &&
+ git push origin master
+ ) &&
+ git clone subsuper_update_r subsuper_update_r2 &&
+ (cd subsuper_update_r2 &&
+ test_commit "update_subsuper" file &&
+ git submodule add ../subsubsuper_update_r subsubmodule &&
+ git commit -am "subsubmodule" &&
+ git push origin master
+ ) &&
+ git clone super_update_r super_update_r2 &&
+ (cd super_update_r2 &&
+ test_commit "update_super" file &&
+ git submodule add ../subsuper_update_r submodule &&
+ git commit -am "submodule" &&
+ git push origin master
+ ) &&
+ rm -rf super_update_r2 &&
+ git clone super_update_r super_update_r2 &&
+ (cd super_update_r2 &&
+ git submodule update --init --recursive &&
+ (cd submodule/subsubmodule &&
+ git log > ../../expected
+ ) &&
+ (cd .git/modules/submodule/modules/subsubmodule
+ git log > ../../../../../actual
+ )
+ test_cmp actual expected
+ )
+'
+
test_done
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 1a974e2..e410bd4 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -270,9 +270,9 @@ test_expect_success 'test "update --recursive" with a flag with spaces' '
git rev-parse --is-well-formed-git-dir nested1/.git &&
git rev-parse --is-well-formed-git-dir nested1/nested2/.git &&
git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git &&
- test -f nested1/.git/objects/info/alternates &&
- test -f nested1/nested2/.git/objects/info/alternates &&
- test -f nested1/nested2/nested3/.git/objects/info/alternates
+ test -f .git/modules/nested1/objects/info/alternates &&
+ test -f .git/modules/nested1/modules/nested2/objects/info/alternates &&
+ test -f .git/modules/nested1/modules/nested2/modules/nested3/objects/info/alternates
)
'
diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh
index cc16d3f..ab37c36 100755
--- a/t/t7408-submodule-reference.sh
+++ b/t/t7408-submodule-reference.sh
@@ -43,7 +43,7 @@ git commit -m B-super-added'
cd "$base_dir"
test_expect_success 'after add: existence of info/alternates' \
-'test `wc -l <super/sub/.git/objects/info/alternates` = 1'
+'test `wc -l <super/.git/modules/sub/objects/info/alternates` = 1'
cd "$base_dir"
@@ -66,7 +66,7 @@ test_expect_success 'update with reference' \
cd "$base_dir"
test_expect_success 'after update: existence of info/alternates' \
-'test `wc -l <super-clone/sub/.git/objects/info/alternates` = 1'
+'test `wc -l <super-clone/.git/modules/sub/objects/info/alternates` = 1'
cd "$base_dir"
--
1.7.6.398.g47bcd.dirty
^ permalink raw reply related
* [PATCH v2 1/2] rev-parse: add option --is-well-formed-git-dir [path]
From: Fredrik Gustafsson @ 2011-08-08 19:17 UTC (permalink / raw)
To: git; +Cc: iveqy, jens.lehmann, hvoigt, gitster
In-Reply-To: <1312831022-12868-1-git-send-email-iveqy@iveqy.com>
Check if [path] is a valid git-dir or a valid git-file that points
to a valid git-dir.
We want tests to be independent from the fact that a git-dir may
be a git-file. Thus we changed tests to use this feature.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
Documentation/git-rev-parse.txt | 4 ++
builtin/rev-parse.c | 8 +++
cache.h | 1 +
setup.c | 7 +++
t/t7400-submodule-basic.sh | 4 +-
t/t7403-submodule-sync.sh | 5 +-
t/t7407-submodule-foreach.sh | 97 ++++++++++++++++++++-------------------
7 files changed, 75 insertions(+), 51 deletions(-)
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 42c9676..3ce81c0 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -180,6 +180,10 @@ print a message to stderr and exit with nonzero status.
<args>...::
Flags and parameters to be parsed.
+--is-well-formed-git-dir [path]::
+ Check if [path] is a valid git-dir or a git-file pointing to a valid
+ git-dir. If [path] is a valid git-dir the resolved path to git-dir will
+ be printed.
include::revisions.txt[]
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 4c19f84..82342b3 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -455,6 +455,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
unsigned char sha1[20];
const char *name = NULL;
+ if (argc > 2 && !strcmp(argv[1], "--is-well-formed-git-dir")) {
+ const char *gitdir = resolve_gitdir(argv[2]);
+ if(!gitdir)
+ die("not a gitdir");
+ puts(gitdir);
+ return 0;
+ }
+
if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
diff --git a/cache.h b/cache.h
index 9e12d55..550f632 100644
--- a/cache.h
+++ b/cache.h
@@ -436,6 +436,7 @@ extern char *get_graft_file(void);
extern int set_git_dir(const char *path);
extern const char *get_git_work_tree(void);
extern const char *read_gitfile_gently(const char *path);
+extern const char *resolve_gitdir(const char *suspect);
extern void set_git_work_tree(const char *tree);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
diff --git a/setup.c b/setup.c
index 5ea5502..15bc305 100644
--- a/setup.c
+++ b/setup.c
@@ -808,3 +808,10 @@ const char *setup_git_directory(void)
{
return setup_git_directory_gently(NULL);
}
+
+const char *resolve_gitdir(const char *suspect)
+{
+ if(is_git_directory(suspect))
+ return suspect;
+ return read_gitfile_gently(suspect);
+}
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 14dc927..4df53e5 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -360,10 +360,10 @@ test_expect_success 'update --init' '
git submodule update init > update.out &&
cat update.out &&
test_i18ngrep "not initialized" update.out &&
- ! test -d init/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir init/.git &&
git submodule update --init init &&
- test -d init/.git
+ git rev-parse --is-well-formed-git-dir init/.git
'
test_expect_success 'do not add files from a submodule' '
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index 95ffe34..3620215 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -56,8 +56,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
git pull --no-recurse-submodules &&
git submodule sync
) &&
- test -d "$(git config -f super-clone/submodule/.git/config \
- remote.origin.url)" &&
+ test -d "$(cd super-clone/submodule &&
+ git config remote.origin.url
+ )" &&
(cd super-clone/submodule &&
git checkout master &&
git pull
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index be745fb..1a974e2 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -118,19 +118,19 @@ test_expect_success 'use "submodule foreach" to checkout 2nd level submodule' '
git clone super clone2 &&
(
cd clone2 &&
- test ! -d sub1/.git &&
- test ! -d sub2/.git &&
- test ! -d sub3/.git &&
- test ! -d nested1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub2/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub3/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir nested1/.git &&
git submodule update --init &&
- test -d sub1/.git &&
- test -d sub2/.git &&
- test -d sub3/.git &&
- test -d nested1/.git &&
- test ! -d nested1/nested2/.git &&
+ git rev-parse --is-well-formed-git-dir sub1/.git &&
+ git rev-parse --is-well-formed-git-dir sub2/.git &&
+ git rev-parse --is-well-formed-git-dir sub3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir nested1/nested2/.git &&
git submodule foreach "git submodule update --init" &&
- test -d nested1/nested2/.git &&
- test ! -d nested1/nested2/nested3/.git
+ git rev-parse --is-well-formed-git-dir nested1/nested1/nested2/.git
+ test_must_fail git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git
)
'
@@ -138,8 +138,8 @@ test_expect_success 'use "foreach --recursive" to checkout all submodules' '
(
cd clone2 &&
git submodule foreach --recursive "git submodule update --init" &&
- test -d nested1/nested2/nested3/.git &&
- test -d nested1/nested2/nested3/submodule/.git
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/submodule/.git
)
'
@@ -183,18 +183,18 @@ test_expect_success 'use "update --recursive" to checkout all submodules' '
git clone super clone3 &&
(
cd clone3 &&
- test ! -d sub1/.git &&
- test ! -d sub2/.git &&
- test ! -d sub3/.git &&
- test ! -d nested1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub2/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub3/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir nested1/.git &&
git submodule update --init --recursive &&
- test -d sub1/.git &&
- test -d sub2/.git &&
- test -d sub3/.git &&
- test -d nested1/.git &&
- test -d nested1/nested2/.git &&
- test -d nested1/nested2/nested3/.git &&
- test -d nested1/nested2/nested3/submodule/.git
+ git rev-parse --is-well-formed-git-dir sub1/.git &&
+ git rev-parse --is-well-formed-git-dir sub2/.git &&
+ git rev-parse --is-well-formed-git-dir sub3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/submodule/.git
)
'
@@ -247,14 +247,17 @@ test_expect_success 'ensure "status --cached --recursive" preserves the --cached
test_expect_success 'use "git clone --recursive" to checkout all submodules' '
git clone --recursive super clone4 &&
- test -d clone4/.git &&
- test -d clone4/sub1/.git &&
- test -d clone4/sub2/.git &&
- test -d clone4/sub3/.git &&
- test -d clone4/nested1/.git &&
- test -d clone4/nested1/nested2/.git &&
- test -d clone4/nested1/nested2/nested3/.git &&
- test -d clone4/nested1/nested2/nested3/submodule/.git
+ (
+ cd clone4 &&
+ git rev-parse --is-well-formed-git-dir .git &&
+ git rev-parse --is-well-formed-git-dir sub1/.git &&
+ git rev-parse --is-well-formed-git-dir sub2/.git &&
+ git rev-parse --is-well-formed-git-dir sub3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/submodule/.git
+ )
'
test_expect_success 'test "update --recursive" with a flag with spaces' '
@@ -262,11 +265,11 @@ test_expect_success 'test "update --recursive" with a flag with spaces' '
git clone super clone5 &&
(
cd clone5 &&
- test ! -d nested1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir d nested1/.git &&
git submodule update --init --recursive --reference="$(dirname "$PWD")/common objects" &&
- test -d nested1/.git &&
- test -d nested1/nested2/.git &&
- test -d nested1/nested2/nested3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git &&
test -f nested1/.git/objects/info/alternates &&
test -f nested1/nested2/.git/objects/info/alternates &&
test -f nested1/nested2/nested3/.git/objects/info/alternates
@@ -277,18 +280,18 @@ test_expect_success 'use "update --recursive nested1" to checkout all submodules
git clone super clone6 &&
(
cd clone6 &&
- test ! -d sub1/.git &&
- test ! -d sub2/.git &&
- test ! -d sub3/.git &&
- test ! -d nested1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub2/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub3/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir nested1/.git &&
git submodule update --init --recursive -- nested1 &&
- test ! -d sub1/.git &&
- test ! -d sub2/.git &&
- test ! -d sub3/.git &&
- test -d nested1/.git &&
- test -d nested1/nested2/.git &&
- test -d nested1/nested2/nested3/.git &&
- test -d nested1/nested2/nested3/submodule/.git
+ test_must_fail git rev-parse --is-well-formed-git-dir sub1/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub2/.git &&
+ test_must_fail git rev-parse --is-well-formed-git-dir sub3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/.git &&
+ git rev-parse --is-well-formed-git-dir nested1/nested2/nested3/submodule/.git
)
'
--
1.7.6.398.g47bcd.dirty
^ permalink raw reply related
* Re: [PATCH 22/48] merge-recursive: Fix sorting order and directory change assumptions
From: Elijah Newren @ 2011-08-08 19:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, jgfouca
In-Reply-To: <7vhb6jcg68.fsf@alter.siamese.dyndns.org>
On Mon, Jul 18, 2011 at 5:39 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> +static int string_list_df_name_compare(const void *a, const void *b)
>> +{
>> + const struct string_list_item *one = a;
>> + const struct string_list_item *two = b;
>> + /*
>> + * Here we only care that entries for D/F conflicts are
>> + * adjacent, in particular with the file of the D/F conflict
>> + * appearing before files below the corresponding directory.
>> + * The order of the rest of the list is irrelevant for us.
>> + *
>> + * To achieve this, we sort with df_name_compare and provide
>> + * the mode S_IFDIR so that D/F conflicts will sort correctly.
>> + * We use the mode S_IFDIR for everything else for simplicity,
>> + * since in other cases any changes in their order due to
>> + * sorting cause no problems for us.
>> + */
>
> I recall there was an issue of this sorting reported earlier...
Yes, in git-fast-export, though. It was 060df62 (fast-export: Fix
output order of D/F changes 2010-07-09), if you're curious.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox