Git development
 help / color / mirror / Atom feed
* Feature wish: Cloning without history
From: Sven Ekman @ 2006-05-18 19:21 UTC (permalink / raw)
  To: git

Hello,

Would it be possible to add an option to git-clone to
skip the complete history? The result should be a
repository which contains the current head only (or
maybe a specified tag) and has that commit id added to
.git/info/grafts. For the fetch process, this would
certainly have to imply the --no-tags flag.

>From a user's point of view I'd imagine something like
this:

git-clone --no-history=v2.6.16 \
    git://git.kernel.org/.../linux-2.6.git

The background: I'm regularly building kernels for a
handful of machines, and while I am happy to use the
blessings of git to get updates from the -stable
releases, I see no point in wasting space for a copy
of the complete kernel history on every single
machine. In practice this works pretty good, once I
have manually created such a castrated repository.

Sven

^ permalink raw reply

* Re: Feature wish: Cloning without history
From: Jakub Narebski @ 2006-05-18 19:35 UTC (permalink / raw)
  To: git
In-Reply-To: <20060518192144.15912.qmail@web25913.mail.ukl.yahoo.com>

Sven Ekman wrote:

> Would it be possible to add an option to git-clone to
> skip the complete history? The result should be a
> repository which contains the current head only (or
> maybe a specified tag) and has that commit id added to
> .git/info/grafts. For the fetch process, this would
> certainly have to imply the --no-tags flag.

It is certainly reccuring request.

Check for "shallow clone" in git mailing list archives.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Make "git rev-list" be a builtin
From: Linus Torvalds @ 2006-05-18 21:19 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


This was surprisingly easy. The diff is truly minimal: rename "main()" to 
"cmd_rev_list()" in rev-list.c, and rename the whole file to reflect its 
new built-in status.

We should have done this long ago.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---

[ NOTE! The diff is a git-only "git diff -M" with rename information, 
  because quite frankly, it's just a hell of a lot more readable that way. 
  But I thought I'd mention it explicitly, since it won't apply for 
  anybody who tries to apply it as a regular unified diff with "patch" ]

 Makefile                         |    6 +++---
 rev-list.c => builtin-rev-list.c |    3 ++-
 builtin.h                        |    1 +
 git.c                            |    1 +
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 3a28580..281fa69 100644
--- a/Makefile
+++ b/Makefile
@@ -158,7 +158,7 @@ PROGRAMS = \
 	git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
 	git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
 	git-peek-remote$X git-prune-packed$X git-read-tree$X \
-	git-receive-pack$X git-rev-list$X git-rev-parse$X \
+	git-receive-pack$X git-rev-parse$X \
 	git-send-pack$X git-show-branch$X git-shell$X \
 	git-show-index$X git-ssh-fetch$X \
 	git-ssh-upload$X git-tar-tree$X git-unpack-file$X \
@@ -170,7 +170,7 @@ PROGRAMS = \
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X \
 	git-count-objects$X git-diff$X git-push$X \
-	git-grep$X git-add$X
+	git-grep$X git-add$X git-rev-list$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -218,7 +218,7 @@ LIB_OBJS = \
 
 BUILTIN_OBJS = \
 	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-	builtin-grep.o builtin-add.o
+	builtin-grep.o builtin-add.o builtin-rev-list.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/rev-list.c b/builtin-rev-list.c
similarity index 99%
rename from rev-list.c
rename to builtin-rev-list.c
index 235ae4c..171f9d5 100644
--- a/rev-list.c
+++ b/builtin-rev-list.c
@@ -7,6 +7,7 @@ #include "blob.h"
 #include "tree-walk.h"
 #include "diff.h"
 #include "revision.h"
+#include "builtin.h"
 
 /* bits #0-15 in revision.h */
 
@@ -291,7 +292,7 @@ static void mark_edges_uninteresting(str
 	}
 }
 
