Git development
 help / color / mirror / Atom feed
* Re: [PATCH] parse-options: fix parsing of "--foobar=" with no value
From: Pierre Habouzit @ 2008-07-22 18:54 UTC (permalink / raw)
  To: Olivier Marin; +Cc: Junio C Hamano, git
In-Reply-To: <1216752267-12138-1-git-send-email-dkr+ml.git@free.fr>

[-- Attachment #1: Type: text/plain, Size: 1031 bytes --]

On Tue, Jul 22, 2008 at 06:44:27PM +0000, Olivier Marin wrote:
> From: Olivier Marin <dkr@freesurf.fr>
> 
> Before this patch, running a git command with a "--foobar=" argument
> will set the "foobar" option with a random value and continue.
> We should instead, exit with an error if a value is required, or use
> the default one if the value is optional.

  Wrong, --foobar= is the option "foobar" with the argument "" (empty
string). as soon as you use the --foobar=... form, that is the "stuck
form" for long option, there *is* a value.

  IOW --foobar= is not the same as --foobar at all. If like you claim,
--foobar= pass a "random" value to the option then *this* is a bug, it
should pass a pointer to an empty string (IOW a pointer that points to a
NUL byte), but I see nothing in the code that would explain what you
claim.


-- 
·O·  Pierre Habouzit
··O                                                madcoder@debian.org
OOO                                                http://www.madism.org

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH] parse-options: fix parsing of "--foobar=" with no value
From: Sverre Rabbelier @ 2008-07-22 18:53 UTC (permalink / raw)
  To: Olivier Marin; +Cc: Pierre Habouzit, Junio C Hamano, git
In-Reply-To: <1216752267-12138-1-git-send-email-dkr+ml.git@free.fr>

On Tue, Jul 22, 2008 at 8:44 PM, Olivier Marin <dkr+ml.git@free.fr> wrote:
> We should instead, exit with an error if a value is required, or use
> the default one if the value is optional.

This makes no sense, when I run "git foo --bar=" I either mean "set
bar to empty" or I typo-ed. Why would I specify "--bar=" if I want the
default value?

-- 
Cheers,

Sverre Rabbelier

^ permalink raw reply

* [PATCH] parse-options: fix parsing of "--foobar=" with no value
From: Olivier Marin @ 2008-07-22 18:44 UTC (permalink / raw)
  To: Pierre Habouzit; +Cc: Junio C Hamano, git

From: Olivier Marin <dkr@freesurf.fr>

Before this patch, running a git command with a "--foobar=" argument
will set the "foobar" option with a random value and continue.
We should instead, exit with an error if a value is required, or use
the default one if the value is optional.

This patch fix the above issue and add some test cases.

