Git development
 help / color / mirror / Atom feed
* Re: [PATCH] README: fix broken mailing list archive link
From: Junio C Hamano @ 2013-01-29 18:10 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Git List
In-Reply-To: <CALkWK0mm8UKBHE=tbXsiS4Z_qBGcRUUsmCKHHFequRiQRL3hsw@mail.gmail.com>

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> Junio C Hamano wrote:
>> Ramkumar Ramachandra <artagnon@gmail.com> writes:
>>
>>> marc.theaimsgroup.com does not exist anymore, so replace it
>>> with a link to the archive on GMane.
>>
>> I think it has been at http://marc.info/?l=git for some time.
>
> Isn't GMane what all of us refer to on the list though?

Then your original log message is wrong, no?  You earlier said that
we should replace it because marc no longer exists.  Now you are
saying we replace it because we prefer gmane.

I do not mind listing both, but I think we should limit the
enumeration to the minimum and let "and other archival sites" cover
the rest.

^ permalink raw reply

* Re: [PATCH 4/6] introduce a commit metapack
From: Junio C Hamano @ 2013-01-29 18:08 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Duy Nguyen, Shawn O. Pearce
In-Reply-To: <7vy5fbq48t.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> I am torn on this one.
>
> These cached properties of a single commit will not change no matter
> which pack it appears in, and it feels logically wrong, especially
> when you record these object names in the full SHA-1 form, to tie a
> "commit metapack" to a pack.  Logically there needs only one commit
> metapack that describes all the commits known to the repository when
> the metapack was created.
>
> In order to reduce the disk footprint and I/O cost, the future
> direction for this mechanism may want to point into an existing
> store of SHA-1 hashes with a shorter file offset, and the .idx file
> could be such a store, and in order to move in that direction, you
> cannot avoid tying a metapack to a pack.

Have you considered if we can extend the .idx format version 2
without actually having to bump the version number?  My quick
reading of check_packed_git_idx() tells me that we have a gap after
the "large offset table" that we can place extensions, but I may be
mistaken.  If we indeed can, then perhaps adding a series of

	4-byte "id" header
        4-byte extension length (or 8-byte)
        ... N-byte worth of extension data ...

followed by

	20-byte SHA-1 checksum of all the extension sections
	8-byte file offset to the first extension section

at that gap, immediately before the trailer of the .idx file written
by git_SHA1_Final(), in a way similar to the index extension is done
may give us a natural way to deal with this.  The reader can first
read the offset recorded at the tail, checking if the offset is
plausible because it may not exist, the check the extension section
checksum, to see if the file has extension, or the file just ends
with the large offset table and the 28 bytes it tried to were from
the entries near the end of the large offset table.

If that is not worth attempting, perhaps we may still want to store
this as an optional extended section and bump the .idx format
version.

Then it will be very natural for the extension data that store the
commit metainfo to name objects in the pack the .idx file describes
by the offset in the SHA-1 table.

As we always say, .idx is a local cache and bumping its version is
not a huge headache compared to other longer term storage items.

^ permalink raw reply

* Re: [PATCH] README: fix broken mailing list archive link
From: Ramkumar Ramachandra @ 2013-01-29 17:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git List
In-Reply-To: <7v622grlj6.fsf@alter.siamese.dyndns.org>

Junio C Hamano wrote:
> Ramkumar Ramachandra <artagnon@gmail.com> writes:
>
>> marc.theaimsgroup.com does not exist anymore, so replace it
>> with a link to the archive on GMane.
>
> I think it has been at http://marc.info/?l=git for some time.

Isn't GMane what all of us refer to on the list though?

^ permalink raw reply

* Re: [PATCH 4/6] introduce a commit metapack
From: Junio C Hamano @ 2013-01-29 17:38 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Duy Nguyen, Shawn O. Pearce
In-Reply-To: <20130129091610.GD9999@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> +int commit_metapack(unsigned char *sha1,
> +		    uint32_t *timestamp,
> +		    unsigned char **tree,
> +		    unsigned char **parent1,
> +		    unsigned char **parent2)
> +{
> +	struct commit_metapack *p;
> +
> +	prepare_commit_metapacks();
> +	for (p = commit_metapacks; p; p = p->next) {
> +		unsigned char *data;
> +		int pos = sha1_entry_pos(p->index, 20, 0, 0, p->nr, p->nr, sha1);

This is a tangent, but isn't it about time to rip out the check for
GIT_USE_LOOKUP in find_pack_entry_one(), I wonder.

> +	prepare_commit_metapacks();
> +	for (p = commit_metapacks; p; p = p->next) {
> +		unsigned char *data;
> +		int pos = sha1_entry_pos(p->index, 20, 0, 0, p->nr, p->nr, sha1);
> +		if (pos < 0)
> +			continue;
> +
> +		/* timestamp(4) + tree(20) + parents(40) */
> +		data = p->data + 64 * pos;
> +		*timestamp = *(uint32_t *)data;
> +		*timestamp = ntohl(*timestamp);
> +		data += 4;
> +		*tree = data;
> +		data += 20;
> +		*parent1 = data;
> +		data += 20;
> +		*parent2 = data;
> +
> +		return 0;
> +	}
> +
> +	return -1;
> +}

I am torn on this one.

These cached properties of a single commit will not change no matter
which pack it appears in, and it feels logically wrong, especially
when you record these object names in the full SHA-1 form, to tie a
"commit metapack" to a pack.  Logically there needs only one commit
metapack that describes all the commits known to the repository when
the metapack was created.

In order to reduce the disk footprint and I/O cost, the future
direction for this mechanism may want to point into an existing
store of SHA-1 hashes with a shorter file offset, and the .idx file
could be such a store, and in order to move in that direction, you
cannot avoid tying a metapack to a pack.

> +static void get_commits(struct metapack_writer *mw,
> +			const unsigned char *sha1,
> +			void *data)
> +{
> +	struct commit_list ***tail = data;
> +	enum object_type type = sha1_object_info(sha1, NULL);
> +	struct commit *c;
> +
> +	if (type != OBJ_COMMIT)
> +		return;
> +
> +	c = lookup_commit(sha1);
> +	if (!c || parse_commit(c))
> +		die("unable to read commit %s", sha1_to_hex(sha1));
> +
> +	/*
> +	 * Our fixed-size parent list cannot represent root commits, nor
> +	 * octopus merges. Just skip those commits, as we can fallback
> +	 * in those rare cases to reading the actual commit object.
> +	 */
> +	if (!c->parents ||
> +	    (c->parents && c->parents->next && c->parents->next->next))
> +		return;
> +
> +	*tail = &commit_list_insert(c, *tail)->next;
> +}

It feels somewhat wasteful to:

 - use commit_list for this, rather than an array of commit
   objects.  If you have a rough estimate of the number of commits
   in the pack, you could just preallocate a single array and use
   ALLOC_GROW() on it, no?

 - iterate over the .idx file and run sha1_object_info() and
   parse_commit() on many objects in the SHA-1 order.  Iterating in
   the way builtin/pack-objects.c::get_object_details() does avoids
   jumping around in existing packfiles, which may be more
   efficient, no?

> +void commit_metapack_write(const char *idx)
> +{
> +	struct metapack_writer mw;
> +	struct commit_list *commits = NULL, *p;
> +	struct commit_list **tail = &commits;
> +	uint32_t nr = 0;
> +
> +	metapack_writer_init(&mw, idx, "commits", 1);
> +
> +	/* Figure out how many eligible commits we've got in this pack. */
> +	metapack_writer_foreach(&mw, get_commits, &tail);
> +	for (p = commits; p; p = p->next)
> +		nr++;

^ permalink raw reply

* Re: [PATCH 3/6] introduce pack metadata cache files
From: Junio C Hamano @ 2013-01-29 17:35 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Duy Nguyen, Shawn O. Pearce
In-Reply-To: <20130129091555.GC9999@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> +static void write_meta_header(struct metapack_writer *mw, const char *id,
> +			      uint32_t version)
> +{
> +	version = htonl(version);
> +
> +	sha1write(mw->out, "META", 4);
> +	sha1write(mw->out, "\0\0\0\1", 4);
> +	sha1write(mw->out, mw->pack->sha1, 20);
> +	sha1write(mw->out, id, 4);
> +	sha1write(mw->out, &version, 4);
> +}

It seems that you are very close to actually having a plumbing that
could also do the pack .idx files.  Until/unless that can be done, I
am not sure how much benefit we would be getting from a file format
that records a subtype "id" and a generic "META" type, instead of
just a single "id" as the type ehader.  But it is OK to use 8 extra
bytes if we can potentially gain something later.

Shouldn't id be validated with at least something like

	if (strlen(id) < 3)
		die("Bad id: %s", id);

to catch a call

	write_meta_header(&mw, "me", 47);

that will stuff 'm', 'e', NUL and the garbage the compiler/linker
combo has placed after that constant string in the 4-byte id field?

> +void metapack_writer_init(struct metapack_writer *mw,
> +			  const char *pack_idx,
> +			  const char *name,
> +			  int version)
> +{
> +	struct strbuf path = STRBUF_INIT;
> +
> +	memset(mw, 0, sizeof(*mw));
> +
> +	mw->pack = add_packed_git(pack_idx, strlen(pack_idx), 1);
> +	if (!mw->pack || open_pack_index(mw->pack))
> +		die("unable to open packfile '%s'", pack_idx);
> +
> +	strbuf_addstr(&path, pack_idx);
> +	strbuf_chompstr(&path, ".idx");
> +	strbuf_addch(&path, '.');
> +	strbuf_addstr(&path, name);

Your chompstr() does not even validate if the given name ends with
".idx", so this sounds like a glorified way to say

	strbuf_splice(&path, path->len - strlen("idx"), strlen("idx"),
			 name, strlen(name));

to me.

> +	mw->path = strbuf_detach(&path, NULL);
> +
> +	mw->out = create_meta_tmp();
> +	write_meta_header(mw, name, version);
> +}
> +
> +void metapack_writer_finish(struct metapack_writer *mw)
> +{
> +	const char *tmp = mw->out->name;
> +
> +	sha1close(mw->out, NULL, CSUM_FSYNC);
> +	if (rename(tmp, mw->path))
> +		die_errno("unable to rename temporary metapack file");

Who is responsible for running adjust_shared_perm()?  The caller, or
this function?

^ permalink raw reply

* Re: [PATCH v2 0/4] Auto-generate mergetool lists
From: John Keeping @ 2013-01-29 16:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Joachim Schmitz, git
In-Reply-To: <7vsj5krmng.fsf@alter.siamese.dyndns.org>

On Tue, Jan 29, 2013 at 08:15:15AM -0800, Junio C Hamano wrote:
> With any backend that is non-trivial, it would not be unusual for
> the *tool.cmd to look like:
> 
>      [mergetool]
>      	mytool = sh -c '
>         	... some massaging to prepare the command line
>                 ... to run the real tool backend comes here, and
>      		... then ...
>                 my_real_tool $arg1 $arg2 ...
> 	'
> 
> and you will end up detecting the presence of the shell, which is
> not very useful.
> 
> I think it is perfectly fine to say "you configured it, so it must
> exist; it may fail when we try to run it but it is your problem".
> It is simpler to explain and requires one less eval.

I think you're right.  The even worse case from this point of view is if
you configure it as:

    [mergetool]
        mytool = 'f() {
            ... code to actually run the tool here ...
        }; f $BASE $REMOTE $LOCAL $MERGED'

which results in a false "unavailable" rather than just a useless check.


John

^ permalink raw reply

* Re: [PATCH] README: fix broken mailing list archive link
From: Junio C Hamano @ 2013-01-29 16:39 UTC (permalink / raw)
  To: Ramkumar Ramachandra; +Cc: Git List
In-Reply-To: <1359456039-20562-1-git-send-email-artagnon@gmail.com>

Ramkumar Ramachandra <artagnon@gmail.com> writes:

> marc.theaimsgroup.com does not exist anymore, so replace it
> with a link to the archive on GMane.

I think it has been at http://marc.info/?l=git for some time.

^ permalink raw reply

* Re: [RFC] The design of new pathspec features
From: Junio C Hamano @ 2013-01-29 16:27 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git
In-Reply-To: <7vk3qwrmea.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Duy Nguyen <pclouds@gmail.com> writes:
>
>> On Tue, Jan 29, 2013 at 11:35 AM, Duy Nguyen <pclouds@gmail.com> wrote:
>>> :(glob) magic
>>> =============
>>>
>>> This magic is for people who want globbing. However, it does _not_ use
>>> the same matching mechanism the non-magic pathspec does today. It uses
>>> wildmatch(WM_PATHNAME), which basically means '*' does not match
>>> slashes and "**" does.
>>>
>>> Global option --glob-pathspecs is added to add :(glob) to all
>>> pathspec. :(literal) magic overrides this global option.
>>
>> I forgot one thing. The current pathspec behavior, the pattern "[a-z]"
>> would match a file named "[a-z]" (iow, wildcards are also considered
>> literal characters).
>
> That sounds like a blatant bug to me (unless you are talking about
> "literal" case).  We should fix it before we include it in any
> released version, I think.

Ah, no, I misread what you meant.

Yes, historically when matching a path with a pattern "a/b[c-d]/e",
we tried to first literally match the path with it (this allows the
path "a/b[c-d]/e" to match with the pattern), and if it did not
match, used fnmatch(3) to allow "a/bc/e" to also match.  This was an
ugly hack to cope with the possiblity that such a funny path is
actually used in projects.

With :(literal) magic and its friends you are working into the
system, the hack should disappear at the same time when you stop
running fnmatch(3) without FNM_PATHNAME.  That should happen no
later than Git 2.0.

But until then, we should keep matching both paths "a/bc/e" and
"a/b[c-d]/e" with pattern "a/b[c-d]/e", for backward compatibility.

Sorry about the earlier confusion.

^ permalink raw reply

* Re: [RFC] The design of new pathspec features
From: Junio C Hamano @ 2013-01-29 16:20 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git
In-Reply-To: <CACsJy8A5VJ4EchbeFEC5ikLYgHze47_xyLTtgH=kqVpP15Hogw@mail.gmail.com>

Duy Nguyen <pclouds@gmail.com> writes:

> On Tue, Jan 29, 2013 at 11:35 AM, Duy Nguyen <pclouds@gmail.com> wrote:
>> :(glob) magic
>> =============
>>
>> This magic is for people who want globbing. However, it does _not_ use
>> the same matching mechanism the non-magic pathspec does today. It uses
>> wildmatch(WM_PATHNAME), which basically means '*' does not match
>> slashes and "**" does.
>>
>> Global option --glob-pathspecs is added to add :(glob) to all
>> pathspec. :(literal) magic overrides this global option.
>
> I forgot one thing. The current pathspec behavior, the pattern "[a-z]"
> would match a file named "[a-z]" (iow, wildcards are also considered
> literal characters).

That sounds like a blatant bug to me (unless you are talking about
"literal" case).  We should fix it before we include it in any
released version, I think.

^ permalink raw reply

* Re: [PATCH] status: show branch name if possible in in-progress info
From: Junio C Hamano @ 2013-01-29 16:18 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Duy Nguyen, git
In-Reply-To: <vpqd2worv23.fsf@grenoble-inp.fr>

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> Not HEAD, but .git/rebase-merge/onto, i.e. the target of the rebase.
> Ideally, I would have loved to see "rebasing master on origin/master",
> but I do not think the target ref name is stored during rebase.

Perhaps do it with --format=%s then.  It often is useless to know
only the commit object name (or the branch name for that matter, as
you wouldn't know what exact commit the branch tip happens to have)
you are rebasing onto.

^ permalink raw reply

* Re: [PATCH v2 0/4] Auto-generate mergetool lists
From: Junio C Hamano @ 2013-01-29 16:15 UTC (permalink / raw)
  To: John Keeping; +Cc: Joachim Schmitz, git
In-Reply-To: <20130129120923.GE7498@serenity.lan>

John Keeping <john@keeping.me.uk> writes:

> On Tue, Jan 29, 2013 at 12:56:58PM +0100, Joachim Schmitz wrote:
>> John Keeping wrote:
>> > Currently I'm extracting the command word using:
>> >
>> >    cmd=$(eval -- "set -- $(git config mergetool.$tool.cmd); echo
>> > \"$1\"")
>> 
>> Shouldnt this work?
>> cmd=$((git config "mergetool.$tool.cmd" || git config "difftool.$tool.cmd") 
>> | awk '{print $1}')
>
> That doesn't handle paths with spaces in, whereas the eval in a subshell
> does:
>
>     $ cmd='"my command" $BASE $LOCAL $REMOTE'
>     $ echo "$cmd" | awk '{print $1}'
>     "my
>     $ ( eval -- "set -- $cmd; echo \"\$1\"" )
>     my command

I'd rather not to see you do any of the above.

With any backend that is non-trivial, it would not be unusual for
the *tool.cmd to look like:

     [mergetool]
     	mytool = sh -c '
        	... some massaging to prepare the command line
                ... to run the real tool backend comes here, and
     		... then ...
                my_real_tool $arg1 $arg2 ...
	'

and you will end up detecting the presence of the shell, which is
not very useful.

I think it is perfectly fine to say "you configured it, so it must
exist; it may fail when we try to run it but it is your problem".
It is simpler to explain and requires one less eval.

        
                

^ permalink raw reply

* Re: [PATCH 0/2] optimizing pack access on "read only" fetch repos
From: Junio C Hamano @ 2013-01-29 15:58 UTC (permalink / raw)
  To: Jeff King; +Cc: Shawn O. Pearce, git
In-Reply-To: <20130129082939.GB6396@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

>> I also wonder if we would be helped by another "repack" mode that
>> coalesces small packs into a single one with minimum overhead, and
>> run that often from "gc --auto", so that we do not end up having to
>> have 50 packfiles.
>> ...
>
> I'm not sure. If I understand you correctly, it would basically just be
> concatenating packs without trying to do delta compression between the
> objects which are ending up in the same pack. So it would save us from
> having to do (up to) 50 binary searches to find an object in a pack, but
> would not actually save us much space.

The point is not about space.  Disk is cheap, and it is not making
it any worse than what happens to your target audience, that is a
fetch-only repository with only "gc --auto" in it, where nobody
passes "-f" to "repack" to cause recomputation of delta.

What I was trying to seek was a way to reduce the runtime penalty we
pay every time we run git in such a repository.

 - Object look-up cost will become log2(50*n) from 50*log2(n), which
   is about 50/log2(50) improvement;

 - System resource cost we incur by having to keep 50 file
   descriptors open and maintaining 50 mmap windows will reduce by
   50 fold.

 - Anything else I missed?

> I would be interested to see the timing on how quick it is compared to a
> real repack,...

Yes, that is what I meant by "wonder if we would be helped by" ;-)

> But how do these somewhat mediocre concatenated packs get turned into
> real packs?

How do they get processed in a fetch-only repositories that
sometimes run "gc --auto" today?  By runninng "repack -a -d -f"
occasionally, perhaps?

At some point, you would need to run a repack that involves a real
object-graph traversal that feeds you the paths for objects to
obtain a reasonably compressed pack.  We can inspect existing packs
and guess a rough traversal order for commits, but for trees and
blobs, you cannot unify existing delta chains from multiple packs
effectively with data in the pack alone.

^ permalink raw reply

* Re: [RFC v2] git-multimail: a replacement for post-receive-email
From: Ævar Arnfjörð Bjarmason @ 2013-01-29 15:25 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: git discussion list, Andy Parkins, Sitaram Chamarty, Matthieu Moy,
	Junio C Hamano, Marc Branchaud, Chris Hiestand
In-Reply-To: <5104E738.602@alum.mit.edu>

On Sun, Jan 27, 2013 at 9:37 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> A while ago, I submitted an RFC for adding a new email notification
> script to "contrib" [1].  The reaction seemed favorable and it was
> suggested that the new script should replace post-receive-email rather
> than be added separately, ideally with some kind of migration support.

I just want to say since I think this thread hasn't been getting the
attention it deserves: I'm all for this. I've used git-multimail and
it's a joy to configure and extend compared to the existing hacky
shellscript.

I'm not running it at $work yet because I still need to write some
extensions for to port some of of our local hacks to the old
shellscript over.

I fully support replacing the existing mailing script with
git-multimail, it's better in every way, and unlike the current script
has an active maintainer.

^ permalink raw reply

* Re: [PATCH 0/2] optimizing pack access on "read only" fetch repos
From: Martin Fick @ 2013-01-29 15:25 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: Shawn O. Pearce, git
In-Reply-To: <20130129082939.GB6396@sigill.intra.peff.net>



Jeff King <peff@peff.net> wrote:

>On Sat, Jan 26, 2013 at 10:32:42PM -0800, Junio C Hamano wrote:
>
>> Both makes sense to me.
>> 
>> I also wonder if we would be helped by another "repack" mode that
>> coalesces small packs into a single one with minimum overhead, and
>> run that often from "gc --auto", so that we do not end up having to
>> have 50 packfiles.
>> 
>> When we have 2 or more small and young packs, we could:
>> 
>>  - iterate over idx files for these packs to enumerate the objects
>>    to be packed, replacing read_object_list_from_stdin() step;
>> 
>>  - always choose to copy the data we have in these existing packs,
>>    instead of doing a full prepare_pack(); and
>> 
>>  - use the order the objects appear in the original packs, bypassing
>>    compute_write_order().
>
>I'm not sure. If I understand you correctly, it would basically just be
>concatenating packs without trying to do delta compression between the
>objects which are ending up in the same pack. So it would save us from
>having to do (up to) 50 binary searches to find an object in a pack,
>but
>would not actually save us much space.
>
>I would be interested to see the timing on how quick it is compared to
>a
>real repack, as the I/O that happens during a repack is non-trivial
>(although if you are leaving aside the big "main" pack, then it is
>probably not bad).
>
>But how do these somewhat mediocre concatenated packs get turned into
>real packs? Pack-objects does not consider deltas between objects in
>the
>same pack. And when would you decide to make a real pack? How do you
>know you have 50 young and small packs, and not 50 mediocre coalesced
>packs?


If we are reconsidering repacking strategies, I would like to propose an approach that might be a more general improvement to repacking which would help in more situations. 

You could roll together any packs which are close in size, say within 50% of each other.  With this strategy you will end up with files which are spread out by size exponentially.  I implementated this strategy on top of the current gc script using keep files, it works fairly well:

https://gerrit-review.googlesource.com/#/c/35215/3/contrib/git-exproll.sh

This saves some time, but mostly it saves I/O when repacking regularly.  I suspect that if this strategy were used in core git that further optimizations could be made to also reduce the repack time, but I don't know enough about repacking to know?  We run it nightly on our servers, both write and read only mirrors. We us are a ratio of 5 currently to drastically reduce large repack file rollovers,

-Martin

^ permalink raw reply

* Re: Updating shared ref from remote helper, or fetch hook
From: Max Horn @ 2013-01-29 15:00 UTC (permalink / raw)
  To: Jed Brown; +Cc: git
In-Reply-To: <87ehh5lw9j.fsf@59A2.org>

Hi Jed, all,


On 28.01.2013, at 06:19, Jed Brown wrote:

> I'm working on an hg remote helper that uses git notes for the sha1
> revision, so that git users can more easily refer to specific commits
> when communicating with hg users.

For the record, I am also working on that very same thing; it is yet another git-remote-hg alternative, based on Felipe's code but with many improvements. You can find it here: <https://github.com/buchuki/gitifyhg>.

Anyway, back to Jed's (and also my) question:

>  Since there may be multiple
> concurrent fast-import streams, I write the notes to a private ref
> (refs/notes/hg-REMOTE), to be merged eventually using
> 
>  git notes --ref hg merge hg-REMOTE*
> 
> There will never be conflicts because each hg commit translates to a
> unique git commit, thus even if multiple concurrent remotes process the
> same commit, the corresponding note will match.
> 
> Unfortunately, I couldn't find a safe way to get this run after a fetch
> or clone.  Of course I can ask the user to arrange to have this command
> run, but it would be a better interface to have it run automatically
> since it is a natural responsibility of the remote helper.  Am I missing
> a way to do this or a viable alternative approach?

One idea we (well, Jed :-) had when brain storming about this was that perhaps one could (or even should?) (ab)use the "checkpoint" feature for that.

Basically, when the remote-helper is almost done with everything, issue a "checkpoint" command, to flush out everything we just imported to the HD. 

Then once this completed, we can perform the notes merge. The main remaining problem with that is: How would we know when the "checkpoint" actually completed? Any ideas?

Perhaps a way to do that would be to make use of the new "bidi-import" remote helper capability -- if I understand it right, then this effectively connects the fast-import stdout to the stdin of the remote helper. Thus, if one were to follow the "checkpoint" by a "progress" command, then by waiting for that progress command's output to appear back on stdin, the remote helper could determine whether the import succeeded, and perform finalization actions (like merging notes, as in our case).


Does that sound viable? Crazy? Anybody got better a idea?


Cheers,
Max

^ permalink raw reply

* [PATCH v2] status: show the branch name if possible in in-progress info
From: Nguyễn Thái Ngọc Duy @ 2013-01-29 14:58 UTC (permalink / raw)
  To: git; +Cc: Matthieu Moy, Nguyễn Thái Ngọc Duy
In-Reply-To: <1359461450-24456-1-git-send-email-pclouds@gmail.com>


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 - fix bisecting on detached HEAD
 - show onto sha-1 for rebase

 t/t7512-status-help.sh | 36 ++++++++++----------
 wt-status.c            | 91 ++++++++++++++++++++++++++++++++++++++++++++++----
 wt-status.h            |  2 ++
 3 files changed, 105 insertions(+), 24 deletions(-)

diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index b3f6eb9..67ece6b 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing branch '\''rebase_conflicts'\'' on '\''000106f'\''.
 	#   (fix conflicts and then run "git rebase --continue")
 	#   (use "git rebase --skip" to skip this patch)
 	#   (use "git rebase --abort" to check out the original branch)
@@ -102,7 +102,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' '
 	git add main.txt &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing branch '\''rebase_conflicts'\'' on '\''000106f'\''.
 	#   (all conflicts fixed: run "git rebase --continue")
 	#
 	# Changes to be committed:
@@ -133,7 +133,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '
 	test_must_fail git rebase -i rebase_i_conflicts &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''e0164e4'\''.
 	#   (fix conflicts and then run "git rebase --continue")
 	#   (use "git rebase --skip" to skip this patch)
 	#   (use "git rebase --abort" to check out the original branch)
@@ -158,7 +158,7 @@ test_expect_success 'status during rebase -i after resolving conflicts' '
 	git add main.txt &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''e0164e4'\''.
 	#   (all conflicts fixed: run "git rebase --continue")
 	#
 	# Changes to be committed:
@@ -185,7 +185,7 @@ test_expect_success 'status when rebasing -i in edit mode' '
 	git rebase -i HEAD~2 &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''f90e540'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -210,7 +210,7 @@ test_expect_success 'status when splitting a commit' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''19b175e'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -240,7 +240,7 @@ test_expect_success 'status after editing the last commit with --amend during a
 	git commit --amend -m "foo" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''dd030b9'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -269,7 +269,7 @@ test_expect_success 'status: (continue first edit) second edit' '
 	git rebase --continue &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -290,7 +290,7 @@ test_expect_success 'status: (continue first edit) second edit and split' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -316,7 +316,7 @@ test_expect_success 'status: (continue first edit) second edit and amend' '
 	git commit --amend -m "foo" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -337,7 +337,7 @@ test_expect_success 'status: (amend first edit) second edit' '
 	git rebase --continue &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -359,7 +359,7 @@ test_expect_success 'status: (amend first edit) second edit and split' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -386,7 +386,7 @@ test_expect_success 'status: (amend first edit) second edit and amend' '
 	git commit --amend -m "d" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -409,7 +409,7 @@ test_expect_success 'status: (split first edit) second edit' '
 	git rebase --continue &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -433,7 +433,7 @@ test_expect_success 'status: (split first edit) second edit and split' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -462,7 +462,7 @@ test_expect_success 'status: (split first edit) second edit and amend' '
 	git commit --amend -m "h" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''eb16a7e'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -558,7 +558,7 @@ test_expect_success 'status when bisecting' '
 	git bisect good one_bisect &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently bisecting.
+	# You are currently bisecting branch '\''bisect'\''.
 	#   (use "git bisect reset" to get back to the original branch)
 	#
 	nothing to commit (use -u to show untracked files)
@@ -580,7 +580,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing branch '\''statushints_disabled'\'' on '\''1d51a61'\''.
 	#
 	# Unmerged paths:
 	#	both modified:      main.txt
diff --git a/wt-status.c b/wt-status.c
index d7cfe8f..42fafd0 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -872,7 +872,14 @@ static void show_rebase_in_progress(struct wt_status *s,
 	struct stat st;
 
 	if (has_unmerged(s)) {
-		status_printf_ln(s, color, _("You are currently rebasing."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently rebasing branch '%s' on '%s'."),
+					 state->branch,
+					 state->onto);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently rebasing."));
 		if (advice_status_hints) {
 			status_printf_ln(s, color,
 				_("  (fix conflicts and then run \"git rebase --continue\")"));
@@ -882,17 +889,38 @@ static void show_rebase_in_progress(struct wt_status *s,
 				_("  (use \"git rebase --abort\" to check out the original branch)"));
 		}
 	} else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
-		status_printf_ln(s, color, _("You are currently rebasing."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently rebasing branch '%s' on '%s'."),
+					 state->branch,
+					 state->onto);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently rebasing."));
 		if (advice_status_hints)
 			status_printf_ln(s, color,
 				_("  (all conflicts fixed: run \"git rebase --continue\")"));
 	} else if (split_commit_in_progress(s)) {
-		status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently splitting a commit while rebasing branch '%s' on '%s'."),
+					 state->branch,
+					 state->onto);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently splitting a commit during a rebase."));
 		if (advice_status_hints)
 			status_printf_ln(s, color,
 				_("  (Once your working directory is clean, run \"git rebase --continue\")"));
 	} else {
-		status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently editing a commit while rebasing branch '%s' on '%s'."),
+					 state->branch,
+					 state->onto);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently editing a commit during a rebase."));
 		if (advice_status_hints && !s->amend) {
 			status_printf_ln(s, color,
 				_("  (use \"git commit --amend\" to amend the current commit)"));
@@ -923,16 +951,54 @@ static void show_bisect_in_progress(struct wt_status *s,
 				struct wt_status_state *state,
 				const char *color)
 {
-	status_printf_ln(s, color, _("You are currently bisecting."));
+	if (state->branch)
+		status_printf_ln(s, color,
+				 _("You are currently bisecting branch '%s'."),
+				 state->branch);
+	else
+		status_printf_ln(s, color,
+				 _("You are currently bisecting."));
 	if (advice_status_hints)
 		status_printf_ln(s, color,
 			_("  (use \"git bisect reset\" to get back to the original branch)"));
 	wt_status_print_trailer(s);
 }
 
+static void read_and_strip_branch(struct strbuf *sb,
+				  const char **branch,
+				  const char *path)
+{
+	unsigned char sha1[20];
+
+	strbuf_reset(sb);
+	if (strbuf_read_file(sb, git_path("%s", path), 0) <= 0)
+		return;
+
+	while (sb->len && sb->buf[sb->len - 1] == '\n')
+		strbuf_setlen(sb, sb->len - 1);
+	if (!sb->len)
+		return;
+	if (!prefixcmp(sb->buf, "refs/heads/"))
+		*branch = sb->buf + strlen("refs/heads/");
+	else if (!prefixcmp(sb->buf, "refs/"))
+		*branch = sb->buf;
+	else if (!get_sha1_hex(sb->buf, sha1)) {
+		const char *abbrev;
+		abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
+		strbuf_reset(sb);
+		strbuf_addstr(sb, abbrev);
+		*branch = sb->buf;
+	} else if (!strcmp(sb->buf, "detached HEAD")) /* rebase */
+		;
+	else			/* bisect */
+		*branch = sb->buf;
+}
+
 static void wt_status_print_state(struct wt_status *s)
 {
 	const char *state_color = color(WT_STATUS_HEADER, s);
+	struct strbuf branch = STRBUF_INIT;
+	struct strbuf onto = STRBUF_INIT;
 	struct wt_status_state state;
 	struct stat st;
 
@@ -947,17 +1013,28 @@ static void wt_status_print_state(struct wt_status *s)
 				state.am_empty_patch = 1;
 		} else {
 			state.rebase_in_progress = 1;
+			read_and_strip_branch(&branch, &state.branch,
+					      "rebase-apply/head-name");
+			read_and_strip_branch(&onto, &state.onto,
+					      "rebase-apply/onto");
 		}
 	} else if (!stat(git_path("rebase-merge"), &st)) {
 		if (!stat(git_path("rebase-merge/interactive"), &st))
 			state.rebase_interactive_in_progress = 1;
 		else
 			state.rebase_in_progress = 1;
+		read_and_strip_branch(&branch, &state.branch,
+				      "rebase-merge/head-name");
+		read_and_strip_branch(&onto, &state.onto,
+				      "rebase-merge/onto");
 	} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
 		state.cherry_pick_in_progress = 1;
 	}
-	if (!stat(git_path("BISECT_LOG"), &st))
+	if (!stat(git_path("BISECT_LOG"), &st)) {
 		state.bisect_in_progress = 1;
+		read_and_strip_branch(&branch, &state.branch,
+				      "BISECT_START");
+	}
 
 	if (state.merge_in_progress)
 		show_merge_in_progress(s, &state, state_color);
@@ -969,6 +1046,8 @@ static void wt_status_print_state(struct wt_status *s)
 		show_cherry_pick_in_progress(s, &state, state_color);
 	if (state.bisect_in_progress)
 		show_bisect_in_progress(s, &state, state_color);
+	strbuf_release(&branch);
+	strbuf_release(&onto);
 }
 
 void wt_status_print(struct wt_status *s)
diff --git a/wt-status.h b/wt-status.h
index 236b41f..81e1dcf 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -79,6 +79,8 @@ struct wt_status_state {
 	int rebase_interactive_in_progress;
 	int cherry_pick_in_progress;
 	int bisect_in_progress;
+	const char *branch;
+	const char *onto;
 };
 
 void wt_status_prepare(struct wt_status *s);
-- 
1.8.1.1.459.g5970e58

^ permalink raw reply related

* Re: [PATCH] status: show branch name if possible in in-progress info
From: Matthieu Moy @ 2013-01-29 13:13 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git
In-Reply-To: <CACsJy8DLdG9O+HaWS8u4n+imdaSZe=GrbYbPOhcMsYMWDq9NZw@mail.gmail.com>

Duy Nguyen <pclouds@gmail.com> writes:

> On Tue, Jan 29, 2013 at 7:31 PM, Matthieu Moy
> <Matthieu.Moy@grenoble-inp.fr> wrote:
>> I like the idea.
>>
>> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>>
>>> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
>>> index b3f6eb9..096ba6f 100755
>>> --- a/t/t7512-status-help.sh
>>> +++ b/t/t7512-status-help.sh
>>> @@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
>>>       test_must_fail git rebase HEAD^ --onto HEAD^^ &&
>>>       cat >expected <<-\EOF &&
>>>       # Not currently on any branch.
>>> -     # You are currently rebasing.
>>> +     # You are currently rebasing '\''rebase_conflicts'\''.
>>
>> Perhaps "rebasing *branch* 'rebase_conflicts'"
>
> Looks good. One minor thing, if the ref happens to be
> refs/somewhere-not-in-heads, should we still say "rebasing branch
> 'refs/...'" or just "rebasing 'refs/...'", or something else?

I think this should not happen, since HEAD can either point to a branch
or directly to a sha1 in normal conditions. But it doesn't harm to be
defensive, in case ...

>> Or even "rebasing branch 'rebase_conflicts' on <sha1sum>"
>
> <sha1sum> being SHA-1 of HEAD?

Not HEAD, but .git/rebase-merge/onto, i.e. the target of the rebase.
Ideally, I would have loved to see "rebasing master on origin/master",
but I do not think the target ref name is stored during rebase.

> Why would you need it?

The typical use-case is starting a rebase, do something else, come back
the day after and wonder wft. Which branch is being rebased is probably
the most useful, but the target may help too. But I can live
without ;-).