-int main(int argc, const char **argv)
+int cmd_rev_list(int argc, const char **argv, char **envp)
 {
 	struct commit_list *list;
 	int i;
diff --git a/builtin.h b/builtin.h
index ccd0e31..a94d728 100644
--- a/builtin.h
+++ b/builtin.h
@@ -26,5 +26,6 @@ extern int cmd_count_objects(int argc, c
 extern int cmd_push(int argc, const char **argv, char **envp);
 extern int cmd_grep(int argc, const char **argv, char **envp);
 extern int cmd_add(int argc, const char **argv, char **envp);
+extern int cmd_rev_list(int argc, const char **argv, char **envp);
 
 #endif
diff --git a/git.c b/git.c
index 6a470cf..e2bba53 100644
--- a/git.c
+++ b/git.c
@@ -52,6 +52,7 @@ static void handle_internal_command(int 
 		{ "diff", cmd_diff },
 		{ "grep", cmd_grep },
 		{ "add", cmd_add },
+		{ "rev-list", cmd_rev_list },
 	};
 	int i;
 
 rename rev-list.c => builtin-rev-list.c (99%)

^ permalink raw reply related

* [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Yann Dirson @ 2006-05-18 21:35 UTC (permalink / raw)
  To: junkio; +Cc: git


This test fails with 1.3.x and HEAD.  This is a very serious bug, since it
causes data loss.

I am not sure whether it is normal that git-fsck-objects does not retun an
error code, while we can see it reports the inconsistency in --verbose
mode.  At least trying to directly access the dropped commit triggers an
error anyway.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---

 t/t6200-prune-grafts.sh |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/t/t6200-prune-grafts.sh b/t/t6200-prune-grafts.sh
new file mode 100755
index 0000000..80d0d59
--- /dev/null
+++ b/t/t6200-prune-grafts.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Yann Dirson
+#
+set -e
+
+test_description='Test that git-prune does not nuke revs hidden by a graft'
+
+. ./test-lib.sh
+
+echo First > A && git-add A && git-commit -m "Add A."
+echo First > B && git-add B && git-commit -m "Add B."
+echo Second >> A && git-update-index A && git-commit -m "Append to A."
+
+test_expect_success 'initial state is valid' 'git-fsck-objects'
+
+echo $(git-rev-parse HEAD) $(git-rev-parse HEAD^^) > .git/info/grafts
+
+test_expect_success 'grafted state is valid' 'git-fsck-objects'
+test_expect_success 'prune with the graft in effect' 'git-prune'
+test_expect_success 'grafted state is valid' 'git-fsck-objects'
+
+rm .git/info/grafts
+
+test_expect_success 'grafted state is still valid' 'git-fsck-objects'
+test_expect_success 'previously-hidden rev is still there' 'git-cat-file commit HEAD^'
+
+test_done

^ permalink raw reply related

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Linus Torvalds @ 2006-05-18 21:37 UTC (permalink / raw)
  To: Yann Dirson; +Cc: junkio, git
In-Reply-To: <20060518213519.14577.67309.stgit@gandelf.nowhere.earth>



On Thu, 18 May 2006, Yann Dirson wrote:
> 
> This test fails with 1.3.x and HEAD.  This is a very serious bug, since it
> causes data loss.

Is it/does it?

I'd assume that if you have a graft, you _want_ the history to be hidden 
and pruned. 

That's how you'd drop history, if you wanted to do it on purpose.

		Linus

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Junio C Hamano @ 2006-05-18 21:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605181435230.10823@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Is it/does it?
>
> I'd assume that if you have a graft, you _want_ the history to be hidden 
> and pruned. 
>
> That's how you'd drop history, if you wanted to do it on purpose.

I haven't looked at what the test does, but I think he is
talking about the opposite.  fsck by design does not honor
grafts, and if you grafted a history back to your true root
commit, that "older" history will be lost.

^ permalink raw reply

* Re: Make "git rev-list" be a builtin
From: Junio C Hamano @ 2006-05-18 21:50 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605181415090.10823@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> This was surprisingly easy. The diff is truly minimal: rename "main()" to 
> "cmd_rev_list()" in rev-list.c, and rename the whole file to reflect its 
> new built-in status.
>
> We should have done this long ago.

Should we have?

Certainly it is almost trivial, and it means we need to worry
about one less file, but is that the point?

^ permalink raw reply

* tailor (Was: gateway status?)
From: Yann Dirson @ 2006-05-18 22:07 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: David Lang, git
In-Reply-To: <46a038f90605160609u19a356ccx9467c32100731b9@mail.gmail.com>

On Wed, May 17, 2006 at 01:09:19AM +1200, Martin Langhoff wrote:
> On 5/16/06, David Lang <dlang@digitalinsight.com> wrote:
> >I seem to remember seeing discussion of gateways to cvs/svn that would let
> >a project use a git repository and allow clients to use cvs/svn clients to
> >retreive data.
> 
> I suspect you might be thinking of git-cvsserver. The code has no
> known bugs, but is has only seen limited use by in-house dev teams.

Another tool that I don't see mentionned often here is tailor, which
has the ability to act as a gatway between git and a good selection of
other SCMs, including cvs and svn.  I have not yet tried it with git
though, so any comments from people having shaked it a bit would be
useful :)

-- 
Yann Dirson    <ydirson@altern.org> |
Debian-related: <dirson@debian.org> |   Support Debian GNU/Linux:
                                    |  Freedom, Power, Stability, Gratis
     http://ydirson.free.fr/        | Check <http://www.debian.org/>

^ permalink raw reply

* Re: Make "git rev-list" be a builtin
From: Linus Torvalds @ 2006-05-18 22:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vejyrngto.fsf@assigned-by-dhcp.cox.net>



On Thu, 18 May 2006, Junio C Hamano wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
> >
> > We should have done this long ago.
> 
> Should we have?
> 
> Certainly it is almost trivial, and it means we need to worry
> about one less file, but is that the point?

Take a look at the size of the binaries before and after.

This is the _stripped_ binaries (on ppc) before:

  -rwxr-xr-x 9 torvalds torvalds 213392 May 18 14:56 git
  -rwxr-xr-x 1 torvalds torvalds 167540 May 18 14:56 git-rev-list

and after:

  -rwxr-xr-x 10 torvalds torvalds 216740 May 18 14:56 git
  -rwxr-xr-x 10 torvalds torvalds 216740 May 18 14:56 git-rev-list

ie the "git" binary grew by about 3kB, and the "git-rev-list" binary 
shrank by about 164kB (because it now takes zero disk-space: it's the same 
as the git binary).

So on ppc, you win about 160kB of disk space from this (and much more if 
you don't strip the binaries - "git-rev-list" is over half a megabyte 
with the debugging info for me).

Now, x86 probably has less of that, because it's a denser instruction set, 
but I'd expect that to be in the 100kB range too.

			Linus

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Linus Torvalds @ 2006-05-18 22:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7viro3nh07.fsf@assigned-by-dhcp.cox.net>



On Thu, 18 May 2006, Junio C Hamano wrote:
> 
> I haven't looked at what the test does, but I think he is
> talking about the opposite.  fsck by design does not honor
> grafts, and if you grafted a history back to your true root
> commit, that "older" history will be lost.

Ahh. Ok. Gotcha.

		Linus

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Yann Dirson @ 2006-05-18 22:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7viro3nh07.fsf@assigned-by-dhcp.cox.net>

On Thu, May 18, 2006 at 02:46:16PM -0700, Junio C Hamano wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
> 
> > Is it/does it?
> >
> > I'd assume that if you have a graft, you _want_ the history to be hidden 
> > and pruned. 
> >
> > That's how you'd drop history, if you wanted to do it on purpose.
> 
> I haven't looked at what the test does, but I think he is
> talking about the opposite.  fsck by design does not honor
> grafts, and if you grafted a history back to your true root
> commit, that "older" history will be lost.

I'm not sure I understand what you're saying.  AFACT fsck does not
ignore grafts: if a rev is not accessible from heads because of a
graft, prune drops it, and fsck does not see a problem.

Linus, I understand your point, but the current situation is
problematic: a graft does not get propagated by cg-clone (and I
suppose not by git-clone or git-fetch either), so cloning a tree which
has undergone such a pruning operation results in an incomplete clone
(indeed it is how I met the problem).  Since grafts are supposed to
have local effect only (as far as I understand), I see it as a bad
indication to have such a remote effect.

Maybe to make things safe, prune should by default consider both
physical and grafted parents as accessible, and a flag could be added
to get the current behaviour for people really knowing what they're
doing ?

Best regards,
-- 
Yann Dirson    <ydirson@altern.org> |
Debian-related: <dirson@debian.org> |   Support Debian GNU/Linux:
                                    |  Freedom, Power, Stability, Gratis
     http://ydirson.free.fr/        | Check <http://www.debian.org/>

^ permalink raw reply

* Re: tailor (Was: gateway status?)
From: Martin Langhoff @ 2006-05-18 22:16 UTC (permalink / raw)
  To: Yann Dirson; +Cc: David Lang, git
In-Reply-To: <20060518220759.GA6535@nowhere.earth>

On 5/19/06, Yann Dirson <ydirson@altern.org> wrote:
> Another tool that I don't see mentionned often here is tailor, which
> has the ability to act as a gatway between git and a good selection of
> other SCMs, including cvs and svn.  I have not yet tried it with git
> though, so any comments from people having shaked it a bit would be
> useful :)

Last I looked, a few months ago, it didn't track branches.

cheers,


martin

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Junio C Hamano @ 2006-05-18 22:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git, Yann Dirson
In-Reply-To: <Pine.LNX.4.64.0605181500470.10823@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> On Thu, 18 May 2006, Junio C Hamano wrote:
>> 
>> I haven't looked at what the test does, but I think he is
>> talking about the opposite.  fsck by design does not honor
>> grafts, and if you grafted a history back to your true root
>> commit, that "older" history will be lost.
>
> Ahh. Ok. Gotcha.
>
> 		Linus

Is it really OK?

I said "fsck by design does not honor" as a flamebait.

And what I said was completely untrue.  Sorry.

If you have a commit chain A->B->C and graft B away by saying
C's parent is A, fsck does read graft and discards B.  But that
is what the user asked to do, so I agree with your initial
response to Yann.

And the opposite case of grafting older history back to the real
root commit was a false alarm.  You would not lose such a
history, because the ancestry traversal will go right through
the real root and traverses the older history.

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Junio C Hamano @ 2006-05-18 22:36 UTC (permalink / raw)
  To: Yann Dirson; +Cc: git
In-Reply-To: <20060518222045.GB6535@nowhere.earth>

Yann Dirson <ydirson@altern.org> writes:

> I'm not sure I understand what you're saying.

Please don't; I was asleep when I typed it -- sorry.

I was hoping fsck was doing the right thing for a very low level
tool -- verify commit objects itself, without relying on the
object parser machinery which does funky things like grafts.

Apparently it doesn't -- which is mostly good.  You can safely
remove commits you wanted to discard by grafting it away like
your test did, and you can keep unrelated history you grafted to
the back of your real root commit.

For the "clone without propagating grafts" issue, I think we
need to have a way to communicate grafts across repositories.
As you say, grafts is a local policy issue, but when you start
cloning you _are_ sharing that local policy across repositories.
Futzing fsck to honor and ignore grafts at the same time sounds
like a band-aid to me.

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Yann Dirson @ 2006-05-18 22:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <20060518222045.GB6535@nowhere.earth>

On Fri, May 19, 2006 at 12:20:45AM +0200, Yann Dirson wrote:
> On Thu, May 18, 2006 at 02:46:16PM -0700, Junio C Hamano wrote:
> > Linus Torvalds <torvalds@osdl.org> writes:
> > 
> > > Is it/does it?
> > >
> > > I'd assume that if you have a graft, you _want_ the history to be hidden 
> > > and pruned. 
> > >
> > > That's how you'd drop history, if you wanted to do it on purpose.
> > 
> > I haven't looked at what the test does, but I think he is
> > talking about the opposite.  fsck by design does not honor
> > grafts, and if you grafted a history back to your true root
> > commit, that "older" history will be lost.
> 
> I'm not sure I understand what you're saying.  AFACT fsck does not
> ignore grafts: if a rev is not accessible from heads because of a
> graft, prune drops it, and fsck does not see a problem.
> 
> Linus, I understand your point, but the current situation is
> problematic: a graft does not get propagated by cg-clone (and I
> suppose not by git-clone or git-fetch either), so cloning a tree which
> has undergone such a pruning operation results in an incomplete clone
> (indeed it is how I met the problem).  Since grafts are supposed to
> have local effect only (as far as I understand), I see it as a bad
> indication to have such a remote effect.

To make my point maybe more clear: if someone really wants to make a
graft permanent, wouldn't some history rewriting (eg. with
cg-admin-rewritehist, but see the patch I posted against it) be the
way to go, instead of relying on out-of-band transfer of graft data ?