Signed-off-by: Olivier Marin <dkr@freesurf.fr>
---
 parse-options.c          |    8 ++++----
 t/t0040-parse-options.sh |   25 +++++++++++++++++++++++++
 test-parse-options.c     |    3 +++
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/parse-options.c b/parse-options.c
index 71a7acf..67be197 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -17,7 +17,7 @@ static int opterror(const struct option *opt, const char *reason, int flags)
 static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
 		   int flags, const char **arg)
 {
-	if (p->opt) {
+	if (p->opt && *p->opt) {
 		*arg = p->opt;
 		p->opt = NULL;
 	} else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
@@ -80,7 +80,7 @@ static int get_value(struct parse_opt_ctx_t *p,
 	case OPTION_STRING:
 		if (unset)
 			*(const char **)opt->value = NULL;
-		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
+		else if (opt->flags & PARSE_OPT_OPTARG && (!p->opt || !*p->opt))
 			*(const char **)opt->value = (const char *)opt->defval;
 		else
 			return get_arg(p, opt, flags, (const char **)opt->value);
@@ -91,7 +91,7 @@ static int get_value(struct parse_opt_ctx_t *p,
 			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
 		if (opt->flags & PARSE_OPT_NOARG)
 			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
-		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
+		if (opt->flags & PARSE_OPT_OPTARG && (!p->opt || !*p->opt))
 			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
 		if (get_arg(p, opt, flags, &arg))
 			return -1;
@@ -102,7 +102,7 @@ static int get_value(struct parse_opt_ctx_t *p,
 			*(int *)opt->value = 0;
 			return 0;
 		}
-		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+		if (opt->flags & PARSE_OPT_OPTARG && (!p->opt || !*p->opt)) {
 			*(int *)opt->value = opt->defval;
 			return 0;
 		}
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 03dbe00..7ce2e86 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -26,6 +26,8 @@ String options
     --st <st>             get another string (pervert ordering)
     -o <str>              get another string
     --default-string      set string to default
+    --optional-string[=<string>]
+                          set string to optional if none given
 
 Magic arguments
     --quux                means --quux
@@ -85,6 +87,29 @@ test_expect_success 'missing required value' '
 	test $? = 129
 '
 
+test_expect_success 'missing required value with "--foobar="' '
+	test-parse-options --length=;
+	test $? = 129 &&
+	test-parse-options --len=;
+	test $? = 129
+'
+
+cat > expect << EOF
+boolean: 0
+integer: 0
+string: optional
+abbrev: 7
+verbose: 0
+quiet: no
+dry run: no
+EOF
+
+test_expect_success 'optional value with "--foobar="' '
+	test-parse-options --optional-string= > output 2> output.err &&
+	test ! -s output.err &&
+	test_cmp expect output
+'
+
 cat > expect << EOF
 boolean: 1
 integer: 13
diff --git a/test-parse-options.c b/test-parse-options.c
index 2a79e72..76db37e 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -42,6 +42,9 @@ int main(int argc, const char **argv)
 		OPT_STRING('o', NULL, &string, "str", "get another string"),
 		OPT_SET_PTR(0, "default-string", &string,
 			"set string to default", (unsigned long)"default"),
+		{ OPTION_STRING, 0, "optional-string", &string,
+			"string", "set string to optional if none given",
+			PARSE_OPT_OPTARG, NULL, (unsigned long)"optional" },
 		OPT_GROUP("Magic arguments"),
 		OPT_ARGUMENT("quux", "means --quux"),
 		OPT_GROUP("Standard options"),
-- 
1.6.0.rc0.16.gb169.dirty

^ permalink raw reply related

* Re: Computing the number of patches in linux-next tree
From: Harvey Harrison @ 2008-07-22 18:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, Tony Luck, Git Mailing List
In-Reply-To: <7vabg9n93f.fsf@gitster.siamese.dyndns.org>

On Tue, 2008-07-22 at 10:04 -0700, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Tue, 22 Jul 2008, Tony Luck wrote:
> >
> >> git tag | grep next- | sort | while read tag
> >
> > This should not be necessary... AFAICT "git tag" sorts its output already.
> >
> >> What does the "git-where-did-this-tag-branch-from-linus" command look like?
> >
> > git merge-base --all <branch1> <branch2>
> >
> > Be warned: there might be multiple merge bases.
> 
> I do not think that approach applies to linux-next, which is constantly
> rewound to the then-tip-of-linus and merge remaining bits.  The question
> is "where does this branch begin", which does not have an answer in git.

I thought that was what Stephen has the next/stable branch for:

git log --pretty=oneline --no-merges next/stable..next/master | wc -l

At least for each day you can find the number of patches....I don't
think he tags the stable points, so historically that may be a problem.

Harvey

^ permalink raw reply

* Re: [PATCH 1/2] Introduce leaky().
From: Jan Hudec @ 2008-07-22 18:09 UTC (permalink / raw)
  To: Pierre Habouzit, Junio C Hamano, git
In-Reply-To: <20080626213304.GA22111@artemis.madism.org>

On Thu, Jun 26, 2008 at 23:33:04 +0200, Pierre Habouzit wrote:
> On Thu, Jun 26, 2008 at 06:46:43PM +0000, Junio C Hamano wrote:
> > The user would also need to worry about not freeing the original
> > allocation pointer when something is realloc(3)ed, which means either
> > finding the last realloc(3) of the object (that is logically the same, but
> > just being extended) and mark the pointer as leaky() after that realloc,
> > or unregister the original pointer from leaks before calling realloc and
> > register what comes back.  It will easily get messy.
> 
>   Hmm indeed, maybe it isn't such a good idea then.

I don't think it's necessary either. Valgrind (unlike other leak detectors
the poor windows folks are stuck with) is quite smart and will only report
memory as leaked when there is no pointer to it. So it should not report any
memory pointed to by index or any other static structure.

Additionally since valgrind allows one to write rules to exclude
uninteresting reports. So a good approach would be to just keep such
exclusion file around in git with the known uninteresting cases.

> > By the way, the series queued in your repository still has "s/pring/print/"
> > typo in 4/7 and "argv not NULL terminated" comment in 6/7.
> 
>   I'll fix that and pushed again, without the leaky() series dependency
> (I've put in a comment that I'm aware that it's a leak), and with the
> two fixes you mention done.
> 
> -- 
> ·O·  Pierre Habouzit
> ··O                                                madcoder@debian.org
> OOO                                                http://www.madism.org


-- 
						 Jan 'Bulb' Hudec <bulb@ucw.cz>

^ permalink raw reply

* Re: [PATCH] Fix update-index --refresh for submodules if stat(2) returns st_size 0
From: Junio C Hamano @ 2008-07-22 17:28 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Alex Riesen, git
In-Reply-To: <4885897C.8010401@viscovery.net>

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

>> +	if ((changed & DATA_CHANGED) && (ce->ce_size != 0 || S_ISGITLINK(ce->ce_mode)))
>
> Does this mean that ce->ce_size is non-zero for gitlinks, at least on
> Unix? Is this value useful in anyway? I don't think so. Then it shouldn't
> be a random value that lstat() happens to return.

These ce_xxx fields are the values we read from lstat(2) when the user
told us to stage that working tree entity, be it a regular file, a
symlink, or a directory that is a submodule.  The only thing required for
them is that they are stable (i.e. if you haven't touched the working tree
entity, the value stays the same), and changes across modification.  The
value itself does not have to "mean" anything.

When trying to see if the user has changes in the working tree entity
since the last such staging of the path, we compare that value with what
comes back from lstat(2), before actually comparing the contents.  If the
filesize changed, they cannot be the same and the code says you have
modified it without having to look at the contents.

	Side note.  This is why you need to be careful after modifying
	autocrlf related configuration and attributes.  If you had CRLF
	contents in the working tree that was incorrectly staged as-is,
	then switch autocrlf-on, and "git add" to fix the staged copy to
	be LF-terminated, we say "it's unchanged and we do not bother
	rehashing" by comparing the ce_xxx fields without looking at the
	contents (this is an absolutely necessary optimization to make
	"git add ."  usable), because ce_size records the size of CRLF
	version you have in the working tree, and you haven't changed the
	working tree file in this sequence above.

        Removing the file and checking things out would be the most
	straightforward solution in such a case.

We used to include ce_dev (taken from struct stat.st_dev) in the list of
fields to cache and compare to detect changes, but that is now excluded
because it is not stable (see comments in read-cache.c).  If the directory
size is unstable, perhaps it would be better to force it to some fixed
magic value so that it is not used by this "quick change detection" check.

If you network-mount the same directory from POSIX and windows, the former
may give "storage size of the directory" while the latter may give 0.
This would mean that you would need a "update-index --refresh" when you
switch between such machines.

^ permalink raw reply

* Re: Computing the number of patches in linux-next tree
From: Johannes Schindelin @ 2008-07-22 17:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Tony Luck, Git Mailing List
In-Reply-To: <7vabg9n93f.fsf@gitster.siamese.dyndns.org>

Hi,

On Tue, 22 Jul 2008, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Tue, 22 Jul 2008, Tony Luck wrote:
> >
> >> git tag | grep next- | sort | while read tag
> >
> > This should not be necessary... AFAICT "git tag" sorts its output already.
> >
> >> What does the "git-where-did-this-tag-branch-from-linus" command look like?
> >
> > git merge-base --all <branch1> <branch2>
> >
> > Be warned: there might be multiple merge bases.
> 
> I do not think that approach applies to linux-next, which is constantly
> rewound to the then-tip-of-linus and merge remaining bits.  The question
> is "where does this branch begin", which does not have an answer in git.

Oh.

Well, there is one thing that _could_ work most of the time, namely 
looking at the committer info of the first parent.

Dunno,
Dscho

^ permalink raw reply

* RE: Computing the number of patches in linux-next tree
From: Luck, Tony @ 2008-07-22 17:13 UTC (permalink / raw)
  To: Junio C Hamano, Johannes Schindelin; +Cc: Git Mailing List
In-Reply-To: <7vabg9n93f.fsf@gitster.siamese.dyndns.org>

>> git merge-base --all <branch1> <branch2>
>>
>> Be warned: there might be multiple merge bases.
>
> I do not think that approach applies to linux-next, which is constantly
> rewound to the then-tip-of-linus and merge remaining bits.  The question
> is "where does this branch begin", which does not have an answer in git.

Using git merge-base on the next-20080701 tag and current Linus tree I get
76 possible merge bases.  None of them appear to be the "right" one (if
I check out this tag and look at Next/merge.log the right answer appears
to be 1702b52 if I'm reading the log correctly).

Perhaps my best hope is to
        $ git checkout $tag Next/merge.log
        ... parse merge.log to figure out $base ...

-Tony

^ permalink raw reply

* Re: [PATCH] bring description of git diff --cc up to date
From: Junio C Hamano @ 2008-07-22 17:09 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, David Greaves
In-Reply-To: <20080722111947.BIW29914@m4500-01.uchicago.edu>

Jonathan Nieder <jrnieder@uchicago.edu> writes:

> Just to make sure I understand, here is what I think --cc does:
>
>   - In a two-parent merge, it is exactly as Linus has been
>     ...
>   - In a many-parent merge, the criterion is more stringent.
>     ...
>
> Is that correct?

The logic in the code does not have separate criteria for two-parent and
Octopus cases.  Actually Linus talks about "when you have two versions to
choose from, and if the result matches one of them, then it is not
interesting".  In a two-parent merge, you cannot have three or more
possible versions to choose from by definition, can you?

^ permalink raw reply

* [PATCH] t7601: extend the 'merge picks up the best result' test
From: Miklos Vajna @ 2008-07-22 17:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7ibenx75.fsf@gitster.siamese.dyndns.org>

The test only checked if the best result picking code works if there are
multiple strategies set in the config. Add a similar one that tests if
the same true if the -s option of git merge was used multiple times.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---

On Tue, Jul 22, 2008 at 01:24:14AM -0700, Junio C Hamano <gitster@pobox.com> wrote:
> Don't.  pull.* has always been defined as "list of strategies", and -s
> has
> always been defined to take "a" strategy.

OK. Here is a testcase for the later. As far as I see the behaviour of
multiple -s was not checked till now.

 t/t7601-merge-pull-config.sh |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index 6b9f638..55aa6b5 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -112,6 +112,21 @@ test_expect_success 'setup conflicted merge' '
 # recusive is choosen.
 
 test_expect_success 'merge picks up the best result' '
+	git config --unset-all pull.twohead &&
+	git reset --hard c5 &&
+	git merge -s resolve c6
+	resolve_count=$(conflict_count) &&
+	git reset --hard c5 &&
+	git merge -s recursive c6
+	recursive_count=$(conflict_count) &&
+	git reset --hard c5 &&
+	git merge -s recursive -s resolve c6
+	auto_count=$(conflict_count) &&
+	test $auto_count = $recursive_count &&
+	test $auto_count != $resolve_count
+'
+
+test_expect_success 'merge picks up the best result (from config)' '
 	git config pull.twohead "recursive resolve" &&
 	git reset --hard c5 &&
 	git merge -s resolve c6
-- 
1.5.6.4.433.g09651.dirty

^ permalink raw reply related

* Re: Computing the number of patches in linux-next tree
From: Junio C Hamano @ 2008-07-22 17:04 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Tony Luck, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0807221727210.8986@racer>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Tue, 22 Jul 2008, Tony Luck wrote:
>
>> git tag | grep next- | sort | while read tag
>
> This should not be necessary... AFAICT "git tag" sorts its output already.
>
>> What does the "git-where-did-this-tag-branch-from-linus" command look like?
>
> git merge-base --all <branch1> <branch2>
>
> Be warned: there might be multiple merge bases.

I do not think that approach applies to linux-next, which is constantly
rewound to the then-tip-of-linus and merge remaining bits.  The question
is "where does this branch begin", which does not have an answer in git.

^ permalink raw reply

* Re: [PATCH] Fix update-index --refresh for submodules if stat(2) returns st_size 0
From: Johannes Sixt @ 2008-07-22 16:59 UTC (permalink / raw)
  To: Alex Riesen; +Cc: Junio C Hamano, git
In-Reply-To: <20080722164604.GA3766@blimp.local>

Alex Riesen schrieb:
> Johannes Sixt, Tue, Jul 22, 2008 09:17:16 +0200:
>> Alex Riesen schrieb:
>>> +	if ((changed & DATA_CHANGED) && (ce->ce_size != 0 || S_ISGITLINK(ce->ce_mode)))
>> Does this mean that ce->ce_size is non-zero for gitlinks, at least on
>> Unix?
> 
> It is non-zero for directories (which is what gitlinks are in working
> directories) on UNIX operating systems I met.
> 
>> Is this value useful in anyway?
> 
> Sometimes it is (the size a directory takes on storage)

Sure; but is ce->ce_size of gitlinks useful?

-- Hannes

^ permalink raw reply

* Re: problem using jgit
From: Shawn O. Pearce @ 2008-07-22 16:58 UTC (permalink / raw)
  To: Marek Zawirski; +Cc: Stephen Bannasch, git, Robin Rosenberg
In-Reply-To: <488482A2.4000601@gmail.com>

Marek Zawirski <marek.zawirski@gmail.com> wrote:
> Marek Zawirski wrote:
>> Stephen Bannasch wrote:
>>> I've setup a simple test class that integrates jgit to clone a git  
>>> repository. However I'm getting a NullPointerError when  
>>> RevWalk.parseAny ends up producing a null object id.
...
> It's caused by 14a630c3: Cached modification times for symbolic refs too
> Changes introduced by this patch made Repository#getAllRefs() including  
> Ref objects with null ObjectId in case of unresolvable (invalid?) HEAD  
> symbolic ref, and null Ref for HEAD  when it doesn't exist. Previous  
> behavior was just not including such refs in result.

My intention here was that if a ref cannot be resolved, it should
not be reported.  So Ref.getObjectId should never return null, and
it should also never return an ObjectId for which the object does
not exist in the Repository's object database(s).  (Though that can
happen in the face of repository corruption, but lets not go there
just yet).

So IMHO the RefDatabase code is _wrong_ for returning HEAD with a
null objectId.

Now this case can happen if HEAD points at a stillborn branch.  This
is easily reproduced in any repository, e.g. just do:

	git symbolic-ref HEAD refs/heads/`date`

You'll wind up on a branch which doesn't exist.  In this case HEAD
shouldn't be reported back from RefDatabase, it doesn't exist, as
branch `date` does not exist either.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] Fix update-index --refresh for submodules if stat(2) returns st_size 0
From: Alex Riesen @ 2008-07-22 16:46 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Junio C Hamano, git
In-Reply-To: <4885897C.8010401@viscovery.net>

Johannes Sixt, Tue, Jul 22, 2008 09:17:16 +0200:
> Alex Riesen schrieb:
> > Can MSys folks please try it? I noticed it when the test
> > t2103-update-index-ignore-missing.sh (the 5th case) started failing.
> 
> I tested it. mingw.git does suffer from the problem, and this fixes it.
> 

Yes, I did too (at work).

> > +	if ((changed & DATA_CHANGED) && (ce->ce_size != 0 || S_ISGITLINK(ce->ce_mode)))
> 
> Does this mean that ce->ce_size is non-zero for gitlinks, at least on
> Unix?

It is non-zero for directories (which is what gitlinks are in working
directories) on UNIX operating systems I met.

> Is this value useful in anyway?

Sometimes it is (the size a directory takes on storage)

> I don't think so. Then it shouldn't be a random value that lstat()
> happens to return.

The problem is: it is not random. I even suspect that Windows is the
ONLY system which has st_size 0 for directories.

^ permalink raw reply

* Re: [PATCH] Fix update-index --refresh for submodules if stat(2) returns st_size 0
From: Alex Riesen @ 2008-07-22 16:49 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7vbq0qnxyi.fsf@gitster.siamese.dyndns.org>

Junio C Hamano, Tue, Jul 22, 2008 10:07:49 +0200:
> I however have to wonder if you also need to touch the end of
> ce_match_stat_basic() that checks for zero sized cache entry.

I frankly don't know.

^ permalink raw reply

* [PATCH] In perforce, RCS keywords are case-sensitive
From: Daniel Barkalow @ 2008-07-22 16:48 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

At least, this is true in 2007.2, according to the documentation.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---

A line of perl with the variable $file in a string followed by a different 
variable not in the string, for example, doesn't get mangled by p4 and may 
therefore appear in a p4 depot.

I don't know if the "old-style keyword expansion" is case-sensitive, 
though, so I'm leaving that alone.

 contrib/fast-import/git-p4 |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index d8de9f6..1ee612e 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -902,7 +902,7 @@ class P4Sync(Command):
             if stat['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
                 text = re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', text)
             elif stat['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
-                text = re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', text)
+                text = re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', text)
 
             contents[stat['depotFile']] = text
 
-- 
1.5.6.rc2.26.g8c37.dirty

^ permalink raw reply related

* Re: post-receive-hook emailer
From: Vincent Kergonna @ 2008-07-22 16:45 UTC (permalink / raw)
  To: Ask Bjørn Hansen; +Cc: git
In-Reply-To: <00AEED4D-BD34-4584-B303-32C5F587EF0F@develooper.com>

> Hi everyone,
>

Hi,

> Anyway - anyone have a mailer that sends diffs and such?  :-)   Or
> should I just write a wrapper around format-patch and send-email?
> (To handle branches well it gets slightly complicated, quick - or
> maybe I just haven't understood how the post-receive hook works).

Below is a script I use to send diffs for each commit pushed to a
repository. This script should be called from the 'update' hook.

-- 
Vincent


#!/usr/bin/perl
#
# Tool to send git commit notifications
#
# Copyright 2005 Alexandre Julliard
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
#
# This script is meant to be called from .git/hooks/update.
#
# Usage: git-notify [options] [--] refname old-sha1 new-sha1
#
#   -c name   Send CIA notifications under specified project name
#   -m addr   Send mail notifications to specified address
#   -n max    Set max number of individual mails to send
#   -r name   Set the git repository name
#   -s bytes  Set the maximum diff size in bytes (-1 for no limit)
#   -u url    Set the URL to the gitweb browser
#   -x branch Exclude changes to the specified branch from reports
#

use strict;
use open ':utf8';
use Encode 'encode';
use Cwd 'realpath';

binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';

# some parameters you may want to change

# base URL of the gitweb repository browser (can be set with the -u option)
my $gitweb_url = "";

# set this to something that takes "-s"
my $mailer = "/usr/bin/mail";

# default repository name (can be changed with the -r option)
my $repos_name = "";

# Repository owner
my $repos_owner = "";

# max size of diffs in bytes (can be changed with the -s option)
my $max_diff_size = 2500000;

# address for mail notices (can be set with -m option)
my $commitlist_address;

# project name for CIA notices (can be set with -c option)
my $cia_project_name;

# CIA notification address
my $cia_address = "cia\@cia.navi.cx";

# max number of individual notices before falling back to a single global
notice (can be set with -n option)
my $max_individual_notices = 100;

# debug mode
my $debug = 0;

# branches to exclude
my @exclude_list = ();

sub usage()
{
    print "Usage: $0 [options] [--] refname old-sha1 new-sha1\n";
    print "   -c name   Send CIA notifications under specified project
name\n";
    print "   -m addr   Send mail notifications to specified address\n";
    print "   -n max    Set max number of individual mails to send\n";
    print "   -r name   Set the git repository name\n";
    print "   -s bytes  Set the maximum diff size in bytes (-1 for no
limit)\n";
    print "   -u url    Set the URL to the gitweb browser\n";
    print "   -x branch Exclude changes to the specified branch from
reports\n";
	  print "   -o owner  Set repository owner (used as a filter on commits)\n";
    exit 1;
}

sub xml_escape($)
{
    my $str = shift;
    $str =~ s/&/&amp;/g;
    $str =~ s/</&lt;/g;
    $str =~ s/>/&gt;/g;
    my @chars = unpack "U*", $str;
    $str = join "", map { ($_ > 127) ? sprintf "&#%u;", $_ : chr($_); }
@chars;
    return $str;
}

# format an integer date + timezone as string
# algorithm taken from git's date.c
sub format_date($$)
{
    my ($time,$tz) = @_;

    if ($tz < 0)
    {
        my $minutes = (-$tz / 100) * 60 + (-$tz % 100);
        $time -= $minutes * 60;
    }
    else
    {
        my $minutes = ($tz / 100) * 60 + ($tz % 100);
        $time += $minutes * 60;
    }
    return gmtime($time) . sprintf " %+05d", $tz;
}

# parse command line options
sub parse_options()
{
    while (@ARGV && $ARGV[0] =~ /^-/)
    {
        my $arg = shift @ARGV;

        if ($arg eq '--') { last; }
        elsif ($arg eq '-c') { $cia_project_name = shift @ARGV; }
        elsif ($arg eq '-m') { $commitlist_address = shift @ARGV; }
        elsif ($arg eq '-n') { $max_individual_notices = shift @ARGV; }
        elsif ($arg eq '-r') { $repos_name = shift @ARGV; }
        elsif ($arg eq '-s') { $max_diff_size = shift @ARGV; }
        elsif ($arg eq '-u') { $gitweb_url = shift @ARGV; }
        elsif ($arg eq '-x') { push @exclude_list, "^" . shift @ARGV; }
		    elsif ($arg eq '-o') { $repos_owner = shift @ARGV; }
        elsif ($arg eq '-d') { $debug++; }
        else { usage(); }
    }
    if (@ARGV && $#ARGV != 2) { usage(); }
}

# send an email notification
sub mail_notification($$$@)
{
    my ($name, $subject, $content_type, @text) = @_;
    $subject = encode("MIME-Q",$subject);
    if ($debug)
    {
        print "---------------------\n";
        print "To: $name\n";
        print "Subject: $subject\n";
        print "Content-Type: $content_type\n";
        print "\n", join("\n", @text), "\n";
    }
    else
    {
        my $pid = open MAIL, "|-";
        return unless defined $pid;
        if (!$pid)
        {
            exec $mailer, "-s", $subject, "-a", "Content-Type:
$content_type", $name or die "Cannot exec $mailer";
        }
        print MAIL join("\n", @text), "\n";
        close MAIL;
    }
}

# get the default repository name
sub get_repos_name()
{
    my $dir = `git rev-parse --git-dir`;
    chomp $dir;
    my $repos = realpath($dir);
    $repos =~ s/(.*?)((\.git\/)?\.git)$/\1/;
    $repos =~ s/(.*)\/([^\/]+)\/?$/\2/;
    return $repos;
}

# extract the information from a commit or tag object and return a hash
containing the various fields
sub get_object_info($)
{
    my $obj = shift;
    my %info = ();
    my @log = ();
    my $do_log = 0;

    open TYPE, "-|" or exec "git", "cat-file", "-t", $obj or die "cannot
run git-cat-file";
    my $type = <TYPE>;
    chomp $type;
    close TYPE;

    open OBJ, "-|" or exec "git", "cat-file", $type, $obj or die "cannot
run git-cat-file";
    while (<OBJ>)
    {
        chomp;
        if ($do_log)
        {
            last if /^-----BEGIN PGP SIGNATURE-----/;
            push @log, $_;
        }
        elsif (/^(author|committer|tagger) ((.*)(<.*>)) (\d+) ([+-]\d+)$/)
        {
            $info{$1} = $2;
            $info{$1 . "_name"} = $3;
            $info{$1 . "_email"} = $4;
            $info{$1 . "_date"} = $5;
            $info{$1 . "_tz"} = $6;
        }
        elsif (/^tag (.*)$/)
        {
            $info{"tag"} = $1;
        }
        elsif (/^$/) { $do_log = 1; }
    }
    close OBJ;

    $info{"type"} = $type;
    $info{"log"} = \@log;
    return %info;
}

# send a commit notice to a mailing list
sub send_commit_notice($$)
{
    my ($ref,$obj) = @_;
    my %info = get_object_info($obj);
    my @notice = ();
    my $subject;

	return if $info{"log"} eq "^(m|M)erge.*";

	if ($info{"author"} =~ "$repos_owner") {

		if ($info{"type"} eq "tag")
		{
			push @notice,
			"Module: $repos_name",
			"Branch: $ref",
			"Tag:    $obj",
			#"URL:    $gitweb_url/?a=tag;h=$obj",
			"",
			"Tagger: " . $info{"tagger"},
			"Date:   " . format_date($info{"tagger_date"},$info{"tagger_tz"}),
			"",
			join "\n", @{$info{"log"}};
			$subject = "[CommitDiff] Tag " . $info{"tag"} . " : " .
$info{"tagger_name"} . ": " . ${$info{"log"}}[0];
		}
		else
		{
			push @notice,
			"Module: $repos_name",
			"Branch: $ref",
			"Commit: $obj",
			"Parent: $info()",
			"URL:    $gitweb_url/?a=commit;h=$obj",
			"Author: " . $info{"author"},
			"AuthorDate:   " . format_date($info{"author_date"},$info{"author_tz"}),
			"",
			join "\n", @{$info{"log"}},
			"",
			"---",
			"";

			open STAT, "-|" or exec "git", "diff-tree", "--stat", "-M",
"--no-commit-id", $obj or die "cannot exec git-diff-tree";
			push @notice, join("", <STAT>);
			close STAT;

			open DIFF, "-|" or exec "git", "diff-tree", "-p", "-M",
"--no-commit-id", $obj or die "cannot exec git-diff-tree";
			my $diff = join( "", <DIFF> );
			close DIFF;

			if (($max_diff_size == -1) || (length($diff) < $max_diff_size))
			{
				push @notice, $diff;
			}
			else
			{
				push @notice, "Diff:   $gitweb_url/?a=commitdiff;h=$obj",
			}

			$subject = "[CommitDiff] " . ${$info{"log"}}[0];
		}

		mail_notification($commitlist_address, $subject, "text/plain;
charset=UTF-8", @notice);
	}
}

# send a commit notice to the CIA server
sub send_cia_notice($$)
{
    my ($ref,$commit) = @_;
    my %info = get_object_info($commit);
    my @cia_text = ();

    return if $info{"type"} ne "commit";

    push @cia_text,
        "<message>",
        "  <generator>",
        "    <name>git-notify script for CIA</name>",
        "  </generator>",
        "  <source>",
        "    <project>" . xml_escape($cia_project_name) . "</project>",
        "    <module>" . xml_escape($repos_name) . "</module>",
        "    <branch>" . xml_escape($ref). "</branch>",
        "  </source>",
        "  <body>",
        "    <commit>",
        "      <revision>" . substr($commit,0,10) . "</revision>",
        "      <author>" . xml_escape($info{"author"}) . "</author>",
        "      <log>" . xml_escape(join "\n", @{$info{"log"}}) . "</log>",
        "      <files>";

    open COMMIT, "-|" or exec "git", "diff-tree", "--name-status", "-r",
"-M", $commit or die "cannot run git-diff-tree";
    while (<COMMIT>)
    {
        chomp;
        if (/^([AMD])\t(.*)$/)
        {
            my ($action, $file) = ($1, $2);
            my %actions = ( "A" => "add", "M" => "modify", "D" => "remove" );
            next unless defined $actions{$action};
            push @cia_text, "        <file action=\"$actions{$action}\">"
. xml_escape($file) . "</file>";
        }
        elsif (/^R\d+\t(.*)\t(.*)$/)
        {
            my ($old, $new) = ($1, $2);
            push @cia_text, "        <file action=\"rename\" to=\"" .
xml_escape($new) . "\">" . xml_escape($old) . "</file>";
        }
    }
    close COMMIT;

    push @cia_text,
        "      </files>",
        "      <url>" . xml_escape("$gitweb_url/?a=commit;h=$commit") .
"</url>",
        "    </commit>",
        "  </body>",
        "  <timestamp>" . $info{"author_date"} . "</timestamp>",
        "</message>";

    mail_notification($cia_address, "DeliverXML", "text/xml", @cia_text);
}

# send a global commit notice when there are too many commits for
individual mails
sub send_global_notice($$$)
{
    my ($ref, $old_sha1, $new_sha1) = @_;
    my @notice = ();

    open LIST, "-|" or exec "git", "rev-list", "--pretty", "^$old_sha1",
"$new_sha1", @exclude_list or die "cannot exec git-rev-list";
    while (<LIST>)
    {
        chomp;
        s/^commit /URL:    $gitweb_url\/?a=commit;h=/;
        push @notice, $_;
    }
    close LIST;

    mail_notification($commitlist_address, "New commits on branch $ref",
"text/plain; charset=UTF-8", @notice);
}

# send all the notices
sub send_all_notices($$$)
{
    my ($ref, $old_sha1, $new_sha1) = @_;

    $ref =~ s/^refs\/heads\///;

    if ($old_sha1 eq '0' x 40)  # new ref
    {
        send_commit_notice( $ref, $new_sha1 ) if $commitlist_address;
        return;
    }

    my @commits = ();

    open LIST, "-|" or exec "git", "rev-list", "^$old_sha1", "$new_sha1",
@exclude_list or die "cannot exec git-rev-list";
    while (<LIST>)
    {
        chomp;
        die "invalid commit $_" unless /^[0-9a-f]{40}$/;
        unshift @commits, $_;
    }
    close LIST;

    if (@commits > $max_individual_notices)
    {
        send_global_notice( $ref, $old_sha1, $new_sha1 ) if
$commitlist_address;
        return;
    }

    foreach my $commit (@commits)
    {
        send_commit_notice( $ref, $commit ) if $commitlist_address;
        send_cia_notice( $ref, $commit ) if $cia_project_name;
    }
}

$repos_name = get_repos_name();
parse_options();

# append repository path to URL
$gitweb_url .= "/$repos_name.git";

if (@ARGV)
{
    send_all_notices( $ARGV[0], $ARGV[1], $ARGV[2] );
}
else  # read them from stdin
{
    while (<>)
    {
        chomp;
        if (/^([0-9a-f]{40}) ([0-9a-f]{40}) (.*)$/) { send_all_notices(
$3, $1, $2 ); }
    }
}

exit 0;

^ permalink raw reply

* Re: Computing the number of patches in linux-next tree
From: Johannes Schindelin @ 2008-07-22 16:28 UTC (permalink / raw)
  To: Tony Luck; +Cc: Git Mailing List
In-Reply-To: <12c511ca0807220919q4db6ee1fr33dc70fe35c58efe@mail.gmail.com>

Hi,

On Tue, 22 Jul 2008, Tony Luck wrote:

> git tag | grep next- | sort | while read tag

This should not be necessary... AFAICT "git tag" sorts its output already.

> What does the "git-where-did-this-tag-branch-from-linus" command look like?

git merge-base --all <branch1> <branch2>

Be warned: there might be multiple merge bases.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] bring description of git diff --cc up to date
From: Jonathan Nieder @ 2008-07-22 16:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, David Greaves

Junio C Hamano wrote:

> Jonathan Nieder <jrnieder@uchicago.edu> writes:
>
>> +	This flag implies the '-c' option and makes the patch output
>> +	even more compact by omitting uninteresting hunks.  A hunk is
>> +	considered interesting only if either (a) it shows changes from
>> +	all parents or (b) in an Octopus merge, it shows different changes
>> +	from at least three different parents.
>
> I am not sure where that "at lesta three different parents" comes from.
> It might be that what the logic does can be expressed that way, but that
> was not the guiding principle why the code does what it currently does.

Yes, exactly - this is what I meant in saying "my proposed text
does not suggest very strongly what --cc is intended to do".  I
haven't found any wording yet that both makes it clear what --cc
actually does and follows a thought process suggesting why.

Just to make sure I understand, here is what I think --cc does:

  - In a two-parent merge, it is exactly as Linus has been
    describing it.  A hunk is interesting if and only if
    it shows changes from both parents.

  - In a many-parent merge, the criterion is more stringent.
    As in the two-parent merge case, the hunk must show no
    changes from at least one of the parents, meaning that
    one of several alternatives for that portion of code
    was chosen by the code integrator (without mixing and
    matching or adding additional changes); but further, there
    must have been only two alternatives for that portion of
    code to choose between.  If there were three distinct
    alternatives, no matter what the code integrator does, the
    hunk will show up (because that is so rare and deserves
    attention).

Is that correct?

Thanks for the reading matter.  If it stimulates anyone reading
into coming up with a better description, they should please let
me know :)

^ permalink raw reply

* Computing the number of patches in linux-next tree
From: Tony Luck @ 2008-07-22 16:19 UTC (permalink / raw)
  To: Git Mailing List

I tried to produce a graph of the pending avalanche of patches
sitting in the linux-next tree and came up with this:

git tag | grep next- | sort | while read tag
do
        c=$(git-rev-list --no-merges $tag ^linus | wc -l)

        echo ${tag##next-} $c
done

Where "linus" is a branch that tracks Linus' tree.  But this gets the
wrong count
for old tags because maintainers who use the topic-branch method have
exactly the same commits in linux-next as eventually end up in Linus ... so
once Linus pulls these trees, the historical counts change.

What I really need at this point is the commit from Linus tree that Stephen
uses as the basis for each next-* tag.  I.e. change the loop body to

       base=`git-where-did-this-tag-branch-from-linus $tag`
       c=$(git-rev-list --no-merges $tag ^$base | wc -l)

Is this the right way to do this?
What does the "git-where-did-this-tag-branch-from-linus" command look like?

-Tony

^ permalink raw reply

* Re: Git Documentation
From: Johannes Schindelin @ 2008-07-22 16:07 UTC (permalink / raw)
  To: Jay Soffian; +Cc: Johan Herland, david, Scott Chacon, git
In-Reply-To: <76718490807220847i298f256bm4c3f85bfde079ee2@mail.gmail.com>

Hi,

On Tue, 22 Jul 2008, Jay Soffian wrote:

> On Tue, Jul 22, 2008 at 7:40 AM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> > Most people hate to know the internals.  They buy the car, and never 
> > want to look inside the motor compartment.  They buy wine, and never 
> > want to know how it is made.  They buy an iPod and never want to know 
> > who assembles it, and how, and in what environment.
> 
> I agree with this. And I like the top-down approach. Nonetheless, I 
> think there are a few git concepts that are important to understand. 
> Specifically, I don't think you can use git without understanding the 
> index.

I do not see that the index is an internal.  I see that the term "index" 
is.  So I think about not even bothering to mention it in my first two Git 
lessons.

And you would be surprised to learn that I personally know a few people 
who use Git happily _without_ knowing any internals.  Now guess why: was 
it because I explained a few easy-to-grasp commands, or because I made it 
pretty complicated but thorough?  Exactly.

Ciao,
Dscho

^ permalink raw reply

* Re: Git Documentation
From: Jay Soffian @ 2008-07-22 15:47 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Johan Herland, david, Scott Chacon, git
In-Reply-To: <alpine.DEB.1.00.0807221335560.3391@eeepc-johanness>

On Tue, Jul 22, 2008 at 7:40 AM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Most people hate to know the internals.  They buy the car, and never want
> to look inside the motor compartment.  They buy wine, and never want to
> know how it is made.  They buy an iPod and never want to know who
> assembles it, and how, and in what environment.

I agree with this. And I like the top-down approach. Nonetheless, I
think there are a few git concepts that are important to understand.
Specifically, I don't think you can use git without understanding
the index.

Unfortunately, git isn't quite as good about abstractions yet as
some of the items you make analogies to. And even car's leak:

   "And you can't drive as fast when it's raining, even though your
   car has windshield wipers and headlights and a roof and a heater,
   all of which protect you from caring about the fact that it's
   raining (they abstract away the weather), but lo, you have to
   worry about hydroplaning (or aquaplaning in England) and
   sometimes the rain is so strong you can't see very far ahead so
   you go slower in the rain, because the weather can never be
   completely abstracted away, because of the law of leaky
   abstractions."

   http://www.joelonsoftware.com/articles/LeakyAbstractions.html

:-)

j.

^ permalink raw reply

* Re: Git Documentation
From: Scott Chacon @ 2008-07-22 14:46 UTC (permalink / raw)
  To: git
In-Reply-To: <alpine.DEB.1.00.0807221335560.3391@eeepc-johanness>

Thanks all for your input - I like the idea of the two-track thing and
I'll probably use a lot of what you've laid out to help structure the
site.  I have personally tried to do a quick under the covers overview
beforehand because I have found that it helps, but I know many of you
work with new converts a lot too, so thanks again for your feedback.

As this gets going, I'll post here with updates from time to time to
make sure not too many of you feel it's going too far off track or I'm
not making incredible mistakes anywhere.

Thanks,
Scott

On Tue, Jul 22, 2008 at 4:40 AM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Tue, 22 Jul 2008, Johan Herland wrote:
>
>> Many Git users will not be VCS geeks like us; they will be "regular"
>> people that use Git because it's useful for them (or because they're
>> forced to use Git at $dayjob).
>
> Exactly.  But it seems a concept hard to understand to some people.  It
> also seems that VCS geeks like scripting, and assume everybody else does,
> too.  Not so.
>
> Most people hate to know the internals.  They buy the car, and never want
> to look inside the motor compartment.  They buy wine, and never want to
> know how it is made.  They buy an iPod and never want to know who
> assembles it, and how, and in what environment.
>
> You cannot teach those people to be more interested/interesting by showing
> them how things work internally.  But you can give Git a bad reputation in
> the process.
>
> This, amongst other reasons, was why a company I worked at had a policy to
> never _ever_ have presentations or tutorials by technical staff.  Never.
>
> Ciao,
> Dscho
>
>

^ permalink raw reply

* Re: git status in clean working dir
From: David Bremner @ 2008-07-22 14:10 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20080722060643.GA25023@sigill.intra.peff.net>

>>>>> "Jeff" == Jeff King <peff@peff.net> writes:
    Jeff> We already do that (see pager.c:53). The original poster
    Jeff> still had a problem, but I don't know if it was for actual
    Jeff> usage or simply a toy

    Jeff>   $ git status 
    Jeff>   $ echo $?  
    Jeff>   $ echo "why don't exit codes work in status?" | mail git@vger

Well, I wanted to know if git status was the right tool to detect a
working directory with no changes to commit. So I tried it in the
shell, and it failed.  I then read the man page. For me, it would be
fine to document the current behaviour (i.e. in practice "git status
-a > /dev/null" would be what I would use in scripts anyway).  To be
honest the current behaviour was not something I would have guessed.

Thanks to all for paying attention to my complaint,

David

^ permalink raw reply

* Re: problem using jgit
From: Marek Zawirski @ 2008-07-22 11:51 UTC (permalink / raw)
  To: Stephen Bannasch; +Cc: git, Robin Rosenberg, Shawn O. Pearce
In-Reply-To: <p0624080dc4aa78c93ffe@[192.168.1.106]>

Stephen Bannasch wrote:
> At 2:35 PM +0200 7/21/08, Marek Zawirski wrote:
>   
>> Marek Zawirski wrote:
>>     
>>> Stephen Bannasch wrote:
>>>       
>>>> I've setup a simple test class that integrates jgit to clone a git repository. However I'm getting a NullPointerError when RevWalk.parseAny ends up producing a null object id.
>>>>
>>>> The code and the stack trace for the error are here:
>>>>
>>>>  http://pastie.org/237711
>>>>
>>>> This problem occurs using the jgit from the master branch from this repo:
>>>>
>>>>  git://repo.or.cz/egit.git
>>>>         
>>> Hello Stephen,
>>>
>>> I think you've experienced error caused by the same bug as me, during my latest fetch/push GUI works few days ago.
>>> Your code looks fine, probably  it's actually bug in jgit. I think it's some regression. Thanks for reporting.
>>>       
>> It's caused by 14a630c3: Cached modification times for symbolic refs too
>> Changes introduced by this patch made Repository#getAllRefs() including Ref objects with null ObjectId in case of unresolvable (invalid?) HEAD symbolic ref, and null Ref for HEAD  when it doesn't exist. Previous behavior was just not including such refs in result.
>>
>> Fix for null Ref is just a matter of simple filtering out null Ref object for HEAD, if it doesn't exist (just is it considered to be legal state of repository when HEAD doesn't exist?).
>>
>> To fix null ObjectId issue, we have to either change all clients of this method or revert method to previous behavior. Now it's just unspecified in javadoc.
>> Robin, Shawn, what do you think? If we want to have unresolvable refs included, IMO it may be sensible to provide argument includeUnresolbable for Repository#getAllRefs() to let clients avoid burden of filtering them out when they don't need them (most cases, perhaps).
>> I can prepare fix for it (rather easy one) as you are unavailable now, let me now what's your opinion.
>>     
>
> Thanks for looking at this problem Marek. 
>
> If you get a change working for jgit that might not be available in a branch on git://repo.or.cz/egit.gi will you send a patch.
>
> I am looking forward to continuing my tests using jgit from Java and JRuby.
>   

You can find temporary workaround for that in "workaround" branch at 
git://repo.or.cz/egit/zawir.git
It's rather not a final solution (disables unresolvable HEADs), but I 
hope it let you continue using jgit for a while, as it does for me ;)

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox