Git development
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] daemon: add tests
From: Junio C Hamano @ 2012-01-04 22:15 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: git, Jonathan Nieder, Jeff King, Erik Faye-Lund, Ilari Liusvaara,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <20120104204017.GC27567@ecki.lan>

Clemens Buchacher <drizzd@aon.at> writes:

> On Wed, Jan 04, 2012 at 10:00:07AM -0800, Junio C Hamano wrote:
>>
>> >> >> +	# kill git-daemon child of git
>> >> >> +	say >&3 "Stopping git daemon ..."
>> >> >> +	pkill -P "$DAEMON_PID"
>> >> 
>> >> How portable is this one (I usually do not trust use of pkill anywhere)?
>> >
>> > I read that it is supposed to be more portable than skill or killall.
>> > But I have no way to research this. I have implemented a workaround
>> > using only 'ps' and 'kill' in [PATCH 3/6] avoid use of pkill.
>> 
>> Yuck, that patch looks even uglier X-<.
>> 
>> Do you really need to kill the children but not the daemon?
>
> If I kill just the parent "git daemon" command, then the actual
> git-daemon (started by run_command) will be left behind.

Sounds like we would be better off with a new "--foreground" option other
daemon-ish projects seem to have?

^ permalink raw reply

* Re: git log --since --until
From: Junio C Hamano @ 2012-01-04 22:16 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Git Users
In-Reply-To: <CAE1pOi30FL+hRSqr3XRNgvOr4yBcTsbTpiNXpxJ=CN1Q=JVo3w@mail.gmail.com>

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

> git log --since="01-Dec-2011" --until="31-Dec-2011"
>
> The returned list of commits also included a few from November.

These limits act on committer dates. Are you by any chance looking at
author dates instead?

^ permalink raw reply

* Re: [PATCH 1/2] daemon: add tests
From: Jeff King @ 2012-01-04 22:26 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Clemens Buchacher, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <7vaa63p11t.fsf@alter.siamese.dyndns.org>

On Wed, Jan 04, 2012 at 02:15:10PM -0800, Junio C Hamano wrote:

> >> Do you really need to kill the children but not the daemon?
> >
> > If I kill just the parent "git daemon" command, then the actual
> > git-daemon (started by run_command) will be left behind.
> 
> Sounds like we would be better off with a new "--foreground" option other
> daemon-ish projects seem to have?

Isn't that usually for "don't background yourself"? AFAIK, git-daemon
stays in the foreground and only forks to handle each connection. So
can't we just kill the main process, and any running cruft will
eventually die as connections are closed?

Or is the problem the git wrapper itself, which doesn't kill its
subprocess when it dies (which IMHO is a bug which we might want to
fix)? In that case, couldn't we just use --pid-file to save the actual
daemon pid, and then kill using that?

As a side note, it looks like we just start the daemon with "git daemon
&". Doesn't that create a race condition with the tests which
immediately try to access it (i.e., the first test may run before the
daemon actually opens the socket)?

-Peff

^ permalink raw reply

* Re: git log --since --until
From: Hilco Wijbenga @ 2012-01-04 22:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Users
In-Reply-To: <7v62grp0z4.fsf@alter.siamese.dyndns.org>

On 4 January 2012 14:16, Junio C Hamano <gitster@pobox.com> wrote:
> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>
>> git log --since="01-Dec-2011" --until="31-Dec-2011"
>>
>> The returned list of commits also included a few from November.
>
> These limits act on committer dates. Are you by any chance looking at
> author dates instead?