-- 
Yann Dirson    <ydirson@altern.org> |
Debian-related: <dirson@debian.org> |   Support Debian GNU/Linux:
                                    |  Freedom, Power, Stability, Gratis
     http://ydirson.free.fr/        | Check <http://www.debian.org/>

^ permalink raw reply

* Re: [PATCH] [BUG] Add a test to check git-prune does not throw away revs hidden by a graft.
From: Junio C Hamano @ 2006-05-18 22:53 UTC (permalink / raw)
  To: Yann Dirson; +Cc: git
In-Reply-To: <20060518225216.GC6535@nowhere.earth>

Yann Dirson <ydirson@altern.org> writes:

> To make my point maybe more clear: if someone really wants to make a
> graft permanent, wouldn't some history rewriting ... be the
> way to go,...

Yes.

^ permalink raw reply

* [PATCH] Allow pickaxe to be used via git log.
From: Sean @ 2006-05-19  1:31 UTC (permalink / raw)
  To: git

Handle the -S option when passed to git log such that only the appropriate
commits are displayed.  Unlike "whatchanged", by default no diff output
is produced.

---

This came out of recent comments on #git and will hopefully further reduce
the need for git-whatchanged.


ecdfaa21dbff93a6a387b02e1f1d3ebf05ee517d
 revision.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

