Git development
 help / color / mirror / Atom feed
* Re: [PATCH resend] Documentation: git-svn: fix example for centralized SVN clone
From: Eric Wong @ 2008-11-15  6:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jan Krüger, Git ML
In-Reply-To: <7vljvl7d3k.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> wrote:
> "Jan Krüger" <jk@jk.gs> writes:
> 
> > The example that tells users how to centralize the effort of the initial
> > git svn clone operation doesn't work properly. It uses rebase but that
> > only works if HEAD exists. This adds one extra command to create a
> > somewhat sensible HEAD that should work in all cases.
> >
> > Signed-off-by: Jan Krüger <jk@jk.gs>
> > ---
> > When I first sent this one I said I didn't like the solution all that
> > much (it would be nicer to use origin/HEAD but we didn't fetch that)
> > but Eric said he thinks it's okay and the original author of the
> > section hasn't piped in. It's still better than a nonfunctional example
> > in any case.
> 
> I'll mark this Acked by Eric and apply to 'maint'.  Thanks, both.

No problem.

I see what happened: I mis-CC-ed Adam as never had him in my aliases
file :x

-- 
Eric Wong

^ permalink raw reply

* Re: [PATCH resend] Documentation: git-svn: fix example for centralized SVN clone
From: Junio C Hamano @ 2008-11-15  5:49 UTC (permalink / raw)
  To: Jan Krüger; +Cc: Git ML, Eric Wong
In-Reply-To: <20081114184514.6f7d437a@perceptron>

"Jan Krüger" <jk@jk.gs> writes:

> The example that tells users how to centralize the effort of the initial
> git svn clone operation doesn't work properly. It uses rebase but that
> only works if HEAD exists. This adds one extra command to create a
> somewhat sensible HEAD that should work in all cases.
>
> Signed-off-by: Jan Krüger <jk@jk.gs>
> ---
> When I first sent this one I said I didn't like the solution all that
> much (it would be nicer to use origin/HEAD but we didn't fetch that)
> but Eric said he thinks it's okay and the original author of the
> section hasn't piped in. It's still better than a nonfunctional example
> in any case.

I'll mark this Acked by Eric and apply to 'maint'.  Thanks, both.

^ permalink raw reply

* Re: [PATCH] sha1_file: make sure correct error is propagated
From: Junio C Hamano @ 2008-11-15  5:44 UTC (permalink / raw)
  To: Francis Galiegue; +Cc: Sam Vilain, Francis Galiegue, git
In-Reply-To: <200811142009.51803.fg@one2team.com>

Francis Galiegue <fg@one2team.com> writes:

> Le Friday 14 November 2008 20:05:19 Junio C Hamano, vous avez écrit :
> [...]
>> >  	fd = mkstemp(buffer);
>> > -	if (fd < 0 && dirlen && (errno != EPERM)) {
>> > +	if (fd < 0 && dirlen && (errno != EACCESS)) {
>>
>> Is this accepting the two as equivalents???
>> --
>> To unsubscribe from this list: send the line "unsubscribe git" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> Well, looking at mkdir(2), it says:
>
>        EPERM  The file system containing pathname does not support the 
> creation of directories.
>
> Hmm, err... git would fail at an earlier point anyway, wouldn't it? Even git 
> init would fail there.

Actually, POSIX does not even talk about EPERM for mkdir(2), but that was
not my point.  The code does something different from what the proposed
commit log message talks about.  That was what bothered me.

^ permalink raw reply

* Re: [PATCH 3/3] Add -k/--keep-going option to mergetool
From: Jeff King @ 2008-11-15  5:38 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Charles Bailey, git, Andreas Ericsson, Theodore Ts'o,
	William Pursell
In-Reply-To: <7vy6zl7drn.fsf@gitster.siamese.dyndns.org>

On Fri, Nov 14, 2008 at 09:35:08PM -0800, Junio C Hamano wrote:

> > -'git mergetool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<file>]...
> 
> I wonder why this even needs to be an option.  If you do not want to
> resolve all of them, you can limit the amount of work you would do by
> giving list of paths to work on, can't you?

I don't know about Charles, but I often don't know that I don't want to
merge a file using the graphical tool until I see it in the graphical
tool. IOW, I start trying to merge it there and realize the conflict is
such that I am better off doing it in my editor with conflict markers.

-Peff

^ permalink raw reply

* Re: [PATCH 3/3] Add -k/--keep-going option to mergetool
From: Junio C Hamano @ 2008-11-15  5:35 UTC (permalink / raw)
  To: Charles Bailey
  Cc: git, Jeff King, Andreas Ericsson, Theodore Ts'o,
	William Pursell
In-Reply-To: <1226580075-29289-4-git-send-email-charles@hashpling.org>

Charles Bailey <charles@hashpling.org> writes:

> This option stops git mergetool from aborting at the first failed merge.
> This allows some additional use patterns. Merge conflicts can now be
> previewed one at time and merges can also be skipped so that they can be
> performed in a later pass.

Hmm, with this command line:

> -'git mergetool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<file>]...

I wonder why this even needs to be an option.  If you do not want to
resolve all of them, you can limit the amount of work you would do by
giving list of paths to work on, can't you?

^ permalink raw reply

* Re: git to libgit2 code relicensing
From: Shawn O. Pearce @ 2008-11-15  5:00 UTC (permalink / raw)
  To: David Brown; +Cc: Linus Torvalds, Andreas Ericsson, Git Mailing List
In-Reply-To: <20081115043051.GA21608@linode.davidb.org>

David Brown <git@davidb.org> wrote:
> On Fri, Nov 14, 2008 at 03:46:58PM -0800, Shawn O. Pearce wrote:
>
>> In addition to the permissions in the GNU General Public License,
>> the authors give you unlimited permission to link the compiled
>> version of this file into combinations with other programs,
>> and to distribute those combinations without any restriction
>> coming from the use of this file.  (The General Public License
>> restrictions do apply in other respects; for example, they cover
>> modification of the file, and distribution when not linked into
>> a combined executable.)
>
> Is this license intended to allow static linking but forbid dynamic
> linking into a non-GPL program?  It depends on how you interpret
> "linked into a combined executable", but that sounds like it
> intentionally excludes the dynamic case.

I don't know.  When I read it myself I assumed dynamic linking
would also be OK.  This is why I prefer programs; I don't read
legalese so I can't quite figure out what the statement means.
At least with C its a little less vague.  ;-)

-- 
Shawn.

^ permalink raw reply

* Re: git to libgit2 code relicensing
From: David Brown @ 2008-11-15  4:30 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Linus Torvalds, Andreas Ericsson, Git Mailing List
In-Reply-To: <20081114234658.GA2932@spearce.org>

On Fri, Nov 14, 2008 at 03:46:58PM -0800, Shawn O. Pearce wrote:

> In addition to the permissions in the GNU General Public License,
> the authors give you unlimited permission to link the compiled
> version of this file into combinations with other programs,
> and to distribute those combinations without any restriction
> coming from the use of this file.  (The General Public License
> restrictions do apply in other respects; for example, they cover
> modification of the file, and distribution when not linked into
> a combined executable.)

Is this license intended to allow static linking but forbid dynamic
linking into a non-GPL program?  It depends on how you interpret
"linked into a combined executable", but that sounds like it
intentionally excludes the dynamic case.

David

^ permalink raw reply

* Re: "secret key not available". "unable to sign the tag".
From: Jeff King @ 2008-11-15  3:57 UTC (permalink / raw)
  To: Gary Yang; +Cc: git
In-Reply-To: <823128.71540.qm@web37902.mail.mud.yahoo.com>

On Fri, Nov 14, 2008 at 03:28:44PM -0800, Gary Yang wrote:

> I got errors and warnings when I used "git tag -s my-tag". It says,
> "secret key not available". "unable to sign the tag". 

Probably because it can't find your secret key, like it says.

> gpg: please see http://www.gnupg.org/faq.html for more information
> gpg: skipped `Gary Yang <gyang@linux123.(none)>': secret key not available
> gpg: signing failed: secret key not available
> error: gpg failed to sign the tag
> fatal: unable to sign the tag
> 
> I ran "gpg --gen-key" and generated keypair. But, still got the same
> error. Please help.

Did the key you generated have the email address
"gyang@linux123.(none)"? If not, then that is your problem.

You need to tell git who you are, since it is unable to deduce it from
doing host lookups. Try:

  git config --global user.email garyyang6@yahoo.com

or whatever email address you used when you created the key, and then
gpg should find it appropriately.

-Peff

^ permalink raw reply

* Re: [PATCH] Teach/Fix pull/fetch -q/-v options
From: Junio C Hamano @ 2008-11-15  3:10 UTC (permalink / raw)
  To: Tuncer Ayaz; +Cc: Junio C Hamano, git
In-Reply-To: <4ac8254d0811141753y18567966h934a5701e168a7bd@mail.gmail.com>

"Tuncer Ayaz" <tuncer.ayaz@gmail.com> writes:

>> The approach with enum { Q, N, V } cannot express this, unfortunately.
>>
>> So let's do something like the attached patch, instead.
>
> That's ok. We should not break anything.
>
> Do you want me to resubmit a new patch with the changes?

As long as you are happy with the suggested change, there is no need to.
You'd need to sign-off the patch, though...

^ permalink raw reply

* Re: [PATCH] Teach/Fix pull/fetch -q/-v options
From: Tuncer Ayaz @ 2008-11-15  1:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7i7594cx.fsf@gitster.siamese.dyndns.org>

On Sat, Nov 15, 2008 at 2:15 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> @@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
>>               remote = remote_get(argv[0]);
>>
>>       transport = transport_get(remote, remote->url[0]);
>> -     if (verbose >= 2)
>> +     if (verbosity == VERBOSE)
>>               transport->verbose = 1;
>> -     if (quiet)
>> +     if (verbosity == QUIET)
>>               transport->verbose = -1;
>>       if (upload_pack)
>>               set_option(TRANS_OPT_UPLOADPACK, upload_pack);
>
> In the original code, the variable verbose can be ">= 2" when "-v -v" is
> given, so transport->verbose is not turned on with a single "-v" alone
> (this correctly mimics the original behaviour in the scripted version).
>
> The approach with enum { Q, N, V } cannot express this, unfortunately.
>
> So let's do something like the attached patch, instead.

That's ok. We should not break anything.

Do you want me to resubmit a new patch with the changes?

> The patch adds OPT__VERBOSITY() that allows you to say "-v -v" to increase
> verbosity (and "-q -q" to make it really quiet, although we do not use it
> anywhere yet).
>
>  builtin-fetch.c |   19 +++++++++----------
>  builtin-merge.c |   21 ++++++++++++++-------
>  parse-options.c |   22 ++++++++++++++++++++++
>  parse-options.h |    6 ++++++
>  4 files changed, 51 insertions(+), 17 deletions(-)
>
> diff --git c/builtin-fetch.c w/builtin-fetch.c
> index f151cfa..7568163 100644
> --- c/builtin-fetch.c
> +++ w/builtin-fetch.c
> @@ -22,7 +22,7 @@ enum {
>        TAGS_SET = 2
>  };
>
> -static int append, force, keep, update_head_ok, verbose, quiet;
> +static int append, force, keep, update_head_ok, verbosity;
>  static int tags = TAGS_DEFAULT;
>  static const char *depth;
>  static const char *upload_pack;
> @@ -30,8 +30,7 @@ static struct strbuf default_rla = STRBUF_INIT;
>  static struct transport *transport;
>
>  static struct option builtin_fetch_options[] = {
> -       OPT__QUIET(&quiet),
> -       OPT__VERBOSE(&verbose),
> +       OPT__VERBOSITY(&verbosity),
>        OPT_BOOLEAN('a', "append", &append,
>                    "append to .git/FETCH_HEAD instead of overwriting"),
>        OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
> @@ -192,7 +191,6 @@ static int s_update_ref(const char *action,
>
>  static int update_local_ref(struct ref *ref,
>                            const char *remote,
> -                           int verbose,
>                            char *display)
>  {
>        struct commit *current = NULL, *updated;
> @@ -210,7 +208,7 @@ static int update_local_ref(struct ref *ref,
>                die("object %s not found", sha1_to_hex(ref->new_sha1));
>
>        if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
> -               if (verbose)
> +               if (verbosity > 0)
>                        sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
>                                "[up to date]", REFCOL_WIDTH, remote,
>                                pretty_ref);
> @@ -366,18 +364,19 @@ static int store_updated_refs(const char *url, const char *remote_name,
>                        note);
>
>                if (ref)
> -                       rc |= update_local_ref(ref, what, verbose, note);
> +                       rc |= update_local_ref(ref, what, note);
>                else
>                        sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
>                                SUMMARY_WIDTH, *kind ? kind : "branch",
>                                 REFCOL_WIDTH, *what ? what : "HEAD");
>                if (*note) {
> -                       if (!shown_url) {
> +                       if (verbosity >= 0 && !shown_url) {
>                                fprintf(stderr, "From %.*s\n",
>                                                url_len, url);
>                                shown_url = 1;
>                        }
> -                       fprintf(stderr, " %s\n", note);
> +                       if (verbosity >= 0)
> +                               fprintf(stderr, " %s\n", note);
>                }
>        }
>        fclose(fp);
> @@ -637,9 +636,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
>                remote = remote_get(argv[0]);
>
>        transport = transport_get(remote, remote->url[0]);
> -       if (verbose >= 2)
> +       if (verbosity >= 2)
>                transport->verbose = 1;
> -       if (quiet)
> +       if (verbosity < 0)
>                transport->verbose = -1;
>        if (upload_pack)
>                set_option(TRANS_OPT_UPLOADPACK, upload_pack);
> diff --git c/builtin-merge.c w/builtin-merge.c
> index 5e7910b..7c2b90c 100644
> --- c/builtin-merge.c
> +++ w/builtin-merge.c
> @@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];
>  static struct strategy **use_strategies;
>  static size_t use_strategies_nr, use_strategies_alloc;
>  static const char *branch;
> +static int verbosity;
>
>  static struct strategy all_strategy[] = {
>        { "recursive",  DEFAULT_TWOHEAD | NO_TRIVIAL },
> @@ -171,6 +172,7 @@ static struct option builtin_merge_options[] = {
>        OPT_CALLBACK('m', "message", &merge_msg, "message",
>                "message to be used for the merge commit (if any)",
>                option_parse_message),
> +       OPT__VERBOSITY(&verbosity),
>        OPT_END()
>  };
>
> @@ -250,7 +252,8 @@ static void restore_state(void)
>  /* This is called when no merge was necessary. */
>  static void finish_up_to_date(const char *msg)
>  {
> -       printf("%s%s\n", squash ? " (nothing to squash)" : "", msg);
> +       if (verbosity >= 0)
> +               printf("%s%s\n", squash ? " (nothing to squash)" : "", msg);
>        drop_save();
>  }
>
> @@ -331,14 +334,15 @@ static void finish(const unsigned char *new_head, const char *msg)
>        if (!msg)
>                strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION"));
>        else {
> -               printf("%s\n", msg);
> +               if (verbosity >= 0)
> +                       printf("%s\n", msg);
>                strbuf_addf(&reflog_message, "%s: %s",
>                        getenv("GIT_REFLOG_ACTION"), msg);
>        }
>        if (squash) {
>                squash_message();
>        } else {
> -               if (!merge_msg.len)
> +               if (verbosity >= 0 && !merge_msg.len)
>                        printf("No merge message -- not updating HEAD\n");
>                else {
>                        const char *argv_gc_auto[] = { "gc", "--auto", NULL };
> @@ -872,6 +876,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
>
>        argc = parse_options(argc, argv, builtin_merge_options,
>                        builtin_merge_usage, 0);
> +       if (verbosity < 0)
> +               show_diffstat = 0;
>
>        if (squash) {
>                if (!allow_fast_forward)
> @@ -1013,10 +1019,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
>
>                strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));
>
> -               printf("Updating %s..%s\n",
> -                       hex,
> -                       find_unique_abbrev(remoteheads->item->object.sha1,
> -                       DEFAULT_ABBREV));
> +               if (verbosity >= 0)
> +                       printf("Updating %s..%s\n",
> +                               hex,
> +                               find_unique_abbrev(remoteheads->item->object.sha1,
> +                               DEFAULT_ABBREV));
>                strbuf_addstr(&msg, "Fast forward");
>                if (have_message)
>                        strbuf_addstr(&msg,
> diff --git c/parse-options.c w/parse-options.c
> index fd08bb4..9eb55cc 100644
> --- c/parse-options.c
> +++ w/parse-options.c
> @@ -484,6 +484,28 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
>        return 0;
>  }
>
> +int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
> +                          int unset)
> +{
> +       int *target = opt->value;
> +
> +       if (unset)
> +               /* --no-quiet, --no-verbose */
> +               *target = 0;
> +       else if (opt->short_name == 'v') {
> +               if (*target >= 0)
> +                       (*target)++;
> +               else
> +                       *target = 1;
> +       } else {
> +               if (*target <= 0)
> +                       (*target)--;
> +               else
> +                       *target = -1;
> +       }
> +       return 0;
> +}
> +
>  /*
>  * This should really be OPTION_FILENAME type as a part of
>  * parse_options that take prefix to do this while parsing.
> diff --git c/parse-options.h w/parse-options.h
> index 5199950..034162e 100644
> --- c/parse-options.h
> +++ w/parse-options.h
> @@ -150,9 +150,15 @@ extern int parse_options_end(struct parse_opt_ctx_t *ctx);
>  /*----- some often used options -----*/
>  extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
>  extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
> +extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
>
>  #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', "verbose", (var), "be verbose")
>  #define OPT__QUIET(var)    OPT_BOOLEAN('q', "quiet",   (var), "be quiet")
> +#define OPT__VERBOSITY(var) \
> +       { OPTION_CALLBACK, 'v', "verbose", (var), NULL, "be more verbose", \
> +         PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \
> +       { OPTION_CALLBACK, 'q', "quiet", (var), NULL, "be more quiet", \
> +         PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
>  #define OPT__DRY_RUN(var)  OPT_BOOLEAN('n', "dry-run", (var), "dry run")
>  #define OPT__ABBREV(var)  \
>        { OPTION_CALLBACK, 0, "abbrev", (var), "n", \
>

^ permalink raw reply

* Re: [PATCH] Teach/Fix pull/fetch -q/-v options
From: Junio C Hamano @ 2008-11-15  1:15 UTC (permalink / raw)
  To: Tuncer Ayaz; +Cc: git
In-Reply-To: <1226708064-19432-1-git-send-email-tuncer.ayaz@gmail.com>

> @@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
>  		remote = remote_get(argv[0]);
>  
>  	transport = transport_get(remote, remote->url[0]);
> -	if (verbose >= 2)
> +	if (verbosity == VERBOSE)
>  		transport->verbose = 1;
> -	if (quiet)
> +	if (verbosity == QUIET)
>  		transport->verbose = -1;
>  	if (upload_pack)
>  		set_option(TRANS_OPT_UPLOADPACK, upload_pack);

In the original code, the variable verbose can be ">= 2" when "-v -v" is
given, so transport->verbose is not turned on with a single "-v" alone
(this correctly mimics the original behaviour in the scripted version).

The approach with enum { Q, N, V } cannot express this, unfortunately.

So let's do something like the attached patch, instead.

The patch adds OPT__VERBOSITY() that allows you to say "-v -v" to increase
verbosity (and "-q -q" to make it really quiet, although we do not use it
anywhere yet).

 builtin-fetch.c |   19 +++++++++----------
 builtin-merge.c |   21 ++++++++++++++-------
 parse-options.c |   22 ++++++++++++++++++++++
 parse-options.h |    6 ++++++
 4 files changed, 51 insertions(+), 17 deletions(-)

diff --git c/builtin-fetch.c w/builtin-fetch.c
index f151cfa..7568163 100644
--- c/builtin-fetch.c
+++ w/builtin-fetch.c
@@ -22,7 +22,7 @@ enum {
 	TAGS_SET = 2
 };
 
-static int append, force, keep, update_head_ok, verbose, quiet;
+static int append, force, keep, update_head_ok, verbosity;
 static int tags = TAGS_DEFAULT;
 static const char *depth;
 static const char *upload_pack;
@@ -30,8 +30,7 @@ static struct strbuf default_rla = STRBUF_INIT;
 static struct transport *transport;
 
 static struct option builtin_fetch_options[] = {
-	OPT__QUIET(&quiet),
-	OPT__VERBOSE(&verbose),
+	OPT__VERBOSITY(&verbosity),
 	OPT_BOOLEAN('a', "append", &append,
 		    "append to .git/FETCH_HEAD instead of overwriting"),
 	OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
@@ -192,7 +191,6 @@ static int s_update_ref(const char *action,
 
 static int update_local_ref(struct ref *ref,
 			    const char *remote,
-			    int verbose,
 			    char *display)
 {
 	struct commit *current = NULL, *updated;
@@ -210,7 +208,7 @@ static int update_local_ref(struct ref *ref,
 		die("object %s not found", sha1_to_hex(ref->new_sha1));
 
 	if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
-		if (verbose)
+		if (verbosity > 0)
 			sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
 				"[up to date]", REFCOL_WIDTH, remote,
 				pretty_ref);
@@ -366,18 +364,19 @@ static int store_updated_refs(const char *url, const char *remote_name,
 			note);
 
 		if (ref)
-			rc |= update_local_ref(ref, what, verbose, note);
+			rc |= update_local_ref(ref, what, note);
 		else
 			sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
 				SUMMARY_WIDTH, *kind ? kind : "branch",
 				 REFCOL_WIDTH, *what ? what : "HEAD");
 		if (*note) {
-			if (!shown_url) {
+			if (verbosity >= 0 && !shown_url) {
 				fprintf(stderr, "From %.*s\n",
 						url_len, url);
 				shown_url = 1;
 			}
-			fprintf(stderr, " %s\n", note);
+			if (verbosity >= 0)
+				fprintf(stderr, " %s\n", note);
 		}
 	}
 	fclose(fp);
@@ -637,9 +636,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 		remote = remote_get(argv[0]);
 
 	transport = transport_get(remote, remote->url[0]);
-	if (verbose >= 2)
+	if (verbosity >= 2)
 		transport->verbose = 1;
-	if (quiet)
+	if (verbosity < 0)
 		transport->verbose = -1;
 	if (upload_pack)
 		set_option(TRANS_OPT_UPLOADPACK, upload_pack);
diff --git c/builtin-merge.c w/builtin-merge.c
index 5e7910b..7c2b90c 100644
--- c/builtin-merge.c
+++ w/builtin-merge.c
@@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];
 static struct strategy **use_strategies;
 static size_t use_strategies_nr, use_strategies_alloc;
 static const char *branch;
+static int verbosity;
 
 static struct strategy all_strategy[] = {
 	{ "recursive",  DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -171,6 +172,7 @@ static struct option builtin_merge_options[] = {
 	OPT_CALLBACK('m', "message", &merge_msg, "message",
 		"message to be used for the merge commit (if any)",
 		option_parse_message),
+	OPT__VERBOSITY(&verbosity),
 	OPT_END()
 };
 
@@ -250,7 +252,8 @@ static void restore_state(void)
 /* This is called when no merge was necessary. */
 static void finish_up_to_date(const char *msg)
 {
-	printf("%s%s\n", squash ? " (nothing to squash)" : "", msg);
+	if (verbosity >= 0)
+		printf("%s%s\n", squash ? " (nothing to squash)" : "", msg);
 	drop_save();
 }
 
@@ -331,14 +334,15 @@ static void finish(const unsigned char *new_head, const char *msg)
 	if (!msg)
 		strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION"));
 	else {
-		printf("%s\n", msg);
+		if (verbosity >= 0)
+			printf("%s\n", msg);
 		strbuf_addf(&reflog_message, "%s: %s",
 			getenv("GIT_REFLOG_ACTION"), msg);
 	}
 	if (squash) {
 		squash_message();
 	} else {
-		if (!merge_msg.len)
+		if (verbosity >= 0 && !merge_msg.len)
 			printf("No merge message -- not updating HEAD\n");
 		else {
 			const char *argv_gc_auto[] = { "gc", "--auto", NULL };
@@ -872,6 +876,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, builtin_merge_options,
 			builtin_merge_usage, 0);
+	if (verbosity < 0)
+		show_diffstat = 0;
 
 	if (squash) {
 		if (!allow_fast_forward)
@@ -1013,10 +1019,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
 		strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));
 
-		printf("Updating %s..%s\n",
-			hex,
-			find_unique_abbrev(remoteheads->item->object.sha1,
-			DEFAULT_ABBREV));
+		if (verbosity >= 0)
+			printf("Updating %s..%s\n",
+				hex,
+				find_unique_abbrev(remoteheads->item->object.sha1,
+				DEFAULT_ABBREV));
 		strbuf_addstr(&msg, "Fast forward");
 		if (have_message)
 			strbuf_addstr(&msg,
diff --git c/parse-options.c w/parse-options.c
index fd08bb4..9eb55cc 100644
--- c/parse-options.c
+++ w/parse-options.c
@@ -484,6 +484,28 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
 	return 0;
 }
 
+int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
+			   int unset)
+{
+	int *target = opt->value;
+
+	if (unset)
+		/* --no-quiet, --no-verbose */
+		*target = 0;
+	else if (opt->short_name == 'v') {
+		if (*target >= 0)
+			(*target)++;
+		else
+			*target = 1;
+	} else {
+		if (*target <= 0)
+			(*target)--;
+		else
+			*target = -1;
+	}
+	return 0;
+}
+
 /*
  * This should really be OPTION_FILENAME type as a part of
  * parse_options that take prefix to do this while parsing.
diff --git c/parse-options.h w/parse-options.h
index 5199950..034162e 100644
--- c/parse-options.h
+++ w/parse-options.h
@@ -150,9 +150,15 @@ extern int parse_options_end(struct parse_opt_ctx_t *ctx);
 /*----- some often used options -----*/
 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
 extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
+extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
 
 #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', "verbose", (var), "be verbose")
 #define OPT__QUIET(var)    OPT_BOOLEAN('q', "quiet",   (var), "be quiet")
+#define OPT__VERBOSITY(var) \
+	{ OPTION_CALLBACK, 'v', "verbose", (var), NULL, "be more verbose", \
+	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \
+	{ OPTION_CALLBACK, 'q', "quiet", (var), NULL, "be more quiet", \
+	  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
 #define OPT__DRY_RUN(var)  OPT_BOOLEAN('n', "dry-run", (var), "dry run")
 #define OPT__ABBREV(var)  \
 	{ OPTION_CALLBACK, 0, "abbrev", (var), "n", \

^ permalink raw reply related

* Re: [PATCH v2 06/11] gitweb: use CSS to style split head lists.
From: Jakub Narebski @ 2008-11-15  0:20 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: git, Petr Baudis, Junio C Hamano
In-Reply-To: <1226616555-24503-7-git-send-email-giuseppe.bilotta@gmail.com>

On Thu, 13 Nov 2008, Giuseppe Bilotta wrote:

> Introduce a new div class 'subsection' in the CSS and use it to style
> split head lists.

I think this patch should be squashed with the previous one.
 
> Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
> ---
>  gitweb/gitweb.css  |   10 ++++++++++
>  gitweb/gitweb.perl |    4 +++-
>  2 files changed, 13 insertions(+), 1 deletions(-)
> 
> diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
> index a01eac8..751749f 100644
> --- a/gitweb/gitweb.css
> +++ b/gitweb/gitweb.css
> @@ -8,6 +8,16 @@ body {
>  	color: #000000;
>  }
>  
> +div.subsection {
> +	border: solid #d9d8d1;
> +	border-width: 1px;
> +	margin: 10px;
> +}
> +
> +.subsection .title {
> +	font-size: smaller;
> +}

Hmmm... do we use "subsection title" class anywhere? If you did
introduce it in earlier patch, this is one more reason to squash
them (after significant reworking)... ahh, this is link or span
or div with class .title insider div.subsection, sorry.

> +
>  a {
>  	color: #0000cc;
>  }
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 836b6ba..03e0b21 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -4296,9 +4296,11 @@ sub git_split_heads_body {
>  	} @$headlist;
>  
>  	foreach $leader (sort(keys %headlists)) {
> -		print "<b>$leader</b><br/>\n" unless $leader eq "\000";
> +		print "<div class=\"subsection\">\n";
> +		git_print_header_div(undef, $leader) unless $leader eq "\000";

Again, cannot this ugly guardian value be replaced by for example empty
string '', or undef?

>  		$list = $headlists{$leader};
>  		git_heads_body($list, $head, $from, $to, $extra);
> +		print "</div>\n";

Just in case, for easier editing and easier browsing through *occur*
buffer, I'd use here

+		print "</div>\n"; # class="subsection"


>  	}
>  }
>  

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [PATCH] Teach/Fix pull/fetch -q/-v options
From: Tuncer Ayaz @ 2008-11-15  0:14 UTC (permalink / raw)
  To: git; +Cc: gitster

Implement git-pull --quiet and git-pull --verbose by
adding the options to git-pull and fixing verbosity
handling in git-fetch.
---
 Documentation/merge-options.txt |    8 +++++
 builtin-fetch.c                 |   21 +++++++------
 builtin-merge.c                 |   22 ++++++++++----
 git-pull.sh                     |   10 ++++--
 t/t5521-pull-options.sh         |   60 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 101 insertions(+), 20 deletions(-)
 create mode 100755 t/t5521-pull-options.sh

diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index 007909a..427cdef 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -1,3 +1,11 @@
+-q::
+--quiet::
+	Operate quietly.
+
+-v::
+--verbose::
+	Be verbose.
+
 --stat::
 	Show a diffstat at the end of the merge. The diffstat is also
 	controlled by the configuration option merge.stat.
diff --git a/builtin-fetch.c b/builtin-fetch.c
index f151cfa..efc5801 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -22,16 +22,17 @@ enum {
 	TAGS_SET = 2
 };
 
-static int append, force, keep, update_head_ok, verbose, quiet;
+static int append, force, keep, update_head_ok;
 static int tags = TAGS_DEFAULT;
 static const char *depth;
 static const char *upload_pack;
 static struct strbuf default_rla = STRBUF_INIT;
 static struct transport *transport;
+static enum { QUIET, NORMAL, VERBOSE } verbosity = NORMAL;
 
 static struct option builtin_fetch_options[] = {
-	OPT__QUIET(&quiet),
-	OPT__VERBOSE(&verbose),
+	OPT_SET_INT('v', "verbose", &verbosity, "be verbose", VERBOSE),
+	OPT_SET_INT('q', "quiet", &verbosity, "operate quietly", QUIET),
 	OPT_BOOLEAN('a', "append", &append,
 		    "append to .git/FETCH_HEAD instead of overwriting"),
 	OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
@@ -192,7 +193,6 @@ static int s_update_ref(const char *action,
 
 static int update_local_ref(struct ref *ref,
 			    const char *remote,
-			    int verbose,
 			    char *display)
 {
 	struct commit *current = NULL, *updated;
@@ -210,7 +210,7 @@ static int update_local_ref(struct ref *ref,
 		die("object %s not found", sha1_to_hex(ref->new_sha1));
 
 	if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
-		if (verbose)
+		if (verbosity == VERBOSE)
 			sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
 				"[up to date]", REFCOL_WIDTH, remote,
 				pretty_ref);
@@ -366,18 +366,19 @@ static int store_updated_refs(const char *url, const char *remote_name,
 			note);
 
 		if (ref)
-			rc |= update_local_ref(ref, what, verbose, note);
+			rc |= update_local_ref(ref, what, note);
 		else
 			sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
 				SUMMARY_WIDTH, *kind ? kind : "branch",
 				 REFCOL_WIDTH, *what ? what : "HEAD");
 		if (*note) {
-			if (!shown_url) {
+			if (verbosity > QUIET && !shown_url) {
 				fprintf(stderr, "From %.*s\n",
 						url_len, url);
 				shown_url = 1;
 			}
-			fprintf(stderr, " %s\n", note);
+			if (verbosity > QUIET)
+				fprintf(stderr, " %s\n", note);
 		}
 	}
 	fclose(fp);
@@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 		remote = remote_get(argv[0]);
 
 	transport = transport_get(remote, remote->url[0]);
-	if (verbose >= 2)
+	if (verbosity == VERBOSE)
 		transport->verbose = 1;
-	if (quiet)
+	if (verbosity == QUIET)
 		transport->verbose = -1;
 	if (upload_pack)
 		set_option(TRANS_OPT_UPLOADPACK, upload_pack);
diff --git a/builtin-merge.c b/builtin-merge.c
index 5e7910b..a35f944 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];
 static struct strategy **use_strategies;
 static size_t use_strategies_nr, use_strategies_alloc;
 static const char *branch;
+static enum { QUIET, NORMAL, VERBOSE } verbosity = NORMAL;
 
 static struct strategy all_strategy[] = {
 	{ "recursive",  DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -152,6 +153,8 @@ static int option_parse_n(const struct option *opt,
 }
 
 static struct option builtin_merge_options[] = {
+	OPT_SET_INT('v', "verbose", &verbosity, "be verbose", VERBOSE),
+	OPT_SET_INT('q', "quiet", &verbosity, "operate quietly", QUIET),
 	{ OPTION_CALLBACK, 'n', NULL, NULL, NULL,
 		"do not show a diffstat at the end of the merge",
 		PARSE_OPT_NOARG, option_parse_n },
@@ -250,7 +253,8 @@ static void restore_state(void)
 /* This is called when no merge was necessary. */
 static void finish_up_to_date(const char *msg)
 {
-	printf("%s%s\n", squash ? " (nothing to squash)" : "", msg);
+	if (verbosity > QUIET)
+		printf("%s%s\n", squash ? " (nothing to squash)" : "", msg);
 	drop_save();
 }
 
@@ -331,14 +335,15 @@ static void finish(const unsigned char *new_head, const char *msg)
 	if (!msg)
 		strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION"));
 	else {
-		printf("%s\n", msg);
+		if (verbosity > QUIET)
+			printf("%s\n", msg);
 		strbuf_addf(&reflog_message, "%s: %s",
 			getenv("GIT_REFLOG_ACTION"), msg);
 	}
 	if (squash) {
 		squash_message();
 	} else {
-		if (!merge_msg.len)
+		if (verbosity > QUIET && !merge_msg.len)
 			printf("No merge message -- not updating HEAD\n");
 		else {
 			const char *argv_gc_auto[] = { "gc", "--auto", NULL };
@@ -872,6 +877,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, builtin_merge_options,
 			builtin_merge_usage, 0);
+	if (verbosity == QUIET)
+		show_diffstat = 0;
 
 	if (squash) {
 		if (!allow_fast_forward)
@@ -1013,10 +1020,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
 		strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));
 
-		printf("Updating %s..%s\n",
-			hex,
-			find_unique_abbrev(remoteheads->item->object.sha1,
-			DEFAULT_ABBREV));
+		if (verbosity > QUIET)
+			printf("Updating %s..%s\n",
+				hex,
+				find_unique_abbrev(remoteheads->item->object.sha1,
+				DEFAULT_ABBREV));
 		strbuf_addstr(&msg, "Fast forward");
 		if (have_message)
 			strbuf_addstr(&msg,
diff --git a/git-pull.sh b/git-pull.sh
index 664fe34..8866f2a 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -16,13 +16,17 @@ cd_to_toplevel
 test -z "$(git ls-files -u)" ||
 	die "You are in the middle of a conflicted merge."
 
-strategy_args= no_stat= no_commit= squash= no_ff= log_arg=
+strategy_args= no_stat= no_commit= squash= no_ff= log_arg= verbosity=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
 rebase=$(git config --bool branch.$curr_branch_short.rebase)
 while :
 do
 	case "$1" in
+	-q|--quiet)
+		verbosity=-q ;;
+	-v|--verbose)
+		verbosity=-v ;;
 	-n|--no-stat|--no-summary)
 		no_stat=-n ;;
 	--stat|--summary)
@@ -121,7 +125,7 @@ test true = "$rebase" && {
 		"refs/remotes/$origin/$reflist" 2>/dev/null)"
 }
 orig_head=$(git rev-parse --verify HEAD 2>/dev/null)
-git fetch --update-head-ok "$@" || exit 1
+git fetch $verbosity --update-head-ok "$@" || exit 1
 
 curr_head=$(git rev-parse --verify HEAD 2>/dev/null)
 if test -n "$orig_head" && test "$curr_head" != "$orig_head"
@@ -182,4 +186,4 @@ test true = "$rebase" &&
 	exec git-rebase $strategy_args --onto $merge_head \
 	${oldremoteref:-$merge_head}
 exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \
-	"$merge_name" HEAD $merge_head
+	"$merge_name" HEAD $merge_head $verbosity
diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
new file mode 100755
index 0000000..83e2e8a
--- /dev/null
+++ b/t/t5521-pull-options.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+test_description='pull options'
+
+. ./test-lib.sh
+
+D=`pwd`
+
+test_expect_success 'setup' '
+	mkdir parent &&
+	(cd parent && git init &&
+	 echo one >file && git add file &&
+	 git commit -m one)
+'
+
+cd "$D"
+
+test_expect_success 'git pull -q' '
+	mkdir clonedq &&
+	cd clonedq &&
+	git pull -q "$D/parent" >out 2>err &&
+	test ! -s out
+'
+
+cd "$D"
+
+test_expect_success 'git pull' '
+	mkdir cloned &&
+	cd cloned &&
+	git pull "$D/parent" >out 2>err &&
+	test -s out
+'
+cd "$D"
+
+test_expect_success 'git pull -v' '
+	mkdir clonedv &&
+	cd clonedv &&
+	git pull -v "$D/parent" >out 2>err &&
+	test -s out
+'
+
+cd "$D"
+
+test_expect_success 'git pull -v -q' '
+	mkdir clonedvq &&
+	cd clonedvq &&
+	git pull -v -q "$D/parent" >out 2>err &&
+	test ! -s out
+'
+
+cd "$D"
+
+test_expect_success 'git pull -q -v' '
+	mkdir clonedqv &&
+	cd clonedqv &&
+	git pull -q -v "$D/parent" >out 2>err &&
+	test -s out
+'
+
+test_done
-- 
1.6.0.4

^ permalink raw reply related

* Re: [PATCH] Teach/Fix pull/fetch -q/-v options
From: Tuncer Ayaz @ 2008-11-15  0:09 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy6zon02o.fsf@gitster.siamese.dyndns.org>

On Wed, Nov 12, 2008 at 9:47 PM, Junio C Hamano <gitster@pobox.com> wrote:
> "Tuncer Ayaz" <tuncer.ayaz@gmail.com> writes:
>
>> On Fri, Nov 7, 2008 at 4:26 AM, Tuncer Ayaz <tuncer.ayaz@gmail.com> wrote:
>>> Implement git-pull --quiet and git-pull --verbose by
>>> adding the options to git-pull and fixing verbosity
>>> handling in git-fetch.
>>
>> Junio,
>>
>> is there anything still missing in this patch?
>> Maybe the name of the test-case is bad.
>
> It seems to break t7600.

thanks for the good review, it sure does break.

I hadn't noticed it as I didn't compare test results
of master against my branch and assumed that that
breakage is part of common failing tests.

Shawn helped me out a little bit with debugging the test scripts
and I quickly found out that an if clause is wrong.
the diff for the last patch to correct it is:
 --- a/builtin-merge.c
 +++ b/builtin-merge.c
 @@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];
@@ -163,7 +144,7 @@

        argc = parse_options(argc, argv, builtin_merge_options,
                        builtin_merge_usage, 0);
-+      if (verbosity > QUIET)
++      if (verbosity == QUIET)
 +              show_diffstat = 0;


a corrected patch will arrive here in a minute.

^ permalink raw reply

* Re: [PATCH v2 05/11] gitweb: git_split_heads_body function.
From: Jakub Narebski @ 2008-11-14 23:59 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: git, Petr Baudis, Junio C Hamano
In-Reply-To: <1226616555-24503-6-git-send-email-giuseppe.bilotta@gmail.com>

On Thu, 13 Nov 2008, Giuseppe Bilotta wrote:

> The purpose of this function is to split a headlist into groups
> determined by the leading part of the refname, and call git_heads_body()
> on each group.

What is the reason of this patch? Is it to split remote-tracking
branches ('remotes' references) into remotes, and group them by
the remote repository name?

If it is true, then first: you should have wrote the _reason_ behind
this patch and not only what it does in this commit message. And use
better summary (commit title / subject of this patch).

Second, this patch wouldn't do what you want from it if there are
remotes with '/' in name.  I for example use "gsoc2008/gitweb-caching"
for Lea Wiemann repository with her GSoC 2008 work on adding caching
to gitweb.  Because there are many ways to specify remotes due to
backwards compatibility (and simplicity, as some for example prefer
old 'branches/' way to specify remotes), namely config, files under
'.git/remotes', and (from Cogito) files in '.git/branches', you would
have to either reimplement/reuse parts of git-remote (there is old Perl
implementation in contrib/examples), or use "git remote" or 
"git remote -v" command output[1].


So from me there is slight NAK on this patch, in this form.

> 
> Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
> ---
>  gitweb/gitweb.perl |   33 ++++++++++++++++++++++++++++++++-
>  1 files changed, 32 insertions(+), 1 deletions(-)
> 
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index a736f2a..836b6ba 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -4271,6 +4271,37 @@ sub git_tags_body {
>  	print "</table>\n";
>  }
>  
> +sub git_split_heads_body {
> +	my ($headlist, $head, $from, $to, $extra) = @_;

It should probably be said somewhere that git_split_heads_body has to
have the same signature as git_heads_body.

> +	my %headlists;
> +	my $leader; my $list; my @list;

Style - I would use:

+	my ($leader, $list, @list);

although I wouldn't use $list and @list together...

> +
> +	# Split @$headlist into a hash of lists
> +	map {
> +		my %ref = %$_;
> +		$ref{'hname'} = $ref{'name'};
> +		if ($ref{'name'} =~ /\//) {
> +			$ref{'name'} =~ s!^([^/]+)/!!;

As I said, this would fail on for example "gsoc2008/gitweb-caching"
remote...

> +			$leader = $1;
> +		} else {
> +			$leader = "\000";

Can't you use undef or "" for $leader? $headlists{undef} works...

> +		}
> +		if (defined $headlists{$leader}) {
> +			@list = @{$headlists{$leader}}
> +		} else {
> +			@list = ()
> +		}
> +		push @list, \%ref;
> +		$headlists{$leader} = [@list];

We have similar code in href(), but we use there:

  if (defined $ref{key}) {
  	push @{$ref{$key}}, $elem;
  } else {
  	$ref{$key} = [ $elem ];
  }

Isn't it simpler and easier to understand?


> +	} @$headlist;

Why such ugly and ungainy 'map' invocation, instead of IMHO simpler
and better here foreach loop?

> +
> +	foreach $leader (sort(keys %headlists)) {
> +		print "<b>$leader</b><br/>\n" unless $leader eq "\000";
> +		$list = $headlists{$leader};
> +		git_heads_body($list, $head, $from, $to, $extra);
> +	}
> +}

Wouldn't be it simpler to loop over @$headlist, and if prefix (or to be
more exact repository shorthand aka 'remote') changes then run 
git_heads_body, adjusting $from / $to accordingly, based on current and
remembered index? I think we can assume that list is sorted by refname,
can't we? If not then perhaps the way by building hash is good idea
after all...

> +
>  sub git_heads_body {
>  	# uses global variable $project
>  	my ($headlist, $head, $from, $to, $extra) = @_;
> @@ -4541,7 +4572,7 @@ sub git_summary {
>  
>  	if (@remotelist) {
>  		git_print_header_div('remotes');
> -		git_heads_body(\@remotelist, $head, 0, 15,
> +		git_split_heads_body(\@remotelist, $head, 0, 15,
>  		               $#remotelist <= 15 ? undef :
>  		               $cgi->a({-href => href(action=>"heads")}, "..."));
>  	}

Nice.


Footnotes:
==========
[1] It is strange that there is no explicit "git remote list"
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: git to libgit2 code relicensing
From: Shawn O. Pearce @ 2008-11-14 23:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andreas Ericsson, Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811141512480.3468@nehalem.linux-foundation.org>

Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Fri, 14 Nov 2008, Andreas Ericsson wrote:
> > 
> > The license decided for libgit2 is "GPL with gcc exception".
> 
> What's the exact language? 
> 
> I'm likely ok with GPLv2 + libgcc-like exception, but I'd like to see the 
> exact one. I haven't followed the discussions much..

The language we are using in libgit2 is taken from libgcc, and is
as follows:

--8<--

 Note that the only valid version of the GPL as far as this project
 is concerned is _this_ particular version of the license (ie v2, not
 v2.2 or v3.x or whatever), unless explicitly otherwise stated.

 In addition to the permissions in the GNU General Public License,
 the authors give you unlimited permission to link the compiled
 version of this file into combinations with other programs,
 and to distribute those combinations without any restriction
 coming from the use of this file.  (The General Public License
 restrictions do apply in other respects; for example, they cover
 modification of the file, and distribution when not linked into
 a combined executable.)

----------------------------------------------------------------------

		    GNU GENERAL PUBLIC LICENSE
		       Version 2, June 1991

(... the rest of GPL v2 as it appears in git.git ...)

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH v2 04/11] gitweb: optional custom name for refs in git_heads_body
From: Jakub Narebski @ 2008-11-14 23:32 UTC (permalink / raw)
  To: Giuseppe Bilotta; +Cc: git, Petr Baudis, Junio C Hamano
In-Reply-To: <1226616555-24503-5-git-send-email-giuseppe.bilotta@gmail.com>

On Thu, 13 Nov 2008, Giuseppe Bilotta wrote:

> We make a clear separation between the hash reference and the displayed
> name for refs displayed by git_heads_body. This can be used e.g. to
> group them and display only the distinct part of the name.

It is not clear for me from this commit message what this patch
is meant to do. Already git_heads_body (and also git_tags_body)
uses $ref{'name'} for display, and $ref{'fullname'} for linking
(to avoid possibility of tag/branch name conflict).

> 
> Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
> ---
>  gitweb/gitweb.perl |   12 +++++++-----
>  1 files changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index ab29aec..a736f2a 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -4288,16 +4288,18 @@ sub git_heads_body {
>  		} else {
>  			print "<tr class=\"light\">\n";
>  		}
> +		my $hname = $ref{'hname'} || $ref{'fullname'} || $ref{'name'};

I don't remember setting $ref{'hname'} anywhere; if there is a patch
that sets this, it should really be squashed together with this commit.
Otherwise the commit is not standalone, as it should be.

> +		my $name = $ref{'name'};

I understand that this is simply "shortcut" name, to avoid using
$ref{'name'} everywhere else, and instead using $name?  This is a bit
independent, I mean in the sense that it makes sense to squash those
patches together in a kind of "by the way" way, i.e. simplify the code
if we are making changes in this area.

>  		$alternate ^= 1;
>  		print "<td><i>$ref{'age'}</i></td>\n" .
>  		      ($curr ? "<td class=\"current_head\">" : "<td>") .
> -		      $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'}),
> -		               -class => "list name"},esc_html($ref{'name'})) .
> +		      $cgi->a({-href => href(action=>"shortlog", hash=>$hname),
> +		               -class => "list name"},esc_html($name)) .
>  		      "</td>\n" .
>  		      "<td class=\"link\">" .
> -		      $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'})}, "shortlog") . " | " .
> -		      $cgi->a({-href => href(action=>"log", hash=>$ref{'fullname'})}, "log") . " | " .
> -		      $cgi->a({-href => href(action=>"tree", hash=>$ref{'fullname'}, hash_base=>$ref{'name'})}, "tree") .
> +		      $cgi->a({-href => href(action=>"shortlog", hash=>$hname)}, "shortlog") . " | " .
> +		      $cgi->a({-href => href(action=>"log", hash=>$hname)}, "log") . " | " .
> +		      $cgi->a({-href => href(action=>"tree", hash=>$hname, hash_base=>$hname)}, "tree") .
>  		      "</td>\n" .
>  		      "</tr>";
>  	}

So, in short I think this patch needs work, at least better commit
message (perhaps I don't understand something...)

-- 
Jakub Narebski
Poland

^ permalink raw reply

* "secret key not available". "unable to sign the tag".
From: Gary Yang @ 2008-11-14 23:28 UTC (permalink / raw)
  To: git

Hi,

I got errors and warnings when I used "git tag -s my-tag". It says, "secret key not available". "unable to sign the tag". 

gpg: please see http://www.gnupg.org/faq.html for more information
gpg: skipped `Gary Yang <gyang@linux123.(none)>': secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the tag
fatal: unable to sign the tag

I ran "gpg --gen-key" and generated keypair. But, still got the same error. Please help.


Thank,

Gary


      

^ permalink raw reply

* [EGIT PATCH 4/7 v3] Handle peeling of loose refs.
From: Robin Rosenberg @ 2008-11-14 23:24 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226705099-18066-3-git-send-email-robin.rosenberg@dewire.com>

For packed refs we got peeling automatically from packed-refs,
but for loose tags we have to follow the tags and get the leaf
object in order to comply with the documentation.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java |   35 ++++++++++++++-----
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   32 ++++++++++++++++--
 .../src/org/spearce/jgit/lib/Repository.java       |   13 +++++++
 .../spearce/jgit/transport/BasePackConnection.java |    2 +-
 .../spearce/jgit/transport/TransportAmazonS3.java  |    2 +-
 .../org/spearce/jgit/transport/TransportHttp.java  |    2 +-
 .../org/spearce/jgit/transport/TransportSftp.java  |    2 +-
 .../jgit/transport/WalkRemoteObjectDatabase.java   |    2 +-
 8 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
index 2f102af..0e98f46 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
@@ -126,6 +126,8 @@ public boolean isPacked() {
 
 	private final String origName;
 
+	private final boolean peeled;
+
 	/**
 	 * Create a new ref pairing.
 	 * 
@@ -140,10 +142,7 @@ public boolean isPacked() {
 	 *            does not exist yet.
 	 */
 	public Ref(final Storage st, final String origName, final String refName, final ObjectId id) {
-		storage = st;
-		this.origName = origName;
-		name = refName;
-		objectId = id;
+		this(st, origName, refName, id, null, false);
 	}
 
 	/**
@@ -158,7 +157,7 @@ public Ref(final Storage st, final String origName, final String refName, final 
 	 *            does not exist yet.
 	 */
 	public Ref(final Storage st, final String refName, final ObjectId id) {
-		this(st, refName, refName, id);
+		this(st, refName, refName, id, null, false);
 	}
 
 	/**
@@ -175,15 +174,18 @@ public Ref(final Storage st, final String refName, final ObjectId id) {
 	 *            does not exist yet.
 	 * @param peel
 	 *            peeled value of the ref's tag. May be null if this is not a
-	 *            tag or the peeled value is not known.
+	 *            tag or not yet peeled (in which case the next parameter should be null)
+	 * @param peeled
+	 * 			  true if peel represents a the peeled value of the object
 	 */
 	public Ref(final Storage st, final String origName, final String refName, final ObjectId id,
-			final ObjectId peel) {
+			final ObjectId peel, final boolean peeled) {
 		storage = st;
 		this.origName = origName;
 		name = refName;
 		objectId = id;
 		peeledObjectId = peel;
+		this.peeled = peeled;
 	}
 
 	/**
@@ -199,10 +201,12 @@ public Ref(final Storage st, final String origName, final String refName, final 
 	 * @param peel
 	 *            peeled value of the ref's tag. May be null if this is not a
 	 *            tag or the peeled value is not known.
+	 * @param peeled
+	 * 			  true if peel represents a the peeled value of the object
 	 */
 	public Ref(final Storage st, final String refName, final ObjectId id,
-			final ObjectId peel) {
-		this(st, refName, refName, id, peel);
+			final ObjectId peel, boolean peeled) {
+		this(st, refName, refName, id, peel, peeled);
 	}
 
 	/**
@@ -238,10 +242,19 @@ public ObjectId getObjectId() {
 	 *         refer to an annotated tag.
 	 */
 	public ObjectId getPeeledObjectId() {
+		if (!peeled)
+			return null;
 		return peeledObjectId;
 	}
 
 	/**
+	 * @return whether the Ref represents a peeled tag
+	 */
+	public boolean isPeeled() {
+		return peeled;
+	}
+
+	/**
 	 * How was this ref obtained?
 	 * <p>
 	 * The current storage model of a Ref may influence how the ref must be
@@ -259,4 +272,8 @@ public String toString() {
 			o = "(" + origName + ")";
 		return "Ref[" + o + name + "=" + ObjectId.toString(getObjectId()) + "]";
 	}
+
+	void setPeeledObjectId(final ObjectId id) {
+		peeledObjectId = id;
+	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 5a1b85f..494aecb 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -271,7 +271,8 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 					return;
 				}
 
-				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
+				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id, null, false); // unpeeled
+
 				looseRefs.put(ref.getName(), ref);
 				looseRefsMTime.put(ref.getName(), ent.lastModified());
 				avail.put(ref.getName(), ref);
@@ -288,6 +289,28 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 		}
 	}
 
+	Ref peel(final Ref ref) {
+		if (ref.isPeeled())
+			return ref;
+		ObjectId peeled = null;
+		try {
+			Object target = db.mapObject(ref.getObjectId(), ref.getName());
+			while (target instanceof Tag) {
+				final Tag tag = (Tag)target;
+				peeled = tag.getObjId();
+				if (Constants.TYPE_TAG.equals(tag.getType()))
+					target = db.mapObject(tag.getObjId(), ref.getName());
+				else
+					break;
+			}
+		} catch (IOException e) {
+			// Ignore a read error.  Callers will also get the same error
+			// if they try to use the result of getPeeledObjectId.
+		}
+		return new Ref(ref.getStorage(), ref.getName(), ref.getObjectId(), peeled, true);
+
+	}
+
 	private File fileForRef(final String name) {
 		if (name.startsWith(REFS_SLASH))
 			return new File(refsDir, name.substring(REFS_SLASH.length()));
@@ -350,7 +373,7 @@ private Ref readRefBasic(final String origName, final String name, final int dep
 			if (r == null)
 				return new Ref(Ref.Storage.LOOSE, origName, target, null);
 			if (!origName.equals(r.getName()))
-				r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId());
+				r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId(), true);
 			return r; 
 		}
 
@@ -364,6 +387,9 @@ private Ref readRefBasic(final String origName, final String name, final int dep
 		}
 
 		ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
+
+		looseRefs.put(origName, ref);
+		ref = new Ref(Ref.Storage.LOOSE, origName, id);
 		looseRefs.put(name, ref);
 		looseRefsMTime.put(name, mtime);
 		return ref;
@@ -397,7 +423,7 @@ private void refreshPackedRefs() {
 
 						final ObjectId id = ObjectId.fromString(p.substring(1));
 						last = new Ref(Ref.Storage.PACKED, last.getName(), last
-								.getName(), last.getObjectId(), id);
+								.getName(), last.getObjectId(), id, true);
 						newPackedRefs.put(last.getName(), last);
 						continue;
 					}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 26748e2..4d6e6fd 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -939,6 +939,19 @@ public String getBranch() throws IOException {
 	}
 
 	/**
+	 * Peel a possibly unpeeled ref and updates it. If the ref cannot be peeled
+	 * the peeled id is set to {@link ObjectId#zeroId()}
+	 * 
+	 * @param ref
+	 *            The ref to peel
+	 * @return The same, an updated ref with peeled info or a new instance with
+	 *         more information
+	 */
+	public Ref peel(final Ref ref) {
+		return refs.peel(ref);
+	}
+
+	/**
 	 * @return true if HEAD points to a StGit patch.
 	 */
 	public boolean isStGitMode() {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
index e5fc040..e9df30e 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackConnection.java
@@ -176,7 +176,7 @@ private void readAdvertisedRefsImpl() throws IOException {
 					throw duplicateAdvertisement(name + "^{}");
 
 				avail.put(name, new Ref(Ref.Storage.NETWORK, name, prior
-						.getObjectId(), id));
+						.getObjectId(), id, true));
 			} else {
 				final Ref prior;
 				prior = avail.put(name, new Ref(Ref.Storage.NETWORK, name, id));
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
index f9df36d..9f1b516 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
@@ -300,7 +300,7 @@ private Ref readRef(final TreeMap<String, Ref> avail, final String rn)
 				if (r == null)
 					return null;
 				r = new Ref(r.getStorage(), rn, r.getObjectId(), r
-						.getPeeledObjectId());
+						.getPeeledObjectId(), r.isPeeled());
 				avail.put(r.getName(), r);
 				return r;
 			}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java
index 1357e58..fe4a437 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportHttp.java
@@ -237,7 +237,7 @@ FileStream open(final String path) throws IOException {
 						throw duplicateAdvertisement(name + "^{}");
 
 					avail.put(name, new Ref(Ref.Storage.NETWORK, name, prior
-							.getObjectId(), id));
+							.getObjectId(), id, true));
 				} else {
 					final Ref prior = avail.put(name, new Ref(
 							Ref.Storage.NETWORK, name, id));
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
index 78f4ad8..544e77c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
@@ -428,7 +428,7 @@ private Ref readRef(final TreeMap<String, Ref> avail,
 					r = avail.get(p);
 				if (r != null) {
 					r = new Ref(loose(r), name, r.getObjectId(), r
-							.getPeeledObjectId());
+							.getPeeledObjectId(), true);
 					avail.put(name, r);
 				}
 				return r;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
index 54dd581..a4f8961 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
@@ -438,7 +438,7 @@ private void readPackedRefsImpl(final Map<String, Ref> avail,
 					throw new TransportException("Peeled line before ref.");
 				final ObjectId id = ObjectId.fromString(line + 1);
 				last = new Ref(Ref.Storage.PACKED, last.getName(), last
-						.getObjectId(), id);
+						.getObjectId(), id, true);
 				avail.put(last.getName(), last);
 				continue;
 			}