I had to look that up. :-) Yes, I'm apparently looking at (and for)
author dates. I don't really care when the commit was merged into
master (that's the committer date, right?), I want to know when the
work was done.

I didn't really see any useful switches for git log in this regard but
then the author date seems to be additional data without special
meaning to Git.

^ permalink raw reply

* Re: git log --since --until
From: Junio C Hamano @ 2012-01-04 22:58 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Git Users
In-Reply-To: <CAE1pOi2vi8WHFNg2+NJCWnQ_atnCTRKXyBDJJpA8GM6nHmj6HQ@mail.gmail.com>

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

> ... the author date seems to be additional data without special
> meaning to Git.

That is exactly correct. The author date is merely for human consumption.

^ permalink raw reply

* Re: [PATCH] Do not fetch tags on new shallow clones
From: Junio C Hamano @ 2012-01-04 23:59 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git
In-Reply-To: <1325676922-6995-1-git-send-email-pclouds@gmail.com>

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

>  This could also be applied for normal clones. But I don't think
>  there are many use cases for it, enough to deserve new --no-tags
>  option.

Correct.

>  We should also fetch a single branch, but because branches are
>  usually less crowded and stay close the tip, they do not produce too
>  many extra objects. Let's leave it until somebody yells up.

Probably this is needed.

>  We should also fetch tags that reference to downloaded objects.

I do not think this has much merit. The usual tag-following rules AFAIK
assumes that if you have the commit C then you ought to have all the
ancestors of C, which does not apply at all for the shallow hack to begin
with, and if you make the rule apply for the shallow hack, you would end
up slurping the objects that are needed only for ancient versions, which
would defeat the objective of this patch, no?

It also is my understanding that the shallow hack is almost always used
with a depth of one, not a range, like "git archive | tar xf -", so if
anything, I would say a single-branch cloning has much higher priority
than following tags.

Will queue on 'pu'. Thanks.

^ permalink raw reply

* Re: [PATCH 0/3] More on pulling signed tags
From: Junio C Hamano @ 2012-01-05  0:10 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds
In-Reply-To: <1325715058-11984-1-git-send-email-gitster@pobox.com>

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

> A sample workflow with the command may look like this:
> ...
>   $ git show -s --show-signature

With this, in the Linux kernel repository, you could do this.

    $ git show -s --show-signature 2240a7bb47
    commit 2240a7bb479c38434bd636da9ce6afbd3f49447a
    parent #2, tagged 'tytso-for-linus-20111214'
    gpg: Signature made Wed 14 Dec 2011 11:15:13 AM PST using RSA key ID C11804F0
    gpg: Good signature from "Theodore Ts'o <tytso@mit.edu>"
    gpg:                 aka "Theodore Ts'o <tytso@debian.org>"
    gpg:                 aka "Theodore Ts'o <tytso@google.com>"
    Merge: 30aaca4 5a0dc73
    Author: Linus Torvalds <torvalds@linux-foundation.org>
    Date:   Wed Dec 14 18:25:58 2011 -0800

        Merge tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/linu...

        * tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/linux/ke...

      8< snip 8<

        .. using the new signed tag merge of git that now verifies the gpg
        signature automatically.  Yay.  The branchname was just 'dev', which is
        prettier.  I'll tell Ted to use nicer tag names for future cases.

We might want to reword "parent #2", by the way. The code was designed to
apply even to an Octopus, but I suspect 99.9% of the mergetag will be on
the second parent of a two-parent commit. You will never see "parent #1"
(i.e. direct parent you pulled into) unless you hand-craft the merge
commit object, and you are not likely to create an Octopus that pulls
multiple signed tags into one commit.

^ permalink raw reply

* Re: [PATCH 1/2] daemon: add tests
From: Clemens Buchacher @ 2012-01-05  0:07 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <20120104222649.GA14727@sigill.intra.peff.net>

On Wed, Jan 04, 2012 at 05:26:49PM -0500, Jeff King wrote:
> 
> Or is the problem the git wrapper itself, which doesn't kill its
> subprocess when it dies (which IMHO is a bug which we might want to
> fix)? In that case, couldn't we just use --pid-file to save the actual
> daemon pid, and then kill using that?

Or like this. Doesn't work with multiple children. I have yet to
check if we have those anywhere.

diff --git a/run-command.c b/run-command.c
index 1c51043..0c105e6 100644
--- a/run-command.c
+++ b/run-command.c
@@ -65,6 +65,22 @@ static int execv_shell_cmd(const char **argv)
 #ifndef WIN32
 static int child_err = 2;
 static int child_notifier = -1;
+static struct child_process *current_cmd;
+
+static void kill_current_cmd(int signo)
+{
+	signal(signo, SIG_DFL);
+
+	if (current_cmd) {
+		if (current_cmd->pid) {
+			/* forward signal to the child process */
+			kill(current_cmd->pid, signo);
+		} else {
+			/* trigger the default signal handler */
+			raise(signo);
+		}
+	}
+}
 
 static void notify_parent(void)
 {
@@ -201,6 +217,9 @@ fail_pipe:
 	if (pipe(notify_pipe))
 		notify_pipe[0] = notify_pipe[1] = -1;
 
+	current_cmd = cmd;
+	signal(SIGTERM, kill_current_cmd);
+
 	cmd->pid = fork();
 	if (!cmd->pid) {
 		/*
diff --git a/t/lib-daemon.sh b/t/lib-daemon.sh
index b2ffd54..c1c41ee 100644
--- a/t/lib-daemon.sh
+++ b/t/lib-daemon.sh
@@ -41,8 +41,8 @@ stop_daemon() {
 
 	# kill git-daemon child of git
 	say >&3 "Stopping git daemon ..."
-	pkill -P "$DAEMON_PID"
-	wait "$DAEMON_PID"
+	kill "$DAEMON_PID"
+	wait "$DAEMON_PID" >&3 2>&4
 	ret=$?
 	#
 	# We signal TERM=15 to the child and expect the parent to

> As a side note, it looks like we just start the daemon with "git daemon
> &". Doesn't that create a race condition with the tests which
> immediately try to access it (i.e., the first test may run before the
> daemon actually opens the socket)?

That's correct. How would I fix that? Try connecting and sleep in a
loop until ready or timeout? Will look into that.

^ permalink raw reply related

* Re: [PATCH 0/3] More on pulling signed tags
From: Junio C Hamano @ 2012-01-05  0:22 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds
In-Reply-To: <7vsjjvnh4e.fsf@alter.siamese.dyndns.org>

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

> We might want to reword "parent #2", by the way. The code was designed to
> apply even to an Octopus, but I suspect 99.9% of the mergetag will be on
> the second parent of a two-parent commit. You will never see "parent #1"
> (i.e. direct parent you pulled into) unless you hand-craft the merge
> commit object, and you are not likely to create an Octopus that pulls
> multiple signed tags into one commit.

... and this is a fix-up patch on top of the series. With this, the output
becomes like this:

  commit 2240a7bb479c38434bd636da9ce6afbd3f49447a
  merged tag 'tytso-for-linus-20111214'
  gpg: Signature made Wed 14 Dec 2011 11:15:13 AM PST using RSA key ID C11804F0
  gpg: Good signature from "Theodore Ts'o <tytso@mit.edu>"
  gpg:                 aka "Theodore Ts'o <tytso@debian.org>"
  gpg:                 aka "Theodore Ts'o <tytso@google.com>"
  Merge: 30aaca4 5a0dc73
  Author: Linus Torvalds <torvalds@linux-foundation.org>
  Date:   Wed Dec 14 18:25:58 2011 -0800

      Merge tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/l...

      * tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/linux...
        ext4: handle EOF correctly in ext4_bio_write_page()
       ...


 log-tree.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/log-tree.c b/log-tree.c
index b87dd53..37510da 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -456,6 +456,13 @@ static int which_parent(const unsigned char *sha1, const struct commit *commit)
 	return -1;
 }
 
+static int is_common_merge(const struct commit *commit)
+{
+	return (commit->parents
+		&& commit->parents->next
+		&& !commit->parents->next->next);
+}
+
 static void show_one_mergetag(struct rev_info *opt,
 			      struct commit_extra_header *extra,
 			      struct commit *commit)
@@ -474,6 +481,11 @@ static void show_one_mergetag(struct rev_info *opt,
 	strbuf_init(&verify_message, 256);
 	if (parse_tag_buffer(tag, extra->value, extra->len))
 		strbuf_addstr(&verify_message, "malformed mergetag\n");
+	else if (is_common_merge(commit) &&
+		 !hashcmp(tag->tagged->sha1,
+			  commit->parents->next->item->object.sha1))
+		strbuf_addf(&verify_message,
+			    "merged tag '%s'\n", tag->tag);
 	else if ((nth = which_parent(tag->tagged->sha1, commit)) < 0)
 		strbuf_addf(&verify_message, "tag %s names a non-parent %s\n",
 				    tag->tag, tag->tagged->sha1);

^ permalink raw reply related

* Re: [PATCH 1/2] daemon: add tests
From: Junio C Hamano @ 2012-01-05  0:24 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: Jeff King, git, Jonathan Nieder, Erik Faye-Lund, Ilari Liusvaara,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <20120105000713.GA24220@ecki.lan>

Clemens Buchacher <drizzd@aon.at> writes:

> On Wed, Jan 04, 2012 at 05:26:49PM -0500, Jeff King wrote:
>> 
>> Or is the problem the git wrapper itself, which doesn't kill its
>> subprocess when it dies (which IMHO is a bug which we might want to
>> fix)? In that case, couldn't we just use --pid-file to save the actual
>> daemon pid, and then kill using that?
>
> Or like this. Doesn't work with multiple children. I have yet to
> check if we have those anywhere.

Hmm, don't we have them in the same process group or something, though?
Can't we kill them as a whole?

^ permalink raw reply

* Re: [PATCH 0/3] More on pulling signed tags
From: Linus Torvalds @ 2012-01-05  0:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vobujngl3.fsf@alter.siamese.dyndns.org>

On Wed, Jan 4, 2012 at 4:22 PM, Junio C Hamano <gitster@pobox.com> wrote:
>
> ... and this is a fix-up patch on top of the series. With this, the output
> becomes like this:

Looking good, this is very useful. The hacks to extract the signatures
with 'git cat-file' were pretty ugly.

This is also nice for the case where the person doing the merge
doesn't yet have the pgp key something was signed with, so when you do
the "git pull", you get the "unknown key" thing instead of a "good
signature" message in the editor buffer.

It *used* to be the case that you had to abort the merge, fetch the
key, and re-pull in order to verify the key.

Now you can just say "ok, I'll commit the merge" and finish up, then
fetch the key, do "git show --show-signature", and if it doesn't show
up as good (which would be very rare) you can then 'git reset'
instead.  Which while less anal, is a lot more convenient.

                    Linus

^ permalink raw reply

* Re: [PATCH 1/2] daemon: add tests
From: Clemens Buchacher @ 2012-01-05  0:38 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, git, Jonathan Nieder, Erik Faye-Lund, Ilari Liusvaara,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <7vk457ngi0.fsf@alter.siamese.dyndns.org>

On Wed, Jan 04, 2012 at 04:24:23PM -0800, Junio C Hamano wrote:
> Clemens Buchacher <drizzd@aon.at> writes:
> 
> > On Wed, Jan 04, 2012 at 05:26:49PM -0500, Jeff King wrote:
> >> 
> >> Or is the problem the git wrapper itself, which doesn't kill its
> >> subprocess when it dies (which IMHO is a bug which we might want to
> >> fix)? In that case, couldn't we just use --pid-file to save the actual
> >> daemon pid, and then kill using that?
> >
> > Or like this. Doesn't work with multiple children. I have yet to
> > check if we have those anywhere.
> 
> Hmm, don't we have them in the same process group or something, though?
> Can't we kill them as a whole?

I tried that, but it seems that the test script itself is in the
same process group.

^ permalink raw reply

* Re: [PATCH 1/2] daemon: add tests
From: Jakub Narebski @ 2012-01-05  2:24 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Clemens Buchacher, git, Jonathan Nieder,
	Erik Faye-Lund, Ilari Liusvaara,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <20120104222649.GA14727@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> As a side note, it looks like we just start the daemon with "git daemon
> &". Doesn't that create a race condition with the tests which
> immediately try to access it (i.e., the first test may run before the
> daemon actually opens the socket)?

Hmmm... perhaps the trick that git-instaweb does for "plackup" web
server would be of use here, waiting for socket to be ready?

-- 
Jakub Narebski

^ permalink raw reply

* Re: [PATCH 1/2] daemon: add tests
From: Jeff King @ 2012-01-05  2:51 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Junio C Hamano, Clemens Buchacher, git, Jonathan Nieder,
	Erik Faye-Lund, Ilari Liusvaara,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <m3vcoqevjm.fsf@localhost.localdomain>

On Wed, Jan 04, 2012 at 06:24:16PM -0800, Jakub Narebski wrote:

> Jeff King <peff@peff.net> writes:
> 
> > As a side note, it looks like we just start the daemon with "git daemon
> > &". Doesn't that create a race condition with the tests which
> > immediately try to access it (i.e., the first test may run before the
> > daemon actually opens the socket)?
> 
> Hmmm... perhaps the trick that git-instaweb does for "plackup" web
> server would be of use here, waiting for socket to be ready?

It looks like it busy loops, which is kind of ugly.

The credential-cache helper has a similar problem. It wants to kick off
a daemon if one is not already running, and then connect to it. So the
daemon does:

  printf("ok\n");
  fclose(stdout);

when it has set up the socket, and the client does:

  r = read_in_full(daemon.out, buf, sizeof(buf));
  if (r < 0)
          die_errno("unable to read result code from cache daemon");
  if (r != 3 || memcmp(buf, "ok\n", 3))
          die("cache daemon did not start: %.*s", r, buf);
  /* now we can connect over the socket */

We could probably add a "--notify-when-ready" option to git-daemon to
do something similar.

-Peff

^ permalink raw reply

* Re: [PATCH 1/2] daemon: add tests
From: Jeff King @ 2012-01-05  2:55 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <20120105000713.GA24220@ecki.lan>

On Thu, Jan 05, 2012 at 01:07:13AM +0100, Clemens Buchacher wrote:

> On Wed, Jan 04, 2012 at 05:26:49PM -0500, Jeff King wrote:
> > 
> > Or is the problem the git wrapper itself, which doesn't kill its
> > subprocess when it dies (which IMHO is a bug which we might want to
> > fix)? In that case, couldn't we just use --pid-file to save the actual
> > daemon pid, and then kill using that?
> 
> Or like this. Doesn't work with multiple children. I have yet to
> check if we have those anywhere.

It so happens that I have just the patch you need. I've been meaning to
go over it again and submit it:

  run-command: optionally kill children on exit
  https://github.com/peff/git/commit/5523d7ebf2a0386c9c61d7bfbc21375041df4989

The original use case was to help with this:

  https://github.com/peff/git/commit/79bf3f232f89c3e2f5284a3b7b71a667be8825d1

> > As a side note, it looks like we just start the daemon with "git daemon
> > &". Doesn't that create a race condition with the tests which
> > immediately try to access it (i.e., the first test may run before the
> > daemon actually opens the socket)?
> 
> That's correct. How would I fix that? Try connecting and sleep in a
> loop until ready or timeout? Will look into that.

Your choices are basically busy-waiting, or convincing the daemon to
send a signal when it's ready to serve. I like the latter, but it does
mean adding a small amount of code to git-daemon.

-Peff

^ permalink raw reply

* Re: [PATCH] Do not fetch tags on new shallow clones
From: Shawn Pearce @ 2012-01-05  3:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nguyễn Thái Ngọc, git
In-Reply-To: <7vwr97nho7.fsf@alter.siamese.dyndns.org>

2012/1/4 Junio C Hamano <gitster@pobox.com>:
> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:
>>  We should also fetch tags that reference to downloaded objects.
>
> I do not think this has much merit.

I disagree. Its useful because cloning a branch immediately after it
has been tagged for a release should have `git describe` provide back
the name of the release from the tag (assuming of course no new
commits were made since the tag).

> The usual tag-following rules AFAIK
> assumes that if you have the commit C then you ought to have all the
> ancestors of C, which does not apply at all for the shallow hack to begin
> with, and if you make the rule apply for the shallow hack, you would end
> up slurping the objects that are needed only for ancient versions, which
> would defeat the objective of this patch, no?

We aren't talking about fetching the ancient history tags. We are
talking about fetching a tag that *directly* points at one of the
commits we did download the complete tree of.

> It also is my understanding that the shallow hack is almost always used
> with a depth of one, not a range, like "git archive | tar xf -", so if
> anything, I would say a single-branch cloning has much higher priority
> than following tags.

I think I agree with you on priority of work effort. But I lack time
to make good on that by writing the code myself.  :-)

^ permalink raw reply

* Re: [PATCH] Do not fetch tags on new shallow clones
From: Junio C Hamano @ 2012-01-05  5:57 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: Nguyễn Thái Ngọc, git
In-Reply-To: <CAJo=hJvL2ebziPw=0q-e=G3WFEvEKtFR2xMFMiquSyrHJDradA@mail.gmail.com>

Shawn Pearce <spearce@spearce.org> writes:

> 2012/1/4 Junio C Hamano <gitster@pobox.com>:
>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:
>>>  We should also fetch tags that reference to downloaded objects.
>>
>> I do not think this has much merit.
>
> I disagree. ...

No, you don't.  Because...

> ... Its useful because cloning a branch immediately after it
> has been tagged for a release should have `git describe` provide back
> the name of the release from the tag (assuming of course no new
> commits were made since the tag).

... this is a natural extension of ...

>> It also is my understanding that the shallow hack is almost always used
>> with a depth of one, not a range, like "git archive | tar xf -", so if
>> anything, I would say a single-branch cloning has much higher priority
>> than following tags.
>
> I think I agree with you on priority of work effort. ...

... this thing, once you have a "single ref only" stuff working.  After
Linus announces that he released 3.2, you would do the poor emulation of
"git archive | tar xf -" with something like:

    git clone --single=v3.2 --shallow $there linux-3.2

and your "git describe" should fall out as a natural consequence out of
everything else, without the usual "tag following" semantics, no?

^ permalink raw reply

* [PATCH v2] Limit refs to fetch to minimum in shallow clones
From: Nguyễn Thái Ngọc Duy @ 2012-01-05  6:05 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Shawn O. Pearce,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1325676922-6995-1-git-send-email-pclouds@gmail.com>

The main purpose of shallow clones is to reduce download by only
fetching objects up to a certain depth from the given refs. The number
of objects depends on how many refs to follow. So:

 - Only fetch HEAD or the ref specified by --branch
 - Only fetch tags that point to downloaded objects

More tags/branches can be fetched later using git-fetch as usual.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Only lightly tested, but seems to work. I'll check later if --branch
 works with a tag like Junio's example --single=v3.2

 Documentation/git-clone.txt |   14 ++++++----
 builtin/clone.c             |   54 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 4b8b26b..d69f440 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -172,12 +172,14 @@ objects from the source repository into a pack in the cloned repository.
 
 --depth <depth>::
 	Create a 'shallow' clone with a history truncated to the
-	specified number of revisions.  A shallow repository has a
-	number of limitations (you cannot clone or fetch from
-	it, nor push from nor into it), but is adequate if you
-	are only interested in the recent history of a large project
-	with a long history, and would want to send in fixes
-	as patches.
+	specified number of revisions. Only one branch (either HEAD
+	or specified by --branch) is fetched. Tags that point
+	outside truncated history are not fetched.
++
+A shallow repository has a number of limitations (you cannot clone or
+fetch from it, nor push from nor into it), but is adequate if you are
+only interested in the recent history of a large project with a long
+history, and would want to send in fixes as patches.
 
 --recursive::
 --recurse-submodules::
diff --git a/builtin/clone.c b/builtin/clone.c
index efe8b6c..8de9248 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -48,6 +48,7 @@ static int option_verbosity;
 static int option_progress;
 static struct string_list option_config;
 static struct string_list option_reference;
+static char *src_ref_prefix = "refs/heads/";
 
 static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
 {
@@ -427,9 +428,27 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
 	struct ref *local_refs = head;
 	struct ref **tail = head ? &head->next : &local_refs;
 
-	get_fetch_map(refs, refspec, &tail, 0);
-	if (!option_mirror)
-		get_fetch_map(refs, tag_refspec, &tail, 0);
+	if (option_depth) {
+		struct ref *remote_head = NULL;
+
+		if (!option_branch)
+			remote_head = guess_remote_head(head, refs, 0);
+		else {
+			struct strbuf sb = STRBUF_INIT;
+			strbuf_addstr(&sb, src_ref_prefix);
+			strbuf_addstr(&sb, option_branch);
+			remote_head = find_ref_by_name(refs, sb.buf);
+			strbuf_release(&sb);
+		}
+
+		if (remote_head)
+			get_fetch_map(remote_head, refspec, &tail, 0);
+	}
+	else {
+		get_fetch_map(refs, refspec, &tail, 0);
+		if (!option_mirror)
+			get_fetch_map(refs, tag_refspec, &tail, 0);
+	}
 
 	return local_refs;
 }
@@ -448,6 +467,27 @@ static void write_remote_refs(const struct ref *local_refs)
 	clear_extra_refs();
 }
 
+static void write_followtags(const struct ref *refs)
+{
+	struct ref_lock *lock;
+	const struct ref *ref;
+
+	for (ref = refs; ref; ref = ref->next) {
+		if (prefixcmp(ref->name, "refs/tags"))
+			continue;
+		if (!suffixcmp(ref->name, "^{}"))
+			continue;
+		if (!has_sha1_file(ref->old_sha1))
+			continue;
+
+		lock = lock_any_ref_for_update(ref->name, NULL, 0);
+		if (!lock)
+			die_errno(_("unable to lock %s for writing"), ref->name);
+		if (write_ref_sha1(lock, ref->old_sha1, "storing tag") < 0)
+			die_errno(_("unable to write %s"), ref->name);
+	}
+}
+
 static int write_one_config(const char *key, const char *value, void *data)
 {
 	return git_config_set_multivar(key, value ? value : "true", "^$", 0);
@@ -478,7 +518,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
-	char *src_ref_prefix = "refs/heads/";
 	int err = 0;
 
 	struct refspec *refspec;
@@ -642,9 +681,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		transport_set_option(transport, TRANS_OPT_KEEP, "yes");
 
-		if (option_depth)
+		if (option_depth) {
 			transport_set_option(transport, TRANS_OPT_DEPTH,
 					     option_depth);
+			transport_set_option(transport, TRANS_OPT_FOLLOWTAGS,
+					     "1");
+		}
 
 		transport_set_verbosity(transport, option_verbosity, option_progress);
 
@@ -663,6 +705,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		clear_extra_refs();
 
 		write_remote_refs(mapped_refs);
+		if (option_depth)
+			write_followtags(refs);
 
 		remote_head = find_ref_by_name(refs, "HEAD");
 		remote_head_points_at =
-- 
1.7.3.1.256.g2539c.dirty

^ permalink raw reply related

* Re: Auto-refresh git-gui
From: Victor Engmark @ 2012-01-05  8:03 UTC (permalink / raw)
  To: Clemens Buchacher; +Cc: git
In-Reply-To: <20120104163338.GA27567@ecki.lan>

On Wed, Jan 04, 2012 at 05:33:40PM +0100, Clemens Buchacher wrote:
> Hi Victor,
> 
> On Wed, Jan 04, 2012 at 10:15:47AM +0100, Victor Engmark wrote:
> >
> > Is there some way to make `git-gui` rescan automatically when anything
> > in the repository changes?
> 
> How about doing it each time git gui gets focus? Or if that's to
> much do it only if it gets focus _and_ the index has changed?

Ideally (like in jEdit) this should be configurable. In Options ->
General of jEdit, there are the following settings:

"If open files are changed on disk", with options:
* do nothing
* prompt
* automatically reload and notify user
* autoreload without notification

"Check for file change upon", with options:
* application focus
* application focus, visiting the buffer or saving any buffer
* visiting the buffer or saving any buffer
* visiting or saving the buffer
* saving the buffer

Based on this, I guess we could use the following settings:

"When repository changes", with options:
* do nothing [This could optionally disable the next setting]
* prompt
* rescan and notify user
* rescan without notification

"Check for repository changes", with options:
* always [Could be implemented with something like `inotifywait -rm`]
* upon application focus
* upon staging, unstaging, committing or pushing

I think I can see use cases for all these options, although it might be
a bit much to chew for a first iteration.

-- 
Victor Engmark
terreActive AG
Kasinostrasse 30
CH-5001 Aarau
Tel: +41 62 834 00 55
Fax: +41 62 823 93 56
www.terreactive.ch

Wir sichern Ihren Erfolg - seit 15 Jahren

^ permalink raw reply

* checkout on an empty directory fails
From: René Doß @ 2012-01-05 10:09 UTC (permalink / raw)
  To: git

I have a clean derectory ang the git database. Now I want check out the 
master.
The master is the last commit. The files name  are displayed but not 
stored out in directory.

Why can not I  check out?

René Doß



red@linux-nrd1:~/iso/a> ls -a
.  ..  .git
red@linux-nrd1:~/iso/a> git checkout master
D       SP601_RevC_annotated_master_ucf_8-28-09.ucf
D       rtl/ether_speed.vhd
D       rtl/ether_top.vhd
D       rtl/ether_tx.vhd
D       rtl/takt.vhd
D       sim/makefile
D       sim/tb_ether_top.vhd
Already on 'master'
red@linux-nrd1:~/iso/a> ls
red@linux-nrd1:~/iso/a>

^ permalink raw reply

* Re: checkout on an empty directory fails
From: Nguyen Thai Ngoc Duy @ 2012-01-05 11:06 UTC (permalink / raw)
  To: René Doß; +Cc: git
In-Reply-To: <4F0576D9.4030207@gmx.de>

On Thu, Jan 5, 2012 at 5:09 PM, René Doß <doss@gmx.de> wrote:
> I have a clean derectory ang the git database. Now I want check out the
> master.
> The master is the last commit. The files name  are displayed but not stored
> out in directory.
>
> Why can not I  check out?

try "git checkout ." but be careful because this command overwrites
any changes you have in the directory.

>
> red@linux-nrd1:~/iso/a> ls -a
> .  ..  .git
> red@linux-nrd1:~/iso/a> git checkout master
> D       SP601_RevC_annotated_master_ucf_8-28-09.ucf
> D       rtl/ether_speed.vhd
> D       rtl/ether_top.vhd
> D       rtl/ether_tx.vhd
> D       rtl/takt.vhd
> D       sim/makefile
> D       sim/tb_ether_top.vhd
> Already on 'master'
> red@linux-nrd1:~/iso/a> ls
> red@linux-nrd1:~/iso/a>
-- 
Duy

^ permalink raw reply

* Re: checkout on an empty directory fails
From: Ramkumar Ramachandra @ 2012-01-05 11:07 UTC (permalink / raw)
  To: René Doß; +Cc: git
In-Reply-To: <4F0576D9.4030207@gmx.de>

Hi René,

René Doß wrote:
> I have a clean derectory ang the git database. Now I want check out the
> master.
> [...]
>
> red@linux-nrd1:~/iso/a> ls -a
> .  ..  .git
> red@linux-nrd1:~/iso/a> git checkout master
> D       SP601_RevC_annotated_master_ucf_8-28-09.ucf
> [...]

In such situations, "git status" usually has something helpful to say.
 You're already on the "master" branch, and you can reset your
worktree with `git reset --hard` (caution: please read the manpage).

-- Ram

^ permalink raw reply

* Re: checkout on an empty directory fails
From: Thomas Rast @ 2012-01-05 11:13 UTC (permalink / raw)
  To: René Doß; +Cc: git
In-Reply-To: <4F0576D9.4030207@gmx.de>

René Doß <doss@gmx.de> writes:

> I have a clean derectory ang the git database. Now I want check out
> the master.

Ok, but why?  What problem were you really trying to solve?

> red@linux-nrd1:~/iso/a> git checkout master
> D       SP601_RevC_annotated_master_ucf_8-28-09.ucf
> D       rtl/ether_speed.vhd
> D       rtl/ether_top.vhd
> D       rtl/ether_tx.vhd
> D       rtl/takt.vhd
> D       sim/makefile
> D       sim/tb_ether_top.vhd
> Already on 'master'

git-checkout considers this an uncommitted change compared to the
current branch (HEAD).  It actually ensures that you do not lose such
changes.

To get your files back, you can use the file-argument form of checkout

  git checkout -- .

or the "really give me back the HEAD state, period" form of git-reset

  git reset --hard

Both of those *will* destroy uncommitted changes with no recourse or
backup, so be careful.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply

* Re: git-subtree
From: Ramkumar Ramachandra @ 2012-01-05 11:28 UTC (permalink / raw)
  To: David Greene; +Cc: git
In-Reply-To: <nngaa638nwf.fsf@transit.us.cray.com>

Hi David,

David Greene wrote:
> I have a patch ready.
> How does the git community want the patch presented?

Please read and follow the guidelines listed in
Documentation/SubmittingPatches.  The TL;DR version is: break it up
into logical reviewable commits based on the current `master` and use
git format-patch/ git send-email to send those commits to this mailing
list.

Cheers!

-- Ram

[1]: https://raw.github.com/git/git/master/Documentation/SubmittingPatches

^ permalink raw reply

* [PATCH] Fix incorrect ref namespace check
From: Nguyễn Thái Ngọc Duy @ 2012-01-05 12:35 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy

The reason why the trailing slash is needed is obvious. refs/stash is
not a namespace, but a single ref. Do full string compare on it.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/fetch.c  |    2 +-
 builtin/remote.c |    2 +-
 log-tree.c       |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 33ad3aa..daa68d2 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -573,7 +573,7 @@ static void find_non_local_tags(struct transport *transport,
 
 	for_each_ref(add_existing, &existing_refs);
 	for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
-		if (prefixcmp(ref->name, "refs/tags"))
+		if (prefixcmp(ref->name, "refs/tags/"))
 			continue;
 
 		/*
diff --git a/builtin/remote.c b/builtin/remote.c
index 583eec9..f54a89a 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -534,7 +534,7 @@ static int add_branch_for_removal(const char *refname,
 	}
 
 	/* don't delete non-remote-tracking refs */
-	if (prefixcmp(refname, "refs/remotes")) {
+	if (prefixcmp(refname, "refs/remotes/")) {
 		/* advise user how to delete local branches */
 		if (!prefixcmp(refname, "refs/heads/"))
 			string_list_append(branches->skipped,
diff --git a/log-tree.c b/log-tree.c
index 319bd31..9a88fcc 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -119,7 +119,7 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
 		type = DECORATION_REF_REMOTE;
 	else if (!prefixcmp(refname, "refs/tags/"))
 		type = DECORATION_REF_TAG;
-	else if (!prefixcmp(refname, "refs/stash"))
+	else if (!strcmp(refname, "refs/stash"))
 		type = DECORATION_REF_STASH;
 	else if (!prefixcmp(refname, "HEAD"))
 		type = DECORATION_REF_HEAD;
-- 
1.7.8.36.g69ee2

^ permalink raw reply related


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