ecdfaa21dbff93a6a387b02e1f1d3ebf05ee517d
diff --git a/revision.c b/revision.c
index 2294b16..2e18b2b 100644
--- a/revision.c
+++ b/revision.c
@@ -743,6 +743,13 @@ int setup_revisions(int argc, const char
 				continue;
 			}
 			opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
+			if (revs->diffopt.pickaxe && revs->always_show_header) {
+				revs->always_show_header = 0;
+				revs->diff = 1;
+				revs->diffopt.recursive = 1;
+				if (revs->diffopt.output_format == DIFF_FORMAT_RAW)
+					revs->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
+			}
 			if (opts > 0) {
 				revs->diff = 1;
 				i += opts - 1;
-- 
1.3.GIT

^ permalink raw reply related

* Re: [PATCH] Allow pickaxe to be used via git log.
From: Junio C Hamano @ 2006-05-19  2:47 UTC (permalink / raw)
  To: Sean; +Cc: git
In-Reply-To: <BAYC1-PASMTP04945C92FB14DA65AB1AC7AEA70@CEZ.ICE>

Sean <seanlkml@sympatico.ca> writes:

> Handle the -S option when passed to git log such that only the appropriate
> commits are displayed.  Unlike "whatchanged", by default no diff output
> is produced.

If that (specifically, "when passed to git log") is what you
want, do all of that in "git log" please.  I haven't checked,
but I suspect your changes would break git-rev-list and makes it
disobey the options the user gives it.

^ permalink raw reply

* Re: [PATCH] Allow pickaxe to be used via git log.
From: Sean @ 2006-05-19  2:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v4pzmn32g.fsf@assigned-by-dhcp.cox.net>

On Thu, 18 May 2006 19:47:19 -0700
Junio C Hamano <junkio@cox.net> wrote:

> If that (specifically, "when passed to git log") is what you
> want, do all of that in "git log" please.  I haven't checked,
> but I suspect your changes would break git-rev-list and makes it
> disobey the options the user gives it.
> 

Well, it's more general than just git log, but that's primarily where one
would see it.  Essentially the patch is saying that specifying both a
"revs->diffopt.pickaxe" string and "revs->always_show_header" is illegal
and proceeds to use pickaxe instead of the other.

Is there any place that depends on the ability to specify both a pickaxe
string _and_ always_show_header?  If not, it's hard to see how this patch
could break anything.

Sean

^ permalink raw reply

* [PATCH] built-in tar-tree and remote tar-tree
From: Junio C Hamano @ 2006-05-19  3:03 UTC (permalink / raw)
  To: git
In-Reply-To: <20060518192144.15912.qmail@web25913.mail.ukl.yahoo.com>

This makes tar-tree a built-in.  As an added bonus, you can now
say:

	git tar-tree --remote=remote-repository <ent> [<base>]

This does not work with git-daemon yet, but should work with
localhost and git over ssh transports.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * It comes up every once in a while that somebody says he wants
   a shallow clone, but when asked "what for?" it turns out that
   what is wanted is the ability to download a tarball for a
   specific revision for building that version, so here is one.

   If people think this is a useful thing, we would need to
   teach git-daemon about git-upload-tar, and perhaps we would
   also want to compress the tar image while it goes over the
   wire, which would be more work.

 Makefile                         |    8 +++--
 tar-tree.c => builtin-tar-tree.c |   62 +++++++++++++++++++++++++++++++++++-
 builtin-upload-tar.c             |   66 ++++++++++++++++++++++++++++++++++++++
 builtin.h                        |    2 +
 git.c                            |    2 +
 5 files changed, 135 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index 2149fb8..caf1e70 100644
--- a/Makefile
+++ b/Makefile
@@ -161,7 +161,7 @@ PROGRAMS = \
 	git-receive-pack$X git-rev-parse$X \
 	git-send-pack$X git-show-branch$X git-shell$X \
 	git-show-index$X git-ssh-fetch$X \
-	git-ssh-upload$X git-tar-tree$X git-unpack-file$X \
+	git-ssh-upload$X git-unpack-file$X \
 	git-unpack-objects$X git-update-index$X git-update-server-info$X \
 	git-upload-pack$X git-verify-pack$X git-write-tree$X \
 	git-update-ref$X git-symbolic-ref$X \
@@ -170,7 +170,8 @@ PROGRAMS = \
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X \
 	git-count-objects$X git-diff$X git-push$X \
-	git-grep$X git-rev-list$X git-check-ref-format$X
+	git-grep$X git-rev-list$X git-check-ref-format$X \
+	git-tar-tree$X git-upload-tar$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -218,7 +219,8 @@ LIB_OBJS = \
 
 BUILTIN_OBJS = \
 	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-	builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o
+	builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o \
+	builtin-tar-tree.o builtin-upload-tar.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/tar-tree.c b/builtin-tar-tree.c
similarity index 86%
rename from tar-tree.c
rename to builtin-tar-tree.c
index 3308736..e97e0af 100644
--- a/tar-tree.c
+++ b/builtin-tar-tree.c
@@ -7,11 +7,14 @@ #include "tree-walk.h"
 #include "commit.h"
 #include "strbuf.h"
 #include "tar.h"
+#include "builtin.h"
+#include "pkt-line.h"
 
 #define RECORDSIZE	(512)
 #define BLOCKSIZE	(RECORDSIZE * 20)
 
-static const char tar_tree_usage[] = "git-tar-tree <key> [basedir]";
+static const char tar_tree_usage[] =
+"git-tar-tree [--remote=<repo>] <ent> [basedir]";
 
 static char block[BLOCKSIZE];
 static unsigned long offset;
@@ -301,7 +304,7 @@ static void traverse_tree(struct tree_de
 	}
 }
 