-- 
1.6.0.3.640.g6331a.dirty

^ permalink raw reply related

* [EGIT PATCH 5/7 v3] Add a method to get refs by object Id
From: Robin Rosenberg @ 2008-11-14 23:24 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226705099-18066-4-git-send-email-robin.rosenberg@dewire.com>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../src/org/spearce/jgit/lib/Repository.java       |   30 ++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 4d6e6fd..5088150 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -47,10 +47,13 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Vector;
 
 import org.spearce.jgit.errors.IncorrectObjectTypeException;
@@ -952,6 +955,33 @@ public Ref peel(final Ref ref) {
 	}
 
 	/**
+	 * @return a map with all objects referenced by a peeled ref.
+	 */
+	public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId() {
+		Map<String, Ref> allRefs = getAllRefs();
+		Map<AnyObjectId, Set<Ref>> ret = new HashMap<AnyObjectId, Set<Ref>>(allRefs.size());
+		for (Ref ref : allRefs.values()) {
+			if (!ref.isPeeled())
+				ref = peel(ref);
+			AnyObjectId target = ref.getPeeledObjectId();
+			if (target == null)
+				target = ref.getObjectId();
+			// We assume most Sets here are singletons
+			Set<Ref> oset = ret.put(target, Collections.singleton(ref));
+			if (oset != null) {
+				// that was not the case (rare)
+				if (oset.size() == 1) {
+					// Was a read-only singleton, we must copy to a new Set
+					oset = new HashSet<Ref>(oset);
+				}
+				ret.put(target, oset);
+				oset.add(ref);
+			}
+		}
+		return ret;
+	}
+
+	/**
 	 * @return true if HEAD points to a StGit patch.
 	 */
 	public boolean isStGitMode() {
-- 
1.6.0.3.640.g6331a.dirty

^ permalink raw reply related

* [EGIT PATCH 3/7 v3] Test the origName part of the key vs the ref itself
From: Robin Rosenberg @ 2008-11-14 23:24 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226705099-18066-2-git-send-email-robin.rosenberg@dewire.com>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../tst/org/spearce/jgit/lib/RefUpdateTest.java    |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java
index 6e2cfa8..12f9ada 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefUpdateTest.java
@@ -39,6 +39,8 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import org.spearce.jgit.lib.RefUpdate.Result;
 
@@ -127,4 +129,12 @@ public void testDeleteEmptyDirs() throws IOException {
 	private void assertExists(final boolean expected, final String name) {
 		assertEquals(expected, new File(db.getDirectory(), name).exists());
 	}
+
+	public void testRefKeySameAsOrigName() {
+		Map<String, Ref> allRefs = db.getAllRefs();
+		for (Entry<String, Ref> e : allRefs.entrySet()) {
+			assertEquals(e.getKey(), e.getValue().getOrigName());
+
+		}
+	}
 }
-- 
1.6.0.3.640.g6331a.dirty

^ permalink raw reply related

* [EGIT PATCH 2/7 v3] Keep original ref name when reading refs
From: Robin Rosenberg @ 2008-11-14 23:24 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <1226705099-18066-1-git-send-email-robin.rosenberg@dewire.com>

We want to know the original name of refs, not just the target name.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java |   63 +++++++++++++++++++-
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   45 +++++++++-----
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   14 ++---
 3 files changed, 94 insertions(+), 28 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
index db94875..2f102af 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Ref.java
@@ -43,6 +43,11 @@
  * A ref in Git is (more or less) a variable that holds a single object
  * identifier. The object identifier can be any valid Git object (blob, tree,
  * commit, annotated tag, ...).
+ * <p>
+ * The ref name has the attributes of the ref that was asked for as well as
+ * the ref it was resolved to for symbolic refs plus the object id it points
+ * to and (for tags) the peeled target object id, i.e. the tag resolved
+ * recursively until a non-tag object is referenced.
  */
 public class Ref {
 	/** Location where a {@link Ref} is stored. */
@@ -119,19 +124,24 @@ public boolean isPacked() {
 
 	private ObjectId peeledObjectId;
 
+	private final String origName;
+
 	/**
 	 * Create a new ref pairing.
 	 * 
 	 * @param st
 	 *            method used to store this ref.
+	 * @param origName
+	 *            The name used to resolve this ref
 	 * @param refName
 	 *            name of this ref.
 	 * @param id
 	 *            current value of the ref. May be null to indicate a ref that
 	 *            does not exist yet.
 	 */
-	public Ref(final Storage st, final String refName, final ObjectId id) {
+	public Ref(final Storage st, final String origName, final String refName, final ObjectId id) {
 		storage = st;
+		this.origName = origName;
 		name = refName;
 		objectId = id;
 	}
@@ -146,19 +156,56 @@ public Ref(final Storage st, final String refName, final ObjectId id) {
 	 * @param id
 	 *            current value of the ref. May be null to indicate a ref that
 	 *            does not exist yet.
+	 */
+	public Ref(final Storage st, final String refName, final ObjectId id) {
+		this(st, refName, refName, id);
+	}
+
+	/**
+	 * Create a new ref pairing.
+	 * 
+	 * @param st
+	 *            method used to store this ref.
+	 * @param origName
+	 *            The name used to resolve this ref
+	 * @param refName
+	 *            name of this ref.
+	 * @param id
+	 *            current value of the ref. May be null to indicate a ref that
+	 *            does not exist yet.
 	 * @param peel
 	 *            peeled value of the ref's tag. May be null if this is not a
 	 *            tag or the peeled value is not known.
 	 */
-	public Ref(final Storage st, final String refName, final ObjectId id,
+	public Ref(final Storage st, final String origName, final String refName, final ObjectId id,
 			final ObjectId peel) {
 		storage = st;
+		this.origName = origName;
 		name = refName;
 		objectId = id;
 		peeledObjectId = peel;
 	}
 
 	/**
+	 * Create a new ref pairing.
+	 * 
+	 * @param st
+	 *            method used to store this ref.
+	 * @param refName
+	 *            name of this ref.
+	 * @param id
+	 *            current value of the ref. May be null to indicate a ref that
+	 *            does not exist yet.
+	 * @param peel
+	 *            peeled value of the ref's tag. May be null if this is not a
+	 *            tag or the peeled value is not known.
+	 */
+	public Ref(final Storage st, final String refName, final ObjectId id,
+			final ObjectId peel) {
+		this(st, refName, refName, id, peel);
+	}
+
+	/**
 	 * What this ref is called within the repository.
 	 * 
 	 * @return name of this ref.
@@ -168,6 +215,13 @@ public String getName() {
 	}
 
 	/**
+	 * @return the originally resolved name
+	 */
+	public String getOrigName() {
+		return origName;
+	}
+
+	/**
 	 * Cached value of this ref.
 	 * 
 	 * @return the value of this ref at the last time we read it.
@@ -200,6 +254,9 @@ public Storage getStorage() {
 	}
 
 	public String toString() {
-		return "Ref[" + name + "=" + ObjectId.toString(getObjectId()) + "]";
+		String o = "";
+		if (!origName.equals(name))
+			o = "(" + origName + ")";
+		return "Ref[" + o + name + "=" + ObjectId.toString(getObjectId()) + "]";
 	}
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 5c1f060..5a1b85f 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -51,6 +51,7 @@
 import java.util.Map;
 
 import org.spearce.jgit.errors.ObjectWritingException;
+import org.spearce.jgit.lib.Ref.Storage;
 import org.spearce.jgit.util.FS;
 import org.spearce.jgit.util.NB;
 
@@ -135,8 +136,8 @@ RefUpdate newUpdate(final String name) throws IOException {
 		return new RefUpdate(this, r, fileForRef(r.getName()));
 	}
 
-	void stored(final String name, final ObjectId id, final long time) {
-		looseRefs.put(name, new Ref(Ref.Storage.LOOSE, name, id));
+	void stored(final String origName, final String name, final ObjectId id, final long time) {
+		looseRefs.put(name, new Ref(Ref.Storage.LOOSE, origName, name, id));
 		looseRefsMTime.put(name, time);
 		setModified();
 		db.fireRefsMaybeChanged();
@@ -222,12 +223,12 @@ private void readLooseRefs(final Map<String, Ref> avail,
 			final String entName = ent.getName();
 			if (".".equals(entName) || "..".equals(entName))
 				continue;
-			readOneLooseRef(avail, prefix + entName, ent);
+			readOneLooseRef(avail, prefix + entName, prefix + entName, ent);
 		}
 	}
 
 	private void readOneLooseRef(final Map<String, Ref> avail,
-			final String refName, final File ent) {
+			final String origName, final String refName, final File ent) {
 		// Unchanged and cached? Don't read it again.
 		//
 		Ref ref = looseRefs.get(refName);
@@ -270,7 +271,7 @@ private void readOneLooseRef(final Map<String, Ref> avail,
 					return;
 				}
 
-				ref = new Ref(Ref.Storage.LOOSE, refName, id);
+				ref = new Ref(Ref.Storage.LOOSE, origName, refName, id);
 				looseRefs.put(ref.getName(), ref);
 				looseRefsMTime.put(ref.getName(), ent.lastModified());
 				avail.put(ref.getName(), ref);
@@ -293,27 +294,35 @@ private File fileForRef(final String name) {
 		return new File(gitDir, name);
 	}
 
-	private Ref readRefBasic(final String name, final int depth)
+	private Ref readRefBasic(final String name, final int depth) throws IOException {
+		return readRefBasic(name, name, depth);
+	}
+
+	private Ref readRefBasic(final String origName, final String name, final int depth)
 			throws IOException {
 		// Prefer loose ref to packed ref as the loose
 		// file can be more up-to-date than a packed one.
 		//
-		Ref ref = looseRefs.get(name);
+		Ref ref = looseRefs.get(origName);
 		final File loose = fileForRef(name);
 		final long mtime = loose.lastModified();
 		if (ref != null) {
 			Long cachedlastModified = looseRefsMTime.get(name);
 			if (cachedlastModified != null && cachedlastModified == mtime)
 				return ref;
-			looseRefs.remove(name);
-			looseRefsMTime.remove(name);
+			looseRefs.remove(origName);
+			looseRefsMTime.remove(origName);
 		}
 
 		if (mtime == 0) {
 			// If last modified is 0 the file does not exist.
 			// Try packed cache.
 			//
-			return packedRefs.get(name);
+			ref = packedRefs.get(name);
+			if (ref != null)
+				if (!ref.getOrigName().equals(origName))
+					ref = new Ref(Storage.LOOSE_PACKED, origName, name, ref.getObjectId());
+			return ref;
 		}
 
 		final String line;
@@ -324,7 +333,7 @@ private Ref readRefBasic(final String name, final int depth)
 		}
 
 		if (line == null || line.length() == 0)
-			return new Ref(Ref.Storage.LOOSE, name, null);
+			return new Ref(Ref.Storage.LOOSE, origName, name, null);
 
 		if (line.startsWith("ref: ")) {
 			if (depth >= 5) {
@@ -333,12 +342,16 @@ private Ref readRefBasic(final String name, final int depth)
 			}
 
 			final String target = line.substring("ref: ".length());
-			final Ref r = readRefBasic(target, depth + 1);
+			Ref r = readRefBasic(target, target, depth + 1);
 			Long cachedMtime = looseRefsMTime.get(name);
 			if (cachedMtime != null && cachedMtime != mtime)
 				setModified();
 			looseRefsMTime.put(name, mtime);
-			return r != null ? r : new Ref(Ref.Storage.LOOSE, target, null);
+			if (r == null)
+				return new Ref(Ref.Storage.LOOSE, origName, target, null);
+			if (!origName.equals(r.getName()))
+				r = new Ref(Ref.Storage.LOOSE_PACKED, origName, r.getName(), r.getObjectId(), r.getPeeledObjectId());
+			return r; 
 		}
 
 		setModified();
@@ -350,7 +363,7 @@ private Ref readRefBasic(final String name, final int depth)
 			throw new IOException("Not a ref: " + name + ": " + line);
 		}
 
-		ref = new Ref(Ref.Storage.LOOSE, name, id);
+		ref = new Ref(Ref.Storage.LOOSE, origName, name, id);
 		looseRefs.put(name, ref);
 		looseRefsMTime.put(name, mtime);
 		return ref;
@@ -384,7 +397,7 @@ private void refreshPackedRefs() {
 
 						final ObjectId id = ObjectId.fromString(p.substring(1));
 						last = new Ref(Ref.Storage.PACKED, last.getName(), last
-								.getObjectId(), id);
+								.getName(), last.getObjectId(), id);
 						newPackedRefs.put(last.getName(), last);
 						continue;
 					}
@@ -392,7 +405,7 @@ private void refreshPackedRefs() {
 					final int sp = p.indexOf(' ');
 					final ObjectId id = ObjectId.fromString(p.substring(0, sp));
 					final String name = new String(p.substring(sp + 1));
-					last = new Ref(Ref.Storage.PACKED, name, id);
+					last = new Ref(Ref.Storage.PACKED, name, name, id);
 					newPackedRefs.put(last.getName(), last);
 				}
 			} finally {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 86b44c5..235c2fd 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -131,9 +131,6 @@
 	/** Repository the ref is stored in. */
 	private final RefDatabase db;
 
-	/** Name of the ref. */
-	private final String name;
-
 	/** Location of the loose file holding the value of this ref. */
 	private final File looseFile;
 
@@ -160,7 +157,6 @@
 	RefUpdate(final RefDatabase r, final Ref ref, final File f) {
 		db = r;
 		this.ref = ref;
-		name = ref.getName();
 		oldValue = ref.getObjectId();
 		looseFile = f;
 	}
@@ -171,7 +167,7 @@ RefUpdate(final RefDatabase r, final Ref ref, final File f) {
 	 * @return name of this ref.
 	 */
 	public String getName() {
-		return name;
+		return ref.getName();
 	}
 
 	/**
@@ -349,9 +345,9 @@ public Result delete() throws IOException {
 	 * @throws IOException
 	 */
 	public Result delete(final RevWalk walk) throws IOException {
-		if (name.startsWith(Constants.R_HEADS)) {
+		if (getName().startsWith(Constants.R_HEADS)) {
 			final Ref head = db.readRef(Constants.HEAD);
-			if (head != null && name.equals(head.getName()))
+			if (head != null && getName().equals(head.getName()))
 				return Result.REJECTED_CURRENT_BRANCH;
 		}
 
@@ -373,7 +369,7 @@ private Result updateImpl(final RevWalk walk, final Store store)
 		if (!lock.lock())
 			return Result.LOCK_FAILURE;
 		try {
-			oldValue = db.idOf(name);
+			oldValue = db.idOf(getName());
 			if (oldValue == null)
 				return store.store(lock, Result.NEW);
 
@@ -428,7 +424,7 @@ else if (status == Result.NEW)
 				getName());
 		if (!lock.commit())
 			return Result.LOCK_FAILURE;
-		db.stored(name, newValue, lock.getCommitLastModified());
+		db.stored(this.ref.getOrigName(),  ref.getName(), newValue, lock.getCommitLastModified());
 		return status;
 	}
 
-- 
1.6.0.3.640.g6331a.dirty

^ permalink raw reply related

* [EGIT PATCH 1/7 v3] Add constant for "refs/"
From: Robin Rosenberg @ 2008-11-14 23:24 UTC (permalink / raw)
  To: spearce; +Cc: git, Robin Rosenberg
In-Reply-To: <20081111183248.GR2932@spearce.org>

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
 .../src/org/spearce/jgit/lib/Constants.java        |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

Here's an update after considering Shawn's comments. 1,2,3 are just reordered.
No 4 and 5 are changed. For patch no 6 and 7 use the ones from the previous
batch.

-- robin

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
index f316881..9613d07 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
@@ -216,6 +216,9 @@
 	/** Prefix for tag refs */
 	public static final String R_TAGS = "refs/tags/";
 
+	/** Prefix for any ref */
+	public static final String R_REFS = "refs/";
+
 	/** Logs folder name */
 	public static final String LOGS = "logs";
 
-- 
1.6.0.3.640.g6331a.dirty

^ permalink raw reply related

* Re: git to libgit2 code relicensing
From: Linus Torvalds @ 2008-11-14 23:13 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Git Mailing List
In-Reply-To: <491DE6CC.6060201@op5.se>



On Fri, 14 Nov 2008, Andreas Ericsson wrote:
> 
> The license decided for libgit2 is "GPL with gcc exception".

What's the exact language? 

I'm likely ok with GPLv2 + libgcc-like exception, but I'd like to see the 
exact one. I haven't followed the discussions much..

		Linus

^ permalink raw reply

* Re: hosting git on a nfs
From: Linus Torvalds @ 2008-11-14 23:10 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Brandon Casey, James Pickens, Bruce Fields, Git Mailing List
In-Reply-To: <7v63mq9iao.fsf@gitster.siamese.dyndns.org>



On Fri, 14 Nov 2008, Junio C Hamano wrote:
> 
> If you have 1000 files in a single directory, do you still want 2 threads
> following the "1/500" rule, or they would compete reading the same
> directory and using a single thread is better off?

Well, first off, the "single directory" thing is really a Linux kernel 
deficiency, and it's entirely possible that it doesn't even exist on other 
systems. Linux has a very special directory cache (dcache) model that is 
pretty unique - it's part of why cached 'lstat()' calls are so cheap on 
Linux - but it is also part of the reason for why we serialize lookups 
when we do miss in the cache (*).

Secondly, anybody who has a thousand tracked files in a single directory 
can damn well blame themselves for being stupid. So I don't think it's a 
case that is worth worrying too much about. Git will slow down for that 
kind of situation for other reasons (ie a lot of the tree pruning 
optimization won't work for projects that have large flat directories).

So i wouldn't worry about it. That said, with the second patch, we default 
to having people enable this explicitly, so it's something that people can 
decide on their own.

			Linus

(*) That said - the Linux dcache consistency is just _one_ reason why we 
serialize lookups. I would not be in the least surprised if other OS's 
have the exact same issue. I'd love to fix it in Linux, but quiet 
honestly, it has never actually come up before now, and we've literally 
worked on multi-threading the _cached_ case, not the uncached one.

^ 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