> In short version, not full SHA-1?

If you add it, the short one (long version would make overly long line
with limited use).

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: [PATCH] status: show branch name if possible in in-progress info
From: Duy Nguyen @ 2013-01-29 12:56 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: git
In-Reply-To: <vpqy5fcrwzq.fsf@grenoble-inp.fr>

On Tue, Jan 29, 2013 at 7:31 PM, Matthieu Moy
<Matthieu.Moy@grenoble-inp.fr> wrote:
> I like the idea.
>
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
>> index b3f6eb9..096ba6f 100755
>> --- a/t/t7512-status-help.sh
>> +++ b/t/t7512-status-help.sh
>> @@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
>>       test_must_fail git rebase HEAD^ --onto HEAD^^ &&
>>       cat >expected <<-\EOF &&
>>       # Not currently on any branch.
>> -     # You are currently rebasing.
>> +     # You are currently rebasing '\''rebase_conflicts'\''.
>
> Perhaps "rebasing *branch* 'rebase_conflicts'"

Looks good. One minor thing, if the ref happens to be
refs/somewhere-not-in-heads, should we still say "rebasing branch
'refs/...'" or just "rebasing 'refs/...'", or something else?

>
> Or even "rebasing branch 'rebase_conflicts' on <sha1sum>"

<sha1sum> being SHA-1 of HEAD? Why would you need it? In short
version, not full SHA-1?