-int main(int argc, char **argv)
+int generate_tar(int argc, const char **argv)
 {
 	unsigned char sha1[20], tree_sha1[20];
 	struct commit *commit;
@@ -348,3 +351,58 @@ int main(int argc, char **argv)
 	free(current_path.buf);
 	return 0;
 }
+
+static const char *exec = "git-upload-tar";
+
+static int remote_tar(int argc, const char **argv)
+{
+	int fd[2], ret, len;
+	pid_t pid;
+	char buf[1024];
+	char *url;
+
+	if (argc < 3 || 4 < argc)
+		usage(tar_tree_usage);
+
+	/* --remote=<repo> */
+	url = strdup(argv[1]+9);
+	pid = git_connect(fd, url, exec);
+	if (pid < 0)
+		return 1;
+
+	packet_write(fd[1], "want %s\n", argv[2]);
+	if (argv[3])
+		packet_write(fd[1], "base %s\n", argv[3]);
+	packet_flush(fd[1]);
+
+	len = packet_read_line(fd[0], buf, sizeof(buf));
+	if (!len)
+		die("git-tar-tree: expected ACK/NAK, got EOF");
+	if (buf[len-1] == '\n')
+		buf[--len] = 0;
+	if (strcmp(buf, "ACK")) {
+		if (5 < len && !strncmp(buf, "NACK ", 5))
+			die("git-tar-tree: NACK %s", buf + 5);
+		die("git-tar-tree: protocol error");
+	}
+	/* expect a flush */
+	len = packet_read_line(fd[0], buf, sizeof(buf));
+	if (len)
+		die("git-tar-tree: expected a flush");
+
+	/* Now, start reading from fd[0] and spit it out to stdout */
+	ret = copy_fd(fd[0], 1);
+	close(fd[0]);
+
+	ret |= finish_connect(pid);
+	return !!ret;
+}
+
+int cmd_tar_tree(int argc, const char **argv, char **envp)
+{
+	if (argc < 2)
+		usage(tar_tree_usage);
+	if (!strncmp("--remote=", argv[1], 9))
+		return remote_tar(argc, argv);
+	return generate_tar(argc, argv);
+}
diff --git a/builtin-upload-tar.c b/builtin-upload-tar.c
new file mode 100644
index 0000000..883b5aa
--- /dev/null
+++ b/builtin-upload-tar.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2006 Junio C Hamano
+ */
+#include "cache.h"
+#include "pkt-line.h"
+#include "exec_cmd.h"
+#include "builtin.h"
+
+static const char upload_tar_usage[] = "git-upload-tar <repo>";
+
+static int nack(const char *reason)
+{
+	packet_write(1, "NACK %s\n", reason);
+	packet_flush(1);
+	return 1;
+}
+
+int cmd_upload_tar(int argc, const char **argv, char **envp)
+{
+	int len;
+	char *dir = argv[1];
+	char buf[8129];
+	unsigned char sha1[20];
+	char *base = NULL;
+	char hex[41];
+	int ac;
+	const char *av[4];
+
+	if (argc != 2)
+		usage(upload_tar_usage);
+	if (!enter_repo(dir, 0))
+		return nak("not a git archive", dir);
+	len = packet_read_line(0, buf, sizeof(buf));
+	if (len < 5 || strncmp("want ", buf, 5))
+		return nak("expected want");
+	if (buf[len-1] == '\n')
+		buf[--len] = 0;
+	if (get_sha1(buf + 5, sha1))
+		return nak("expected sha1");
+        strcpy(hex, sha1_to_hex(sha1));
+
+	len = packet_read_line(0, buf, sizeof(buf));
+	if (len) {
+		if (len < 5 || strncmp("base ", buf, 5))
+			return nak("expected (optional) base");
+		if (buf[len-1] == '\n')
+			buf[--len] = 0;
+		base = strdup(buf + 5);
+		len = packet_read_line(0, buf, sizeof(buf));
+	}
+	if (len)
+		return nak("expected flush");
+
+	packet_write(1, "ACK\n");
+	packet_flush(1);
+
+	ac = 0;
+	av[ac++] = "tar-tree";
+	av[ac++] = hex;
+	if (base)
+		av[ac++] = base;
+	av[ac++] = NULL;
+	execv_git_cmd(av);
+	/* should it return that is an error */
+	return 1;
+}
diff --git a/builtin.h b/builtin.h
index ff559de..3ed5d65 100644
--- a/builtin.h
+++ b/builtin.h
@@ -26,5 +26,7 @@ extern int cmd_push(int argc, const char
 extern int cmd_grep(int argc, const char **argv, char **envp);
 extern int cmd_rev_list(int argc, const char **argv, char **envp);
 extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
+extern int cmd_tar_tree(int argc, const char **argv, char **envp);
+extern int cmd_upload_tar(int argc, const char **argv, char **envp);
 
 #endif
diff --git a/git.c b/git.c
index d0650bb..79d81b1 100644
--- a/git.c
+++ b/git.c
@@ -50,6 +50,8 @@ static void handle_internal_command(int 
 		{ "count-objects", cmd_count_objects },
 		{ "diff", cmd_diff },
 		{ "grep", cmd_grep },
+		{ "tar-tree", cmd_tar_tree },
+		{ "upload-tar", cmd_upload_tar },
 		{ "rev-list", cmd_rev_list },
 		{ "check-ref-format", cmd_check_ref_format }
 	};
-- 
1.3.3.gfad60

^ permalink raw reply related

* Re: [PATCH] Allow pickaxe to be used via git log.
From: Junio C Hamano @ 2006-05-19  3:05 UTC (permalink / raw)
  To: git
In-Reply-To: <BAYC1-PASMTP07581788E7BAAC19B2A159AEA70@CEZ.ICE>

Sean <seanlkml@sympatico.ca> writes:

> Is there any place that depends on the ability to specify both a pickaxe
> string _and_ always_show_header?  If not, it's hard to see how this patch
> could break anything.

User's scripts.  The point is the set of arguments rev-list as
the lowest level machinery should not be modified by an
arbitrary policy decision that happens to suit "git log" usage.

^ permalink raw reply

* Re: [PATCH] Allow pickaxe to be used via git log.
From: Junio C Hamano @ 2006-05-19  3:39 UTC (permalink / raw)
  To: Sean; +Cc: git
In-Reply-To: <BAYC1-PASMTP04945C92FB14DA65AB1AC7AEA70@CEZ.ICE>

Sean <seanlkml@sympatico.ca> writes:

> Handle the -S option when passed to git log such that only the appropriate
> commits are displayed.  Unlike "whatchanged", by default no diff output
> is produced.

If your goal is to make whatchanged less necessary, I think you
would need to special case --diff-filter as well for "git log",
although nobody on #git channel seems to have noticed.  I often
run --diff-filter=A when I am trying to see when I added a
particular file, to avoid getting distracted by other types of
changes; log would be still shown if do not disable --always.

^ permalink raw reply

* Re: [PATCH] Allow pickaxe to be used via git log.
From: Sean @ 2006-05-19  3:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vk68ilnoi.fsf@assigned-by-dhcp.cox.net>

On Thu, 18 May 2006 20:05:01 -0700
Junio C Hamano <junkio@cox.net> wrote:


> User's scripts.  The point is the set of arguments rev-list as
> the lowest level machinery should not be modified by an
> arbitrary policy decision that happens to suit "git log" usage.
> 

Okay, thanks.

This moves the policy up a level and into the log/show/whatchanged code
and makes the code match the commit message better.  However, it will still
"disobey" user options if the user tries to combine both pickaxe and
--always for these commands; but hopefully that's okay at this level.

Sean

diff --git a/builtin-log.c b/builtin-log.c
index d5bbc1c..d2c3df0 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -23,6 +23,11 @@ static int cmd_log_wc(int argc, const ch
 	rev->commit_format = CMIT_FMT_DEFAULT;
 	rev->verbose_header = 1;
 	argc = setup_revisions(argc, argv, rev, "HEAD");
+	if (rev->diffopt.pickaxe && rev->always_show_header) {
+		rev->always_show_header = 0;
+		if (rev->diffopt.output_format == DIFF_FORMAT_RAW)
+			rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
+	}
 
 	if (argc > 1)
 		die("unrecognized argument: %s", argv[1]);

^ permalink raw reply related

* [PATCH] Allow pickaxe and diff-filter options to be used by git log.
From: Sean @ 2006-05-19  4:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vac9elm2p.fsf@assigned-by-dhcp.cox.net>

Handle the -S option when passed to git log such that only the
appropriate commits are displayed.  Also per Junio's comments, do
the same for "--diff-filter", so that it too can be used as an option
to git log.  By default no patch or diff information is displayed.

Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>

---

> If your goal is to make whatchanged less necessary, I think you
> would need to special case --diff-filter as well for "git log",
> although nobody on #git channel seems to have noticed.  I often
> run --diff-filter=A when I am trying to see when I added a
> particular file, to avoid getting distracted by other types of
> changes; log would be still shown if do not disable --always.

Makes sense.  This patch should cover that case too.

Sean


a2221c07a94bc378ef40182fa6b260ac88804073
 builtin-log.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

a2221c07a94bc378ef40182fa6b260ac88804073
diff --git a/builtin-log.c b/builtin-log.c
index d5bbc1c..12a6d19 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -23,6 +23,13 @@ static int cmd_log_wc(int argc, const ch
 	rev->commit_format = CMIT_FMT_DEFAULT;
 	rev->verbose_header = 1;
 	argc = setup_revisions(argc, argv, rev, "HEAD");
+	if (rev->always_show_header) {
+		if (rev->diffopt.pickaxe || rev->diffopt.filter) {
+			rev->always_show_header = 0;
+			if (rev->diffopt.output_format == DIFF_FORMAT_RAW)
+				rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
+		}
+	}
 
 	if (argc > 1)
 		die("unrecognized argument: %s", argv[1]);
-- 
1.3.GIT

^ permalink raw reply related

* Re: [PATCH] Allow pickaxe and diff-filter options to be used by git log.
From: Junio C Hamano @ 2006-05-19  5:41 UTC (permalink / raw)
  To: Sean; +Cc: git
In-Reply-To: <BAYC1-PASMTP096010F052E9BF78B5FD4AAEA70@CEZ.ICE>

Sean <seanlkml@sympatico.ca> writes:

> +	if (rev->always_show_header) {
> +		if (rev->diffopt.pickaxe || rev->diffopt.filter) {

I understand and agree to the change up to this part, but I do
not necessarily agree with what follows:

> +			rev->always_show_header = 0;
> +			if (rev->diffopt.output_format == DIFF_FORMAT_RAW)
> +				rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;

To me, if the user explicitly says --diff-filter or -S, it seems
more natural to interpret that the user wanted _some_ sort of
diff.  Now, there are people who say raw format is anti-human,
which I consider is a valid view, but I think it is better than
NO_OUTPUT in that case.

I wonder if doing something like this instead makes more sense
perhaps?

-- >8 --

diff --git a/builtin-log.c b/builtin-log.c
index 69f2911..e68bfad 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -23,6 +23,35 @@ static int cmd_log_wc(int argc, const ch
 	if (argc > 1)
 		die("unrecognized argument: %s", argv[1]);
 
+	if (rev->always_show_header) {
+		/* Log command is primarily about the message for human
+		 * consumption, but if the user asks for any diff, it
+		 * is human unfriendly to give the raw diff.
+		 *
+		 * Show command is the same way, but there the default is
+		 * always give patch output, so this does not trigger.
+		 */
+		if (rev->diffopt.output_format == DIFF_FORMAT_RAW) {
+			if (rev->diffopt.pickaxe)
+				rev->diffopt.output_format = DIFF_FORMAT_PATCH;
+			else {
+				rev->diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
+				rev->diffopt.summary = 1;
+			}
+		}
+
+		/* If the user is limiting the commits to the ones
+		 * that have particular classes of diff, we should not
+		 * show the log message for irrelevant ones.
+		 *
+		 * git show --diff-filter=R -M --all can be used to view
+		 * the branch tips that renames something.  I do not know
+		 * how useful that is, though.
+		 */
+		if (rev->diffopt.pickaxe || rev->diffopt.filter)
+			rev->always_show_header = 0;
+	}
+
 	prepare_revision_walk(rev);
 	setup_pager();
 	while ((commit = get_revision(rev)) != NULL) {

^ 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