> ?
>
>> @@ -923,7 +947,7 @@ static void show_bisect_in_progress(struct wt_status *s,
>>                               struct wt_status_state *state,
>>                               const char *color)
>>  {
>> -     status_printf_ln(s, color, _("You are currently bisecting."));
>> +     status_printf_ln(s, color, _("You are currently bisecting '%s'."), state->branch);
>>       if (advice_status_hints)
>>               status_printf_ln(s, color,
>>                       _("  (use \"git bisect reset\" to get back to the original branch)"));
>
> In the "rebase" case, you test state->branch for null-ness. Don't you
> need the same test here? (What happens if you start a bisect from a
> detached HEAD state?)

I did read git-bisect.sh. I did not think it allowed bisecting on
detached HEAD. A simple test just told me otherwise. Will update.
-- 
Duy

^ permalink raw reply

* Re: [PATCH] status: show branch name if possible in in-progress info
From: Matthieu Moy @ 2013-01-29 12:31 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1359461450-24456-1-git-send-email-pclouds@gmail.com>

I like the idea.

Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:

> diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
> index b3f6eb9..096ba6f 100755
> --- a/t/t7512-status-help.sh
> +++ b/t/t7512-status-help.sh
> @@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
>  	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
>  	cat >expected <<-\EOF &&
>  	# Not currently on any branch.
> -	# You are currently rebasing.
> +	# You are currently rebasing '\''rebase_conflicts'\''.

Perhaps "rebasing *branch* 'rebase_conflicts'"

Or even "rebasing branch 'rebase_conflicts' on <sha1sum>"

?

> @@ -923,7 +947,7 @@ static void show_bisect_in_progress(struct wt_status *s,
>  				struct wt_status_state *state,
>  				const char *color)
>  {
> -	status_printf_ln(s, color, _("You are currently bisecting."));
> +	status_printf_ln(s, color, _("You are currently bisecting '%s'."), state->branch);
>  	if (advice_status_hints)
>  		status_printf_ln(s, color,
>  			_("  (use \"git bisect reset\" to get back to the original branch)"));

In the "rebase" case, you test state->branch for null-ness. Don't you
need the same test here? (What happens if you start a bisect from a
detached HEAD state?)

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: [RFC] The design of new pathspec features
From: Duy Nguyen @ 2013-01-29 12:17 UTC (permalink / raw)
  To: git
In-Reply-To: <20130129043517.GA2878@duynguyen-vnpc.dek-tpc.internal>

On Tue, Jan 29, 2013 at 11:35 AM, Duy Nguyen <pclouds@gmail.com> wrote:
> :(glob) magic
> =============
>
> This magic is for people who want globbing. However, it does _not_ use
> the same matching mechanism the non-magic pathspec does today. It uses
> wildmatch(WM_PATHNAME), which basically means '*' does not match
> slashes and "**" does.
>
> Global option --glob-pathspecs is added to add :(glob) to all
> pathspec. :(literal) magic overrides this global option.

I forgot one thing. The current pathspec behavior, the pattern "[a-z]"
would match a file named "[a-z]" (iow, wildcards are also considered
literal characters). Do we want to keep this behavior in :(glob)? To
me it's a surprise factor and therefore not good. But common sense may
be different.
-- 
Duy

^ permalink raw reply

* [PATCH] branch: show (rebasing) or (bisecting) instead of (no branch) when possible
From: Nguyễn Thái Ngọc Duy @ 2013-01-29 12:12 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 In the spirit of status' in-progress info. I think showing this is
 more useful than "(no branch)". I tend to do "git br" more often than
 "git st" and this catches my eyes.

 builtin/branch.c            | 10 +++++++++-
 t/t6030-bisect-porcelain.sh |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 873f624..b0c5a20 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -557,7 +557,15 @@ static void show_detached(struct ref_list *ref_list)
 
 	if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
 		struct ref_item item;
-		item.name = xstrdup(_("(no branch)"));
+		struct stat st;
+		if ((!stat(git_path("rebase-apply"), &st) &&
+		     stat(git_path("rebase-apply/applying"), &st)) ||
+		    !stat(git_path("rebase-merge"), &st))
+			item.name = xstrdup(_("(rebasing)"));
+		else if (!stat(git_path("BISECT_LOG"), &st))
+			item.name = xstrdup(_("(bisecting)"));
+		else
+			item.name = xstrdup(_("(no branch)"));
 		item.width = utf8_strwidth(item.name);
 		item.kind = REF_LOCAL_BRANCH;
 		item.dest = NULL;
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 3e0e15f..bc21bc9 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -164,7 +164,7 @@ test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if
 	cp .git/BISECT_START saved &&
 	test_must_fail git bisect start $HASH4 foo -- &&
 	git branch > branch.output &&
-	test_i18ngrep "* (no branch)" branch.output > /dev/null &&
+	test_i18ngrep "* (bisecting)" branch.output > /dev/null &&
 	test_cmp saved .git/BISECT_START
 '
 test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' '
-- 
1.8.1.1.459.g5970e58

^ permalink raw reply related

* [PATCH] status: show branch name if possible in in-progress info
From: Nguyễn Thái Ngọc Duy @ 2013-01-29 12:10 UTC (permalink / raw)
  To: git; +Cc: Matthieu Moy, Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Seems like a good thing to do.

 t/t7512-status-help.sh | 36 +++++++++++++++----------------
 wt-status.c            | 58 ++++++++++++++++++++++++++++++++++++++++++--------
 wt-status.h            |  1 +
 3 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index b3f6eb9..096ba6f 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -76,7 +76,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing '\''rebase_conflicts'\''.
 	#   (fix conflicts and then run "git rebase --continue")
 	#   (use "git rebase --skip" to skip this patch)
 	#   (use "git rebase --abort" to check out the original branch)
@@ -102,7 +102,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' '
 	git add main.txt &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing '\''rebase_conflicts'\''.
 	#   (all conflicts fixed: run "git rebase --continue")
 	#
 	# Changes to be committed:
@@ -133,7 +133,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '
 	test_must_fail git rebase -i rebase_i_conflicts &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing '\''rebase_i_conflicts_second'\''.
 	#   (fix conflicts and then run "git rebase --continue")
 	#   (use "git rebase --skip" to skip this patch)
 	#   (use "git rebase --abort" to check out the original branch)
@@ -158,7 +158,7 @@ test_expect_success 'status during rebase -i after resolving conflicts' '
 	git add main.txt &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing '\''rebase_i_conflicts_second'\''.
 	#   (all conflicts fixed: run "git rebase --continue")
 	#
 	# Changes to be committed:
@@ -185,7 +185,7 @@ test_expect_success 'status when rebasing -i in edit mode' '
 	git rebase -i HEAD~2 &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''rebase_i_edit'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -210,7 +210,7 @@ test_expect_success 'status when splitting a commit' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing '\''split_commit'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -240,7 +240,7 @@ test_expect_success 'status after editing the last commit with --amend during a
 	git commit --amend -m "foo" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''amend_last'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -269,7 +269,7 @@ test_expect_success 'status: (continue first edit) second edit' '
 	git rebase --continue &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''several_edits'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -290,7 +290,7 @@ test_expect_success 'status: (continue first edit) second edit and split' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing '\''several_edits'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -316,7 +316,7 @@ test_expect_success 'status: (continue first edit) second edit and amend' '
 	git commit --amend -m "foo" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''several_edits'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -337,7 +337,7 @@ test_expect_success 'status: (amend first edit) second edit' '
 	git rebase --continue &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''several_edits'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -359,7 +359,7 @@ test_expect_success 'status: (amend first edit) second edit and split' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing '\''several_edits'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -386,7 +386,7 @@ test_expect_success 'status: (amend first edit) second edit and amend' '
 	git commit --amend -m "d" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''several_edits'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -409,7 +409,7 @@ test_expect_success 'status: (split first edit) second edit' '
 	git rebase --continue &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''several_edits'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -433,7 +433,7 @@ test_expect_success 'status: (split first edit) second edit and split' '
 	git reset HEAD^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently splitting a commit during a rebase.
+	# You are currently splitting a commit while rebasing '\''several_edits'\''.
 	#   (Once your working directory is clean, run "git rebase --continue")
 	#
 	# Changes not staged for commit:
@@ -462,7 +462,7 @@ test_expect_success 'status: (split first edit) second edit and amend' '
 	git commit --amend -m "h" &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently editing a commit during a rebase.
+	# You are currently editing a commit while rebasing '\''several_edits'\''.
 	#   (use "git commit --amend" to amend the current commit)
 	#   (use "git rebase --continue" once you are satisfied with your changes)
 	#
@@ -558,7 +558,7 @@ test_expect_success 'status when bisecting' '
 	git bisect good one_bisect &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently bisecting.
+	# You are currently bisecting '\''bisect'\''.
 	#   (use "git bisect reset" to get back to the original branch)
 	#
 	nothing to commit (use -u to show untracked files)
@@ -580,7 +580,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '
 	test_must_fail git rebase HEAD^ --onto HEAD^^ &&
 	cat >expected <<-\EOF &&
 	# Not currently on any branch.
-	# You are currently rebasing.
+	# You are currently rebasing '\''statushints_disabled'\''.
 	#
 	# Unmerged paths:
 	#	both modified:      main.txt
diff --git a/wt-status.c b/wt-status.c
index d7cfe8f..cc7e2d7 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -872,7 +872,13 @@ static void show_rebase_in_progress(struct wt_status *s,
 	struct stat st;
 
 	if (has_unmerged(s)) {
-		status_printf_ln(s, color, _("You are currently rebasing."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently rebasing '%s'."),
+					 state->branch);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently rebasing."));
 		if (advice_status_hints) {
 			status_printf_ln(s, color,
 				_("  (fix conflicts and then run \"git rebase --continue\")"));
@@ -882,17 +888,35 @@ static void show_rebase_in_progress(struct wt_status *s,
 				_("  (use \"git rebase --abort\" to check out the original branch)"));
 		}
 	} else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
-		status_printf_ln(s, color, _("You are currently rebasing."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently rebasing '%s'."),
+					 state->branch);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently rebasing."));
 		if (advice_status_hints)
 			status_printf_ln(s, color,
 				_("  (all conflicts fixed: run \"git rebase --continue\")"));
 	} else if (split_commit_in_progress(s)) {
-		status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently splitting a commit while rebasing '%s'."),
+					 state->branch);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently splitting a commit during a rebase."));
 		if (advice_status_hints)
 			status_printf_ln(s, color,
 				_("  (Once your working directory is clean, run \"git rebase --continue\")"));
 	} else {
-		status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
+		if (state->branch)
+			status_printf_ln(s, color,
+					 _("You are currently editing a commit while rebasing '%s'."),
+					 state->branch);
+		else
+			status_printf_ln(s, color,
+					 _("You are currently editing a commit during a rebase."));
 		if (advice_status_hints && !s->amend) {
 			status_printf_ln(s, color,
 				_("  (use \"git commit --amend\" to amend the current commit)"));
@@ -923,7 +947,7 @@ static void show_bisect_in_progress(struct wt_status *s,
 				struct wt_status_state *state,
 				const char *color)
 {
-	status_printf_ln(s, color, _("You are currently bisecting."));
+	status_printf_ln(s, color, _("You are currently bisecting '%s'."), state->branch);
 	if (advice_status_hints)
 		status_printf_ln(s, color,
 			_("  (use \"git bisect reset\" to get back to the original branch)"));
@@ -935,6 +959,7 @@ static void wt_status_print_state(struct wt_status *s)
 	const char *state_color = color(WT_STATUS_HEADER, s);
 	struct wt_status_state state;
 	struct stat st;
+	struct strbuf sb = STRBUF_INIT;
 
 	memset(&state, 0, sizeof(state));
 
@@ -947,28 +972,43 @@ static void wt_status_print_state(struct wt_status *s)
 				state.am_empty_patch = 1;
 		} else {
 			state.rebase_in_progress = 1;
+			strbuf_read_file(&sb, git_path("rebase-apply/head-name"), 0);
 		}
 	} else if (!stat(git_path("rebase-merge"), &st)) {
 		if (!stat(git_path("rebase-merge/interactive"), &st))
 			state.rebase_interactive_in_progress = 1;
 		else
 			state.rebase_in_progress = 1;
+		strbuf_read_file(&sb, git_path("rebase-merge/head-name"), 0);
 	} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
 		state.cherry_pick_in_progress = 1;
 	}
-	if (!stat(git_path("BISECT_LOG"), &st))
+	if (!stat(git_path("BISECT_LOG"), &st)) {
+		strbuf_read_file(&sb, git_path("BISECT_START"), 0);
 		state.bisect_in_progress = 1;
+	}
 
 	if (state.merge_in_progress)
 		show_merge_in_progress(s, &state, state_color);
 	else if (state.am_in_progress)
 		show_am_in_progress(s, &state, state_color);
-	else if (state.rebase_in_progress || state.rebase_interactive_in_progress)
+	else if (state.rebase_in_progress || state.rebase_interactive_in_progress) {
+		while (sb.len && sb.buf[sb.len - 1] == '\n')
+			strbuf_setlen(&sb, sb.len - 1);
+		if (!prefixcmp(sb.buf, "refs/heads/"))
+			state.branch = sb.buf + strlen("refs/heads/");
+		else if (!prefixcmp(sb.buf, "refs/"))
+			state.branch = sb.buf;
 		show_rebase_in_progress(s, &state, state_color);
-	else if (state.cherry_pick_in_progress)
+	} else if (state.cherry_pick_in_progress)
 		show_cherry_pick_in_progress(s, &state, state_color);
-	if (state.bisect_in_progress)
+	if (state.bisect_in_progress) {
+		while (sb.len && sb.buf[sb.len - 1] == '\n')
+			strbuf_setlen(&sb, sb.len - 1);
+		state.branch = sb.buf;
 		show_bisect_in_progress(s, &state, state_color);
+	}
+	strbuf_release(&sb);
 }
 
 void wt_status_print(struct wt_status *s)
diff --git a/wt-status.h b/wt-status.h
index 236b41f..c5eae29 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -79,6 +79,7 @@ struct wt_status_state {
 	int rebase_interactive_in_progress;
 	int cherry_pick_in_progress;
 	int bisect_in_progress;
+	const char *branch;
 };
 
 void wt_status_prepare(struct wt_status *s);
-- 
1.8.1.1.459.g5970e58

^ permalink raw reply related

* Re: [PATCH v2 0/4] Auto-generate mergetool lists
From: John Keeping @ 2013-01-29 12:09 UTC (permalink / raw)
  To: Joachim Schmitz; +Cc: git
In-Reply-To: <ke8de9$lk5$1@ger.gmane.org>

On Tue, Jan 29, 2013 at 12:56:58PM +0100, Joachim Schmitz wrote:
> John Keeping wrote:
> > Currently I'm extracting the command word using:
> >
> >    cmd=$(eval -- "set -- $(git config mergetool.$tool.cmd); echo
> > \"$1\"")
> 
> Shouldnt this work?
> cmd=$((git config "mergetool.$tool.cmd" || git config "difftool.$tool.cmd") 
> | awk '{print $1}')

That doesn't handle paths with spaces in, whereas the eval in a subshell
does:

    $ cmd='"my command" $BASE $LOCAL $REMOTE'
    $ echo "$cmd" | awk '{print $1}'
    "my
    $ ( eval -- "set -- $cmd; echo \"\$1\"" )
    my command


John

^ permalink raw reply

* Re: [PATCH v2 0/4] Auto-generate mergetool lists
From: Joachim Schmitz @ 2013-01-29 11:56 UTC (permalink / raw)
  To: git
In-Reply-To: <20130128222147.GD7498@serenity.lan>

John Keeping wrote:
> On Mon, Jan 28, 2013 at 01:50:19PM -0800, Junio C Hamano wrote:
>> What are the situations where a valid user-defined tools is
>> unavailable, by the way?
>
> The same as a built-in tool: the command isn't available.
>
> Currently I'm extracting the command word using:
>
>    cmd=$(eval -- "set -- $(git config mergetool.$tool.cmd); echo
> \"$1\"")

Shouldnt this work?
cmd=$((git config "mergetool.$tool.cmd" || git config "difftool.$tool.cmd") 
| awk '{print $1}')


> (it's slightly more complicated due to handling difftool.$tool.cmd as
> well, but that's essentially it).  Then it just uses the same "type
> $cmd" test as for built-in tools.
>
> I don't know if there's a better way to extract the first word, but
> that's the best I've come up with so far.
>
>
> John 

^ permalink raw reply

* Re: [PATCH 4/6] introduce a commit metapack
From: Jeff King @ 2013-01-29 11:13 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: git, Duy Nguyen, Shawn O. Pearce
In-Reply-To: <5107A36D.2050307@alum.mit.edu>

On Tue, Jan 29, 2013 at 11:24:45AM +0100, Michael Haggerty wrote:

> On 01/29/2013 10:16 AM, Jeff King wrote:
> > When we are doing a commit traversal that does not need to
> > look at the commit messages themselves (e.g., rev-list,
> > merge-base, etc), we spend a lot of time accessing,
> > decompressing, and parsing the commit objects just to find
> > the parent and timestamp information. We can make a
> > space-time tradeoff by caching that information on disk in a
> > compact, uncompressed format.
> > 
> > TODO: document on-disk format in Documentation/technical
> > TODO: document API
> 
> Would this be a good place to add the commit generation number that is
> so enthusiastically discussed on the mailing list from time to time?

Yes, that is one of my goals. We may even be able to just replace the
timestamp field in the cache with a generation number. When it gets
pretty-printed we pull it out of the commit message again anyway, so in
theory the only use inside "struct commit" is for ordering. But I
haven't looked at all of the use sites yet to be sure nobody is
depending on it being an actual date stamp.

-Peff

^ 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