Git development
 help / color / mirror / Atom feed
* [PATCH TOPGIT] tg export: Implement flattening patch paths for quilt mode
From: Uwe Kleine-König @ 2008-12-23 14:32 UTC (permalink / raw)
  To: git; +Cc: martin f. krafft, Petr Baudis
In-Reply-To: <1230042744-24675-1-git-send-email-u.kleine-koenig@pengutronix.de>

The result of providing the new flag -f is that the exported patches are
all placed directly in the output directory, not in subdirectories.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 tg-export.sh |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/tg-export.sh b/tg-export.sh
index 95aa346..06b9c8d 100644
--- a/tg-export.sh
+++ b/tg-export.sh
@@ -7,6 +7,7 @@ name=
 branches=
 output=
 driver=collapse
+flatten=false
 
 
 ## Parse options
@@ -16,6 +17,8 @@ while [ -n "$1" ]; do
 	case "$arg" in
 	-b)
 		branches="$1"; shift;;
+	-f)
+		flatten=true;;
 	--quilt)
 		driver=quilt;;
 	--collapse)
@@ -34,6 +37,9 @@ done
 [ -z "$branches" -o "$driver" = "quilt" ] ||
 	die "-b works only with the quilt driver"
 
+[ "$driver" = "quilt" ] || ! "$flatten" ||
+	die "-f works only with the quilt driver"
+
 if [ -z "$branches" ]; then
 	# this check is only needed when no branches have been passed
 	name="$(git symbolic-ref HEAD | sed 's#^refs/heads/##')"
@@ -138,7 +144,18 @@ quilt()
 		return
 	fi
 
-	filename="$output/$_dep.diff"
+	if "$flatten"; then
+		bn="$(echo "$_dep.diff" | sed -e 's#_#__#g' -e 's#/#_#g')";
+		dn="";
+	else
+		bn="$(basename "$_dep.diff")";
+		dn="$(dirname "$_dep.diff")/";
+		if [ "x$dn" = "x./" ]; then
+			dn="";
+		fi;
+	fi;
+
+	filename="$output/$dn$bn";
 	if [ -e "$filename" ]; then
 		# We've already seen this dep
 		return
@@ -148,9 +165,9 @@ quilt()
 		echo "Skip empty patch $_dep";
 	else
 		echo "Exporting $_dep"
-		mkdir -p "$(dirname "$filename")"
+		mkdir -p "$output/$dn";
 		$tg patch "$_dep" >"$filename"
-		echo "$_dep.diff -p1" >>"$output/series"
+		echo "$dn$bn -p1" >>"$output/series"
 	fi
 }
 
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH TOPGIT] tg export (quilt): Implement numbering the patches
From: Uwe Kleine-König @ 2008-12-23 14:32 UTC (permalink / raw)
  To: git; +Cc: martin f. krafft, Petr Baudis
In-Reply-To: <1230042744-24675-2-git-send-email-u.kleine-koenig@pengutronix.de>

To ease sending patches, with -n each patch gets a number prefix similar
to git format-patch.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 tg-export.sh |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/tg-export.sh b/tg-export.sh
index 06b9c8d..7a7d87a 100644
--- a/tg-export.sh
+++ b/tg-export.sh
@@ -8,6 +8,7 @@ branches=
 output=
 driver=collapse
 flatten=false
+numbered=false
 
 
 ## Parse options
@@ -19,6 +20,9 @@ while [ -n "$1" ]; do
 		branches="$1"; shift;;
 	-f)
 		flatten=true;;
+	-n)
+		flatten=true;
+		numbered=true;;
 	--quilt)
 		driver=quilt;;
 	--collapse)
@@ -37,6 +41,9 @@ done
 [ -z "$branches" -o "$driver" = "quilt" ] ||
 	die "-b works only with the quilt driver"
 
+[ "$driver" = "quilt" ] || ! "$numbered" ||
+	die "-n works only with the quilt driver";
+
 [ "$driver" = "quilt" ] || ! "$flatten" ||
 	die "-f works only with the quilt driver"
 
@@ -155,18 +162,26 @@ quilt()
 		fi;
 	fi;
 
-	filename="$output/$dn$bn";
-	if [ -e "$filename" ]; then
+	if [ -e "$playground/$_dep" ]; then
 		# We've already seen this dep
 		return
 	fi
 
+	mkdir -p "$playground/$(dirname "$_dep")";
+	touch "$playground/$_dep";
+
 	if branch_empty "$_dep"; then
 		echo "Skip empty patch $_dep";
 	else
+		if "$numbered"; then
+			number="$(printf "%04u" $(($(cat "$playground/^number" 2>/dev/null) + 1)))";
+			bn="$number-$bn";
+			echo "$number" >"$playground/^number";
+		fi;
+
 		echo "Exporting $_dep"
 		mkdir -p "$output/$dn";
-		$tg patch "$_dep" >"$filename"
+		$tg patch "$_dep" >"$output/$dn$bn"
 		echo "$dn$bn -p1" >>"$output/series"
 	fi
 }
-- 
1.5.6.5

^ permalink raw reply related

* Installing git docs in Cygwin.
From: Tim Visher @ 2008-12-23 14:39 UTC (permalink / raw)
  To: git

Hey Everyone,

I was wondering if anyone has been able to install the git docs on
Windows under Cygwin?  I just ran a successful compile of the core
software and everything seems to be working fine but when I do a `make
install-doc`, all of the pages compile fine but then make exits after
exiting git/Documentation with an `Error 2`.

Thoughts?

-- 

In Christ,

Timmy V.

http://burningones.com/
http://five.sentenc.es/ - Spend less time on e-mail

^ permalink raw reply

* Re: [RFC] Automagic patch merge ack emails
From: Richard Hartmann @ 2008-12-23 14:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v8wq8hs34.fsf@gitster.siamese.dyndns.org>

On Mon, Dec 22, 2008 at 21:29, Junio C Hamano <gitster@pobox.com> wrote:

> The only time that it may make a difference to you is when things are
> pushed out to the public repository, and there is a mechanism for
> automating tasks after new commits hits the public repository: the
> post-receive hook.  contrib/hooks/post-receive-email may be a good example
> to study if you are interested (I use it in my day job repository, but I
> do not use the hook in git.git because the style of announcing I adopted
> on this list is to send out "What's in/cooking" messages once or twice a
> week).

That's pretty much what I meant, yes. As to the rest, I am still thinking
too much in VCS, not DVCS, style, I guess.
Thanks for your clarification, it all makes sense, now :)


Richard

^ permalink raw reply

* Re: [announce] gc
From: Mike Ralphson @ 2008-12-23 15:06 UTC (permalink / raw)
  To: Stephen Haberman; +Cc: Matthieu Moy, git
In-Reply-To: <20081223082207.f31ab2a3.stephen@exigencecorp.com>

2008/12/23 Stephen Haberman <stephen@exigencecorp.com>
>
> > You should find a better name. I mean, one for which
> >
> >   http://www.google.com/search?q=git+YOUR-NAME-HERE
> >
> > has a chance to find you ...
>
> Ah, good point.
>
> Perhaps "git corporate hooks" or "git enterprise hooks".
>
> I'm a little cautious about using words like corporate/enterprise as
> there is nothing exclusively "corporate/enterprise" about any of the
> hooks in the project, we just happened to be on a corporate/enterprise
> project when we came up with them.

As the workflows these seem to support are centralised (as you say
these apply equally well in some non-corporate / enterprise projects),
how about git-central?

Mike

^ permalink raw reply

* Re: git-cvsimport fuzzy commit log matching?
From: Christoph Hellwig @ 2008-12-23 15:16 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Matthias Urlichs, git
In-Reply-To: <46a038f90812230453m4122e018l2cc22be3f40ab630@mail.gmail.com>

On Tue, Dec 23, 2008 at 10:53:42AM -0200, Martin Langhoff wrote:
> What you could do is
> 
>  1 - run cvsps with export to a file (I've posted in this list how to
> run it exactly as cvsimport does)
>  2 - post-process cvsps ouput with perl (there's a parser already in
> cvsimport ;-) )
>  3 - run cvsimport with the post-processed file
> 
> Or postprocess the imported git tree as others have suggested.

Instead of post-processing I hacked cvsps.  It already has a different
way to detect changesets when running in --bkcvs mode, and re-using that
one for ptools works great.

^ permalink raw reply

* Re: Questions about repo and git submodule
From: Shawn O. Pearce @ 2008-12-23 15:29 UTC (permalink / raw)
  To: Emily Ren; +Cc: Git Mailinglist
In-Reply-To: <856bfe0e0812230601m1765b483pe62c7902849e9cea@mail.gmail.com>

Emily Ren <lingyan.ren@gmail.com> wrote:
> 
> I have some questions about android repo and git submodule.
> 
> I created a repo repository with below commands:
> 1.  repo init -u git://android.git.kernel.org/platform/manifest.git
> 2.  repo initialized in /android
> 
> 1. The android dir is not a git repository,

Correct, it is not a git repository.  The repo tool does not use
git submodules.  The top level of a repo client has a ".repo/"
directory with metadata, not a ".git/" directory.  The table of
contents (the subprojects) is stored in XML files under ".repo/".

<aside>
I actually fought against the XML format for repo's manifest, but
others felt it was suitable.  And then walked away from the project
after Android open-sourced its code tree.  Leaving me to maintain it.
I see a file format simplification in the future for repo.
</aside>

> if other people clone my
> android code, how does it work?

Sadly this isn't supported correctly.  You can't initialize one
repo client from another, even though you can git clone one git
repository from any other.  Its a bug in repo's design.  The data
under ".repo/projects/" isn't laid out correctly to permit reuse
of one repo client to initialize another.

Its something I keep meaning to fix, but its going to take some
real effort.

In the mean time, there is a "--mirror" flag to repo init
which can be used to clone everything into bare repositories.
Those bare repositories can be published for others to repo init
from, though you need to customize the manifest.git:default.xml
so that the embedded URL refers back to your server and not
android.git.kernel.org.  Yet another thing I want to fix.

> 2. I want to make android dir to be a git repository, is it workable
> that I create submodule for each subdirectory in another directory? Is
> there a script for it?

You might be able to do something like this:

	cd /android
	git init
	repo forall -c 'cd /android && git submodule add `pwd`'

Also, you might want to consider asking questions related to repo
on the repo-discuss@googlegroups.com mailing list.  There's a lot
more repo users there than on the git mailing list, and they have
started to come up with their own "tips n tricks".

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] merge-recursive: mark rename/delete conflict as unmerged
From: Johannes Schindelin @ 2008-12-23 16:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Constantine Plotnikov, git, Alex Riesen
In-Reply-To: <7v7i5rhkix.fsf@gitster.siamese.dyndns.org>

Hi,

On Mon, 22 Dec 2008, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > When a file was renamed in one branch, but deleted in the other, one 
> > should expect the index to contain an unmerged entry, namely the 
> > target of the rename.  Make it so.
> 
> That was quick, but the surrounding code makes me wonder if other
> if/elseif branches also need similar handling.

I tried to make sure that the surrounding code also adds unmerged entries, 
but I have to admit that my focus lay with the bug report at hand.

> For example, rename/add comes up with a new name that does not exist 
> anywhere, and adds both to the index; it is understandable that you need 
> to do this when processing a merge with non-zero depth because you need 
> to have a tree as the result, but shouldn't the final zero depth merge 
> just use the original names and leave the results in higher stages?

Hmm.  I think this is a different issue (if you mean the issue that the 
result might be named differently than expected).

As for the unmerged entries, no, I do not think we need to do anything 
else besides calling update_file() and set try_merge = 1.

After all, if a file was renamed in one branch, but added directly in 
another, does it need to conflict?  I'd say no.

Ciao,
Dscho

^ permalink raw reply

* Re: What's cooking in git.git (Dec 2008, #03; Sun, 21)
From: Johannes Schindelin @ 2008-12-23 16:26 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20081223120534.GA21633@coredump.intra.peff.net>

Hi,

On Tue, 23 Dec 2008, Jeff King wrote:

> On Sun, Dec 21, 2008 at 04:23:22AM -0800, Junio C Hamano wrote:
> 
> > * js/notes (Sat Dec 20 13:06:03 2008 +0100) 4 commits
> >  - Add an expensive test for git-notes
> >  - Speed up git notes lookup
> >  - Add a script to edit/inspect notes
> >  - Introduce commit notes
> 
> I haven't had much time to really look at this closely, and I probably 
> won't for another week or so due to the holidays. But from my cursory 
> examination, I think I want to propose something that is a bit 
> different.

Could you be a bit more, like, specific, please?

Ciao,
Dscho

^ permalink raw reply

* Re: What's cooking in git.git (Dec 2008, #03; Sun, 21)
From: Jeff King @ 2008-12-23 16:38 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <alpine.DEB.1.00.0812231725270.30769@pacific.mpi-cbg.de>

On Tue, Dec 23, 2008 at 05:26:01PM +0100, Johannes Schindelin wrote:

> > I haven't had much time to really look at this closely, and I probably 
> > won't for another week or so due to the holidays. But from my cursory 
> > examination, I think I want to propose something that is a bit 
> > different.
> 
> Could you be a bit more, like, specific, please?

The way that GIT_NOTES_REF and core.notesref work aren't what I had in
mind. I imagined something more amenable to having lots of different
metadata notes.  Refer to the other messages I have written on "naming".

I don't want to hold up progress, so if people want those patches in
"next", then go for it. What I really meant by my email was that I think
my suggested changes might be simpler to see as a re-roll rather than
patches on top, but since I can't work on them for a while, I didn't
want Junio to take silence as "OK, nobody has complained, so it's time
for this to graduate to next." But again, if people are ready to start
playing with this and building on top of it, then I don't want to stand
in the way.

-Peff

^ permalink raw reply

* Re: What's cooking in git.git (Dec 2008, #03; Sun, 21)
From: Johannes Schindelin @ 2008-12-23 16:52 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20081223163811.GA25658@coredump.intra.peff.net>

Hi,

On Tue, 23 Dec 2008, Jeff King wrote:

> On Tue, Dec 23, 2008 at 05:26:01PM +0100, Johannes Schindelin wrote:
> 
> > > I haven't had much time to really look at this closely, and I probably 
> > > won't for another week or so due to the holidays. But from my cursory 
> > > examination, I think I want to propose something that is a bit 
> > > different.
> > 
> > Could you be a bit more, like, specific, please?
> 
> The way that GIT_NOTES_REF and core.notesref work aren't what I had in 
> mind. I imagined something more amenable to having lots of different 
> metadata notes.  Refer to the other messages I have written on "naming".

Unfortunately, there were way too many messages between you and Govind, 
with not enough new stuff that could interest me, so I had to stop reading 
them to avoid depleting my Git time budget each and every single day.

However, note that without something like core.notesref you will never be 
able to have private and public notes.

And I very much want to have private notes _and_ public notes on the very 
same commits of the very same branches.

> I don't want to hold up progress, so if people want those patches in 
> "next", then go for it. What I really meant by my email was that I think 
> my suggested changes might be simpler to see as a re-roll rather than 
> patches on top, but since I can't work on them for a while, I didn't 
> want Junio to take silence as "OK, nobody has complained, so it's time 
> for this to graduate to next." But again, if people are ready to start 
> playing with this and building on top of it, then I don't want to stand 
> in the way.

I just wanted to fiddle a little bit with profiling, as I really do not 
understand why the new notes perform that badly against the old notes, 
even allowing for reading a complete, possibly huge tree into a hashmap.

And while I am almost sure that there is a stupid bug lurking that will 
kick the performance again, I think the basic design is sound, and it 
should be easy to modify no matter which way you want to change the 
behavior with regards to trees/blobs or refs.

Of course, I'd like Miklos' read-tree bug solved before any more work is 
done on notes, since we are in -rc4 after all, and that is a potentially 
pretty serious bug.

Ciao,
Dscho

^ permalink raw reply

* Question with git push
From: Paul Vincent Craven @ 2008-12-23 16:59 UTC (permalink / raw)
  To: git

If I do a 'git push' to another repository, my changes are reverted
the next time that repository is updated, unless I do a hard reset on
the remote repository first. Of course, then I would lose my changes
in the remote repository. What is the correct way of handling this?

A quick example:

mkdir -p RepositoryA/files RepositoryB
cd RepositoryA/files
echo "Test file" > test1.txt
git init
git add .
git commit -a -m "Test Commit 1"
cd ../../RepositoryB
git clone ../RepositoryA/files
cd files
# I want this change to go to RepositoryA
echo "More data" >> test1.txt
git add .
git commit -a -m "Test Commit 2"
git push ../../RepositoryA/files
cd ../../RepositoryA/files
echo "Test file" > test2.txt
git add .
# This commit reverts test1.txt to not have "More data"
git commit -a -m "Test Commit 3" # This reverts test1.txt to not
git diff master^ master

How do I change my commands so I keep the change I made in RepositoryB?

Thanks,

-- 
Paul Vincent Craven

--
Paul Vincent Craven
http://www.cravenfamily.com

^ permalink raw reply

* Re: Installing git docs in Cygwin.
From: Pascal Obry @ 2008-12-23 17:06 UTC (permalink / raw)
  To: Tim Visher; +Cc: git@vger.kernel.org
In-Reply-To: <c115fd3c0812230639v78cee30cqbc7303b02633c8d1@mail.gmail.com>


Le 23 déc. 08 à 15:39, "Tim Visher" <tim.visher@gmail.com> a écrit :

> working fine but when I do a `make
> install-doc`, all of the pages compile fine but then make exits after
> exiting git/Documentation with an `Error 2`.
>
> Thoughts?

Are you sure the docs were built fine. I had to revert to a previous  
version of asciidoc. Just an hint.

Pascal.

^ permalink raw reply

* Re: What's cooking in git.git (Dec 2008, #03; Sun, 21)
From: Jeff King @ 2008-12-23 17:34 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <alpine.DEB.1.00.0812231746250.30769@pacific.mpi-cbg.de>

On Tue, Dec 23, 2008 at 05:52:54PM +0100, Johannes Schindelin wrote:

> However, note that without something like core.notesref you will never be 
> able to have private and public notes.
> 
> And I very much want to have private notes _and_ public notes on the very 
> same commits of the very same branches.

Right. I think core.notesref doesn't go far enough, because it doesn't
provide a way to talk about notes from two sources at the same time.
Like:

  git log --pretty=format:'%N(my-private-notes:foo) %N(public-notes:bar)'

> I just wanted to fiddle a little bit with profiling, as I really do not 
> understand why the new notes perform that badly against the old notes, 
> even allowing for reading a complete, possibly huge tree into a hashmap.

I haven't looked closely at the latest series yet, so I can't comment.

> And while I am almost sure that there is a stupid bug lurking that will 
> kick the performance again, I think the basic design is sound, and it 
> should be easy to modify no matter which way you want to change the 
> behavior with regards to trees/blobs or refs.

I agree that the data structure is sound, so I can probably work on top
of what you posted, too. I was planning on doing git-notes in C, though.

-Peff

^ permalink raw reply

* Re: Question with git push
From: Peter Harris @ 2008-12-23 17:35 UTC (permalink / raw)
  To: Paul Vincent Craven; +Cc: git
In-Reply-To: <5591393c0812230859n3b50b1f9k36153f40dd75ff57@mail.gmail.com>

On Tue, Dec 23, 2008 at 11:59 AM, Paul Vincent Craven wrote:
> If I do a 'git push' to another repository, my changes are reverted
> the next time that repository is updated, unless I do a hard reset on
> the remote repository first. Of course, then I would lose my changes
> in the remote repository. What is the correct way of handling this?

Pull from the other side, or push to a branch that you never check
out. Better yet, push to a bare (no work tree) repo you can pull from
both sides.

http://git.or.cz/gitwiki/GitFaq#head-b96f48bc9c925074be9f95c0fce69bcece5f6e73

Peter Harris

^ permalink raw reply

* Re: Question with git push
From: demerphq @ 2008-12-23 17:37 UTC (permalink / raw)
  To: Paul Vincent Craven; +Cc: git
In-Reply-To: <5591393c0812230859n3b50b1f9k36153f40dd75ff57@mail.gmail.com>

2008/12/23 Paul Vincent Craven <paul@cravenfamily.com>:
> If I do a 'git push' to another repository, my changes are reverted
> the next time that repository is updated, unless I do a hard reset on
> the remote repository first.

Or just git checkout -f

> Of course, then I would lose my changes
> in the remote repository. What is the correct way of handling this?

I think the general practice is not to push to non-bare repositories
unless you and the owner of the repository can coordinate things. This
either means you push and then tell them, or they set up a
post-receive hook (and understand the consequences of doing so). Of
course often you are both of these people and coordination is easy.

The post-receive hook would go in .git/hooks and would effectively execute:

  git checkout -f

on push. However this also means that the working directory will be
unilaterally updated every time someone pushes. Not something you want
to do in a truely shared non-bare repo.
Yves


-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

^ permalink raw reply

* Re: Can `git config` override entries in .gitconfig?
From: Johan Herland @ 2008-12-23 17:59 UTC (permalink / raw)
  To: Nicholas LaRoche; +Cc: git
In-Reply-To: <4950D41A.5050009@vt.edu>

On Tuesday 23 December 2008, Nicholas LaRoche wrote:
> Is there a direct way to change the user.email entry for a git
> repository for one user (applied to all previous commits)?
>
> I tried `git config --unset user.email` followed by `git config
> user.email email2` but it just sets a second field called user.email
> that shows up in `git config -l` as a duplicate. My ~/.gitconfig file
> contains email1 for the user.email entry.
>
> Also, when the repository is created can I specify a second set of
> contact information (i.e. using a project specific email) which isn't a
> part of ~/.gitconfig?
>
> output of `git config -l`:
> user.email=email1
> ..
> ..
> user.email=email2

Hi,

Use git-config's --global option to set options in your ~/.gitconfig. 
Otherwise, your config changes are stored in the current repo's config 
(.git/config).

In your case, when you did `git config --unset user.email`, you unset the 
(non-existing) user.email in your repo config, without touching the one in 
~/.gitconfig, and when you did `git config user.email email2`, you set 
user.email in the repo config (without changing the one in your 
~/.gitconfig).

Although `git config -l` displays options from both ~/.gitconfig and the 
repo config, AFAIK the repo config does _override_ the ~/.gitconfig, so 
when you have user.email set in both, your new commits will use the one in 
the repo config (i.e. "email2").

As for rewriting your email address in all previous commits, that is 
impossible to do without rewriting your entire history. Rewriting your 
history is probably not something you want to do if you have published your 
repo, and other people have started working on top of your commits. If you 
_do_ want to rewrite your history, you should look at the "git 
filter-branch" command.


Have fun!

...Johan

-- 
Johan Herland, <johan@herland.net>
www.herland.net

^ permalink raw reply

* [JGIT PATCH 0/5] Add jgit init, clone, receive-pack; transport fixes
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

Define a "jgit init", "jgit clone" commands from the command line.

Add "jgit receive-pack".  This now works from C git:

  git push --receive-pack='jgit receive-pack' dst.git

Fix issue #22, causing jgit to fetch too many objects during an
initial clone/fetch of a repository.

Change "jgit daemon" so it can run outside of a repository, making
it slightly more useful.


Shawn O. Pearce (5):
  Add "jgit receive-pack" and permit commands to start not in a
    repository
  Add "jgit init" command to create a new repository
  Modify "jgit daemon" so it can run outside of a repository
  Add "jgit clone" to support cloning off URLs that are JGit specific
  Fix "fetch pulled too many objects" when auto-following tags

 .../services/org.spearce.jgit.pgm.TextBuiltin      |    3 +
 .../org/spearce/jgit/pgm/AbstractFetchCommand.java |  126 ++++++++++++++
 .../src/org/spearce/jgit/pgm/Clone.java            |  177 ++++++++++++++++++++
 .../src/org/spearce/jgit/pgm/Daemon.java           |   33 +---
 .../src/org/spearce/jgit/pgm/Fetch.java            |   83 +---------
 .../src/org/spearce/jgit/pgm/Init.java             |   60 +++++++
 .../src/org/spearce/jgit/pgm/Main.java             |   19 ++-
 .../src/org/spearce/jgit/pgm/ReceivePack.java      |   67 ++++++++
 .../src/org/spearce/jgit/pgm/TextBuiltin.java      |   24 +++-
 .../jgit/transport/BaseFetchConnection.java        |   26 ++-
 .../jgit/transport/BasePackFetchConnection.java    |   25 +++-
 .../spearce/jgit/transport/FetchConnection.java    |   21 ++-
 .../org/spearce/jgit/transport/FetchProcess.java   |    6 +-
 .../spearce/jgit/transport/TransportBundle.java    |    3 +-
 .../jgit/transport/WalkFetchConnection.java        |   14 ++-
 15 files changed, 544 insertions(+), 143 deletions(-)
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/AbstractFetchCommand.java
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Clone.java
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Init.java
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ReceivePack.java

^ permalink raw reply

* [JGIT PATCH 2/5] Add "jgit init" command to create a new repository
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git
In-Reply-To: <1230055423-9944-2-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../services/org.spearce.jgit.pgm.TextBuiltin      |    1 +
 .../src/org/spearce/jgit/pgm/Init.java             |   60 ++++++++++++++++++++
 2 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Init.java

diff --git a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
index 0e7e7d8..4a2b605 100644
--- a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
+++ b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
@@ -4,6 +4,7 @@ org.spearce.jgit.pgm.DiffTree
 org.spearce.jgit.pgm.Fetch
 org.spearce.jgit.pgm.Glog
 org.spearce.jgit.pgm.IndexPack
+org.spearce.jgit.pgm.Init
 org.spearce.jgit.pgm.Log
 org.spearce.jgit.pgm.LsRemote
 org.spearce.jgit.pgm.LsTree
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Init.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Init.java
new file mode 100644
index 0000000..197864d
--- /dev/null
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Init.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.pgm;
+
+import java.io.File;
+
+import org.spearce.jgit.lib.Repository;
+
+@Command(common = true, usage = "Create an empty git repository")
+class Init extends TextBuiltin {
+	@Override
+	protected final boolean requiresRepository() {
+		return false;
+	}
+
+	@Override
+	protected void run() throws Exception {
+		if (gitdir == null)
+			gitdir = new File(".git");
+		db = new Repository(gitdir);
+		db.create();
+		out.println("Initialized empty Git repository in "
+				+ gitdir.getAbsolutePath());
+	}
+}
-- 
1.6.1.rc4.301.g5497a

^ permalink raw reply related

* [JGIT PATCH 1/5] Add "jgit receive-pack" and permit commands to start not in a repository
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git
In-Reply-To: <1230055423-9944-1-git-send-email-spearce@spearce.org>

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../services/org.spearce.jgit.pgm.TextBuiltin      |    1 +
 .../src/org/spearce/jgit/pgm/Main.java             |   19 +++---
 .../src/org/spearce/jgit/pgm/ReceivePack.java      |   67 ++++++++++++++++++++
 .../src/org/spearce/jgit/pgm/TextBuiltin.java      |   24 ++++++-
 4 files changed, 99 insertions(+), 12 deletions(-)
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ReceivePack.java

diff --git a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
index 5fb0953..0e7e7d8 100644
--- a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
+++ b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
@@ -9,6 +9,7 @@ org.spearce.jgit.pgm.LsRemote
 org.spearce.jgit.pgm.LsTree
 org.spearce.jgit.pgm.MergeBase
 org.spearce.jgit.pgm.Push
+org.spearce.jgit.pgm.ReceivePack
 org.spearce.jgit.pgm.RevList
 org.spearce.jgit.pgm.Rm
 org.spearce.jgit.pgm.ShowRev
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Main.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Main.java
index c8bade8..8de4ae9 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Main.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Main.java
@@ -143,15 +143,18 @@ private void execute(final String[] argv) throws Exception {
 			System.exit(1);
 		}
 
-		if (gitdir == null)
-			gitdir = findGitDir();
-		if (gitdir == null || !gitdir.isDirectory()) {
-			System.err.println("error: can't find git directory");
-			System.exit(1);
-		}
-
 		final TextBuiltin cmd = subcommand;
-		cmd.init(new Repository(gitdir));
+		if (cmd.requiresRepository()) {
+			if (gitdir == null)
+				gitdir = findGitDir();
+			if (gitdir == null || !gitdir.isDirectory()) {
+				System.err.println("error: can't find git directory");
+				System.exit(1);
+			}
+			cmd.init(new Repository(gitdir), gitdir);
+		} else {
+			cmd.init(null, gitdir);
+		}
 		try {
 			cmd.execute(arguments.toArray(new String[arguments.size()]));
 		} finally {
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ReceivePack.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ReceivePack.java
new file mode 100644
index 0000000..579f893
--- /dev/null
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/ReceivePack.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.pgm;
+
+import java.io.File;
+
+import org.kohsuke.args4j.Argument;
+import org.spearce.jgit.lib.Repository;
+
+@Command(common = false, usage = "Server side backend for 'jgit push'")
+class ReceivePack extends TextBuiltin {
+	@Argument(index = 0, required = true, metaVar = "DIRECTORY", usage = "Repository to receive into")
+	File gitdir;
+
+	@Override
+	protected final boolean requiresRepository() {
+		return false;
+	}
+
+	@Override
+	protected void run() throws Exception {
+		final org.spearce.jgit.transport.ReceivePack rp;
+
+		if (new File(gitdir, ".git").isDirectory())
+			gitdir = new File(gitdir, ".git");
+		db = new Repository(gitdir);
+		if (!db.getObjectsDirectory().isDirectory())
+			throw die("'" + gitdir.getPath() + "' not a git repository");
+		rp = new org.spearce.jgit.transport.ReceivePack(db);
+		rp.receive(System.in, System.out, System.err);
+	}
+}
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
index 1f3a136..d3e32b3 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/TextBuiltin.java
@@ -43,6 +43,7 @@
 import static org.spearce.jgit.lib.Constants.R_TAGS;
 
 import java.io.BufferedWriter;
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
@@ -77,6 +78,9 @@
 	/** Git repository the command was invoked within. */
 	protected Repository db;
 
+	/** Directory supplied via --git-dir command line option. */
+	protected File gitdir;
+
 	/** RevWalk used during command line parsing, if it was required. */
 	protected RevWalk argWalk;
 
@@ -84,10 +88,15 @@ final void setCommandName(final String name) {
 		commandName = name;
 	}
 
-	void init(final Repository repo) {
+	/** @return true if {@link #db}/{@link #getRepository()} is required. */
+	protected boolean requiresRepository() {
+		return true;
+	}
+
+	void init(final Repository repo, final File gd) {
 		try {
-			String outputEncoding = repo.getConfig().getString("i18n", null,
-					"logOutputEncoding");
+			final String outputEncoding = repo != null ? repo.getConfig()
+					.getString("i18n", null, "logOutputEncoding") : null;
 			if (outputEncoding != null)
 				out = new PrintWriter(new BufferedWriter(
 						new OutputStreamWriter(System.out, outputEncoding)));
@@ -97,7 +106,14 @@ void init(final Repository repo) {
 		} catch (IOException e) {
 			throw die("cannot create output stream");
 		}
-		db = repo;
+
+		if (repo != null) {
+			db = repo;
+			gitdir = repo.getDirectory();
+		} else {
+			db = null;
+			gitdir = gd;
+		}
 	}
 
 	/**
-- 
1.6.1.rc4.301.g5497a

^ permalink raw reply related

* [JGIT PATCH 3/5] Modify "jgit daemon" so it can run outside of a repository
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git
In-Reply-To: <1230055423-9944-3-git-send-email-spearce@spearce.org>

We no longer export the current repository, but instead export the
directory trees given.  This behavior is more closely matches that
of "git daemon".

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/pgm/Daemon.java           |   33 +++++--------------
 1 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Daemon.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Daemon.java
index aafc82e..39b43b2 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Daemon.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Daemon.java
@@ -44,7 +44,6 @@
 
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
-import org.spearce.jgit.lib.Repository;
 import org.spearce.jgit.transport.DaemonService;
 
 @Command(common = true, usage = "Export repositories over git://")
@@ -67,10 +66,15 @@
 	@Option(name = "--forbid-override", metaVar = "SERVICE", usage = "configure the service in daemon.servicename", multiValued = true)
 	final List<String> forbidOverride = new ArrayList<String>();
 
-	@Argument(metaVar = "DIRECTORY", usage = "directories to export")
+	@Argument(required = true, metaVar = "DIRECTORY", usage = "directories to export")
 	final List<File> directory = new ArrayList<File>();
 
 	@Override
+	protected boolean requiresRepository() {
+		return false;
+	}
+
+	@Override
 	protected void run() throws Exception {
 		final org.spearce.jgit.transport.Daemon d;
 
@@ -88,13 +92,9 @@ protected void run() throws Exception {
 		for (final String n : forbidOverride)
 			service(d, n).setOverridable(false);
 
-		if (directory.isEmpty()) {
-			export(d, db);
-		} else {
-			for (final File f : directory) {
-				out.println("Exporting " + f.getAbsolutePath());
-				d.exportDirectory(f);
-			}
+		for (final File f : directory) {
+			out.println("Exporting " + f.getAbsolutePath());
+			d.exportDirectory(f);
 		}
 		d.start();
 		out.println("Listening on " + d.getAddress());
@@ -107,19 +107,4 @@ private DaemonService service(final org.spearce.jgit.transport.Daemon d,
 			throw die("Service '" + n + "' not supported");
 		return svc;
 	}
-
-	private void export(final org.spearce.jgit.transport.Daemon daemon,
-			final Repository repo) {
-		File d = repo.getDirectory();
-		String name = d.getName();
-		while (name.equals(".git") || name.equals(".")) {
-			d = d.getParentFile();
-			name = d.getName();
-		}
-		if (!name.endsWith(".git"))
-			name += ".git";
-
-		out.println("Exporting current repository as \"" + name + "\"");
-		daemon.exportRepository(name, repo);
-	}
 }
-- 
1.6.1.rc4.301.g5497a

^ permalink raw reply related

* [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git
In-Reply-To: <1230055423-9944-4-git-send-email-spearce@spearce.org>

The amazon-s3:// protocol is unique to JGit, and is not supported
by any other Git implementation.  The easiest way to clone off of
one of those URLs is to use "jgit clone".  This program also acts
as a simple example for any IDE developers who want to implement
a clone feature, as it is the minimum effort required to make a
user reasonably happy with the resulting repository.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../services/org.spearce.jgit.pgm.TextBuiltin      |    1 +
 .../org/spearce/jgit/pgm/AbstractFetchCommand.java |  126 ++++++++++++++
 .../src/org/spearce/jgit/pgm/Clone.java            |  177 ++++++++++++++++++++
 .../src/org/spearce/jgit/pgm/Fetch.java            |   83 +---------
 4 files changed, 306 insertions(+), 81 deletions(-)
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/AbstractFetchCommand.java
 create mode 100644 org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Clone.java

diff --git a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
index 4a2b605..40177f9 100644
--- a/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
+++ b/org.spearce.jgit.pgm/src/META-INF/services/org.spearce.jgit.pgm.TextBuiltin
@@ -1,4 +1,5 @@
 org.spearce.jgit.pgm.Branch
+org.spearce.jgit.pgm.Clone
 org.spearce.jgit.pgm.Daemon
 org.spearce.jgit.pgm.DiffTree
 org.spearce.jgit.pgm.Fetch
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/AbstractFetchCommand.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/AbstractFetchCommand.java
new file mode 100644
index 0000000..ea6f277
--- /dev/null
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/AbstractFetchCommand.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.pgm;
+
+import org.kohsuke.args4j.Option;
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.RefUpdate;
+import org.spearce.jgit.transport.FetchResult;
+import org.spearce.jgit.transport.TrackingRefUpdate;
+import org.spearce.jgit.transport.Transport;
+
+abstract class AbstractFetchCommand extends TextBuiltin {
+	@Option(name = "--verbose", aliases = { "-v" }, usage = "be more verbose")
+	private boolean verbose;
+
+	protected void showFetchResult(final Transport tn, final FetchResult r) {
+		boolean shownURI = false;
+		for (final TrackingRefUpdate u : r.getTrackingRefUpdates()) {
+			if (!verbose && u.getResult() == RefUpdate.Result.NO_CHANGE)
+				continue;
+
+			final char type = shortTypeOf(u.getResult());
+			final String longType = longTypeOf(u);
+			final String src = abbreviateRef(u.getRemoteName(), false);
+			final String dst = abbreviateRef(u.getLocalName(), true);
+
+			if (!shownURI) {
+				out.print("From ");
+				out.print(tn.getURI());
+				out.println();
+				shownURI = true;
+			}
+
+			out.format(" %c %-17s %-10s -> %s", type, longType, src, dst);
+			out.println();
+		}
+	}
+
+	private String longTypeOf(final TrackingRefUpdate u) {
+		final RefUpdate.Result r = u.getResult();
+		if (r == RefUpdate.Result.LOCK_FAILURE)
+			return "[lock fail]";
+
+		if (r == RefUpdate.Result.IO_FAILURE)
+			return "[i/o error]";
+
+		if (r == RefUpdate.Result.NEW) {
+			if (u.getRemoteName().startsWith(Constants.R_HEADS))
+				return "[new branch]";
+			else if (u.getLocalName().startsWith(Constants.R_TAGS))
+				return "[new tag]";
+			return "[new]";
+		}
+
+		if (r == RefUpdate.Result.FORCED) {
+			final String aOld = u.getOldObjectId().abbreviate(db).name();
+			final String aNew = u.getNewObjectId().abbreviate(db).name();
+			return aOld + "..." + aNew;
+		}
+
+		if (r == RefUpdate.Result.FAST_FORWARD) {
+			final String aOld = u.getOldObjectId().abbreviate(db).name();
+			final String aNew = u.getNewObjectId().abbreviate(db).name();
+			return aOld + ".." + aNew;
+		}
+
+		if (r == RefUpdate.Result.REJECTED)
+			return "[rejected]";
+		if (r == RefUpdate.Result.NO_CHANGE)
+			return "[up to date]";
+		return "[" + r.name() + "]";
+	}
+
+	private static char shortTypeOf(final RefUpdate.Result r) {
+		if (r == RefUpdate.Result.LOCK_FAILURE)
+			return '!';
+		if (r == RefUpdate.Result.IO_FAILURE)
+			return '!';
+		if (r == RefUpdate.Result.NEW)
+			return '*';
+		if (r == RefUpdate.Result.FORCED)
+			return '+';
+		if (r == RefUpdate.Result.FAST_FORWARD)
+			return ' ';
+		if (r == RefUpdate.Result.REJECTED)
+			return '!';
+		if (r == RefUpdate.Result.NO_CHANGE)
+			return '=';
+		return ' ';
+	}
+}
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Clone.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Clone.java
new file mode 100644
index 0000000..51dd95d
--- /dev/null
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Clone.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Git Development Community nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.spearce.jgit.pgm;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+import org.spearce.jgit.errors.NotSupportedException;
+import org.spearce.jgit.errors.TransportException;
+import org.spearce.jgit.lib.Commit;
+import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.GitIndex;
+import org.spearce.jgit.lib.Ref;
+import org.spearce.jgit.lib.RefComparator;
+import org.spearce.jgit.lib.RefUpdate;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.lib.TextProgressMonitor;
+import org.spearce.jgit.lib.Tree;
+import org.spearce.jgit.lib.WorkDirCheckout;
+import org.spearce.jgit.transport.FetchResult;
+import org.spearce.jgit.transport.RefSpec;
+import org.spearce.jgit.transport.RemoteConfig;
+import org.spearce.jgit.transport.Transport;
+import org.spearce.jgit.transport.URIish;
+
+@Command(common = true, usage = "Clone a repository into a new directory")
+class Clone extends AbstractFetchCommand {
+	@Option(name = "--origin", aliases = { "-o" }, metaVar = "name", usage = "use <name> instead of 'origin' to track upstream")
+	private String remoteName = "origin";
+
+	@Argument(index = 0, required = true, metaVar = "uri-ish")
+	private String sourceUri;
+
+	@Argument(index = 1, metaVar = "directory")
+	private String localName;
+
+	@Override
+	protected final boolean requiresRepository() {
+		return false;
+	}
+
+	@Override
+	protected void run() throws Exception {
+		if (localName != null && gitdir != null)
+			throw die("conflicting usage of --git-dir and arguments");
+
+		final URIish uri = new URIish(sourceUri);
+		if (localName == null) {
+			String p = uri.getPath();
+			while (p.endsWith("/"))
+				p = p.substring(0, p.length() - 1);
+			final int s = p.lastIndexOf('/');
+			if (s < 0)
+				throw die("cannot guess local name from " + sourceUri);
+			localName = p.substring(s + 1);
+			if (localName.endsWith(".git"))
+				localName = localName.substring(0, localName.length() - 4);
+		}
+		if (gitdir == null)
+			gitdir = new File(localName, ".git");
+		db = new Repository(gitdir);
+		db.create();
+		out.println("Initialized empty Git repository in "
+				+ gitdir.getAbsolutePath());
+		out.flush();
+
+		saveRemote(uri);
+		final FetchResult r = runFetch();
+		final Ref branch = guessHEAD(r);
+		doCheckout(branch);
+	}
+
+	private void saveRemote(final URIish uri) throws URISyntaxException,
+			IOException {
+		final RemoteConfig rc = new RemoteConfig(db.getConfig(), remoteName);
+		rc.addURI(uri);
+		rc.addFetchRefSpec(new RefSpec().setForceUpdate(true)
+				.setSourceDestination(Constants.R_HEADS + "*",
+						Constants.R_REMOTES + remoteName + "/*"));
+		rc.update(db.getConfig());
+		db.getConfig().save();
+	}
+
+	private FetchResult runFetch() throws NotSupportedException,
+			URISyntaxException, TransportException {
+		final Transport tn = Transport.open(db, remoteName);
+		final FetchResult r;
+		try {
+			r = tn.fetch(new TextProgressMonitor(), null);
+		} finally {
+			tn.close();
+		}
+		showFetchResult(tn, r);
+		return r;
+	}
+
+	private Ref guessHEAD(final FetchResult result) {
+		final Ref idHEAD = result.getAdvertisedRef(Constants.HEAD);
+		final List<Ref> availableRefs = new ArrayList<Ref>();
+		Ref head = null;
+		for (final Ref r : result.getAdvertisedRefs()) {
+			final String n = r.getName();
+			if (!n.startsWith(Constants.R_HEADS))
+				continue;
+			availableRefs.add(r);
+			if (idHEAD == null || head != null)
+				continue;
+			if (r.getObjectId().equals(idHEAD.getObjectId()))
+				head = r;
+		}
+		Collections.sort(availableRefs, RefComparator.INSTANCE);
+		if (idHEAD != null && head == null)
+			head = idHEAD;
+		return head;
+	}
+
+	private void doCheckout(final Ref branch) throws IOException {
+		if (branch == null)
+			throw die("cannot checkout; no HEAD advertised by remote");
+		if (!Constants.HEAD.equals(branch.getName()))
+			db.writeSymref(Constants.HEAD, branch.getName());
+
+		final Commit commit = db.mapCommit(branch.getObjectId());
+		final RefUpdate u = db.updateRef(Constants.HEAD);
+		u.setNewObjectId(commit.getCommitId());
+		u.forceUpdate();
+
+		final GitIndex index = new GitIndex(db);
+		final Tree tree = commit.getTree();
+		final WorkDirCheckout co;
+
+		co = new WorkDirCheckout(db, db.getWorkDir(), index, tree);
+		co.checkout();
+		index.write();
+	}
+}
diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Fetch.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Fetch.java
index e9d3260..8f3f7d5 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Fetch.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Fetch.java
@@ -41,19 +41,13 @@
 
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
-import org.spearce.jgit.lib.Constants;
-import org.spearce.jgit.lib.RefUpdate;
 import org.spearce.jgit.lib.TextProgressMonitor;
 import org.spearce.jgit.transport.FetchResult;
 import org.spearce.jgit.transport.RefSpec;
-import org.spearce.jgit.transport.TrackingRefUpdate;
 import org.spearce.jgit.transport.Transport;
 
 @Command(common = true, usage = "Update remote refs from another repository")
-class Fetch extends TextBuiltin {
-	@Option(name = "--verbose", aliases = { "-v" }, usage = "be more verbose")
-	private boolean verbose;
-
+class Fetch extends AbstractFetchCommand {
 	@Option(name = "--fsck", usage = "perform fsck style checks on receive")
 	private Boolean fsck;
 
@@ -91,79 +85,6 @@ protected void run() throws Exception {
 		} finally {
 			tn.close();
 		}
-
-		boolean shownURI = false;
-		for (final TrackingRefUpdate u : r.getTrackingRefUpdates()) {
-			if (!verbose && u.getResult() == RefUpdate.Result.NO_CHANGE)
-				continue;
-
-			final char type = shortTypeOf(u.getResult());
-			final String longType = longTypeOf(u);
-			final String src = abbreviateRef(u.getRemoteName(), false);
-			final String dst = abbreviateRef(u.getLocalName(), true);
-
-			if (!shownURI) {
-				out.print("From ");
-				out.print(tn.getURI());
-				out.println();
-				shownURI = true;
-			}
-
-			out.format(" %c %-17s %-10s -> %s", type, longType, src, dst);
-			out.println();
-		}
-	}
-
-	private String longTypeOf(final TrackingRefUpdate u) {
-		final RefUpdate.Result r = u.getResult();
-		if (r == RefUpdate.Result.LOCK_FAILURE)
-			return "[lock fail]";
-
-		if (r == RefUpdate.Result.IO_FAILURE)
-			return "[i/o error]";
-
-		if (r == RefUpdate.Result.NEW) {
-			if (u.getRemoteName().startsWith(Constants.R_HEADS))
-				return "[new branch]";
-			else if (u.getLocalName().startsWith(Constants.R_TAGS))
-				return "[new tag]";
-			return "[new]";
-		}
-
-		if (r == RefUpdate.Result.FORCED) {
-			final String aOld = u.getOldObjectId().abbreviate(db).name();
-			final String aNew = u.getNewObjectId().abbreviate(db).name();
-			return aOld + "..." + aNew;
-		}
-
-		if (r == RefUpdate.Result.FAST_FORWARD) {
-			final String aOld = u.getOldObjectId().abbreviate(db).name();
-			final String aNew = u.getNewObjectId().abbreviate(db).name();
-			return aOld + ".." + aNew;
-		}
-
-		if (r == RefUpdate.Result.REJECTED)
-			return "[rejected]";
-		if (r == RefUpdate.Result.NO_CHANGE)
-			return "[up to date]";
-		return "[" + r.name() + "]";
-	}
-
-	private static char shortTypeOf(final RefUpdate.Result r) {
-		if (r == RefUpdate.Result.LOCK_FAILURE)
-			return '!';
-		if (r == RefUpdate.Result.IO_FAILURE)
-			return '!';
-		if (r == RefUpdate.Result.NEW)
-			return '*';
-		if (r == RefUpdate.Result.FORCED)
-			return '+';
-		if (r == RefUpdate.Result.FAST_FORWARD)
-			return ' ';
-		if (r == RefUpdate.Result.REJECTED)
-			return '!';
-		if (r == RefUpdate.Result.NO_CHANGE)
-			return '=';
-		return ' ';
+		showFetchResult(tn, r);
 	}
 }
-- 
1.6.1.rc4.301.g5497a

^ permalink raw reply related

* [JGIT PATCH 5/5] Fix "fetch pulled too many objects" when auto-following tags
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git
In-Reply-To: <1230055423-9944-5-git-send-email-spearce@spearce.org>

If we don't take into consideration the objects obtained during
the first connection when we open a second to auto-follow tags
we will download a large chunk of the repository a second time.
This is very wasteful of network bandwidth, and is an abuse of
the server.

Because we delay all ref updates until the very end of the fetch
process we need to hold onto the set of objects we requested in
the first connection, and pass that set into the subsequent one
so it can be considered reachable.

Issue: http://code.google.com/p/egit/issues/detail?id=22
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../jgit/transport/BaseFetchConnection.java        |   26 ++++++++++++-------
 .../jgit/transport/BasePackFetchConnection.java    |   25 +++++++++++++++----
 .../spearce/jgit/transport/FetchConnection.java    |   21 +++++++++++----
 .../org/spearce/jgit/transport/FetchProcess.java   |    6 ++++-
 .../spearce/jgit/transport/TransportBundle.java    |    3 +-
 .../jgit/transport/WalkFetchConnection.java        |   14 ++++++++--
 6 files changed, 69 insertions(+), 26 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BaseFetchConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BaseFetchConnection.java
index 6709bfc..bb81296 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BaseFetchConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BaseFetchConnection.java
@@ -38,8 +38,10 @@
 package org.spearce.jgit.transport;
 
 import java.util.Collection;
+import java.util.Set;
 
 import org.spearce.jgit.errors.TransportException;
+import org.spearce.jgit.lib.ObjectId;
 import org.spearce.jgit.lib.ProgressMonitor;
 import org.spearce.jgit.lib.Ref;
 
@@ -54,9 +56,10 @@
 abstract class BaseFetchConnection extends BaseConnection implements
 		FetchConnection {
 	public final void fetch(final ProgressMonitor monitor,
-			final Collection<Ref> want) throws TransportException {
+			final Collection<Ref> want, final Set<ObjectId> have)
+			throws TransportException {
 		markStartedOperation();
-		doFetch(monitor, want);
+		doFetch(monitor, want, have);
 	}
 
 	/**
@@ -68,19 +71,22 @@ public boolean didFetchIncludeTags() {
 	}
 
 	/**
-	 * Implementation of {@link #fetch(ProgressMonitor, Collection)} without
-	 * checking for multiple fetch.
+	 * Implementation of {@link #fetch(ProgressMonitor, Collection, Set)}
+	 * without checking for multiple fetch.
 	 *
 	 * @param monitor
-	 *            as in {@link #fetch(ProgressMonitor, Collection)}
+	 *            as in {@link #fetch(ProgressMonitor, Collection, Set)}
 	 * @param want
-	 *            as in {@link #fetch(ProgressMonitor, Collection)}
+	 *            as in {@link #fetch(ProgressMonitor, Collection, Set)}
+	 * @param have
+	 *            as in {@link #fetch(ProgressMonitor, Collection, Set)}
 	 * @throws TransportException
-	 *             as in {@link #fetch(ProgressMonitor, Collection)}, but
+	 *             as in {@link #fetch(ProgressMonitor, Collection, Set)}, but
 	 *             implementation doesn't have to care about multiple
-	 *             {@link #fetch(ProgressMonitor, Collection)} calls, as it is
-	 *             checked in this class.
+	 *             {@link #fetch(ProgressMonitor, Collection, Set)} calls, as it
+	 *             is checked in this class.
 	 */
 	protected abstract void doFetch(final ProgressMonitor monitor,
-			final Collection<Ref> want) throws TransportException;
+			final Collection<Ref> want, final Set<ObjectId> have)
+			throws TransportException;
 }
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackFetchConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackFetchConnection.java
index 542a8a9..2cb9b64 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackFetchConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/BasePackFetchConnection.java
@@ -41,10 +41,12 @@
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Date;
+import java.util.Set;
 
 import org.spearce.jgit.errors.TransportException;
 import org.spearce.jgit.lib.AnyObjectId;
 import org.spearce.jgit.lib.MutableObjectId;
+import org.spearce.jgit.lib.ObjectId;
 import org.spearce.jgit.lib.ProgressMonitor;
 import org.spearce.jgit.lib.Ref;
 import org.spearce.jgit.revwalk.RevCommit;
@@ -137,9 +139,10 @@ BasePackFetchConnection(final PackTransport packTransport) {
 	}
 
 	public final void fetch(final ProgressMonitor monitor,
-			final Collection<Ref> want) throws TransportException {
+			final Collection<Ref> want, final Set<ObjectId> have)
+			throws TransportException {
 		markStartedOperation();
-		doFetch(monitor, want);
+		doFetch(monitor, want, have);
 	}
 
 	public boolean didFetchIncludeTags() {
@@ -151,10 +154,11 @@ public boolean didFetchTestConnectivity() {
 	}
 
 	protected void doFetch(final ProgressMonitor monitor,
-			final Collection<Ref> want) throws TransportException {
+			final Collection<Ref> want, final Set<ObjectId> have)
+			throws TransportException {
 		try {
 			markRefsAdvertised();
-			markReachable(maxTimeWanted(want));
+			markReachable(have, maxTimeWanted(want));
 
 			if (sendWants(want)) {
 				negotiate(monitor);
@@ -193,7 +197,8 @@ private int maxTimeWanted(final Collection<Ref> wants) {
 		return maxTime;
 	}
 
-	private void markReachable(final int maxTime) throws IOException {
+	private void markReachable(final Set<ObjectId> have, final int maxTime)
+			throws IOException {
 		for (final Ref r : local.getAllRefs().values()) {
 			try {
 				final RevCommit o = walk.parseCommit(r.getObjectId());
@@ -204,6 +209,16 @@ private void markReachable(final int maxTime) throws IOException {
 			}
 		}
 
+		for (final ObjectId id : have) {
+			try {
+				final RevCommit o = walk.parseCommit(id);
+				o.add(REACHABLE);
+				reachableCommits.add(o);
+			} catch (IOException readError) {
+				// If we cannot read the value of the ref skip it.
+			}
+		}
+
 		if (maxTime > 0) {
 			// Mark reachable commits until we reach maxTime. These may
 			// wind up later matching up against things we want and we
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchConnection.java
index a56ca6c..61ef219 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchConnection.java
@@ -38,8 +38,10 @@
 package org.spearce.jgit.transport;
 
 import java.util.Collection;
+import java.util.Set;
 
 import org.spearce.jgit.errors.TransportException;
+import org.spearce.jgit.lib.ObjectId;
 import org.spearce.jgit.lib.ProgressMonitor;
 import org.spearce.jgit.lib.Ref;
 
@@ -85,23 +87,29 @@
 	 * @param want
 	 *            one or more refs advertised by this connection that the caller
 	 *            wants to store locally.
+	 * @param have
+	 *            additional objects known to exist in the destination
+	 *            repository, especially if they aren't yet reachable by the ref
+	 *            database. Connections should take this set as an addition to
+	 *            what is reachable through all Refs, not in replace of it.
 	 * @throws TransportException
 	 *             objects could not be copied due to a network failure,
 	 *             protocol error, or error on remote side, or connection was
 	 *             already used for fetch.
 	 */
-	public void fetch(final ProgressMonitor monitor, final Collection<Ref> want)
+	public void fetch(final ProgressMonitor monitor,
+			final Collection<Ref> want, final Set<ObjectId> have)
 			throws TransportException;
 
 	/**
-	 * Did the last {@link #fetch(ProgressMonitor, Collection)} get tags?
+	 * Did the last {@link #fetch(ProgressMonitor, Collection, Set)} get tags?
 	 * <p>
 	 * Some Git aware transports are able to implicitly grab an annotated tag if
 	 * {@link TagOpt#AUTO_FOLLOW} or {@link TagOpt#FETCH_TAGS} was selected and
 	 * the object the tag peels to (references) was transferred as part of the
-	 * last {@link #fetch(ProgressMonitor, Collection)} call. If it is possible
-	 * for such tags to have been included in the transfer this method returns
-	 * true, allowing the caller to attempt tag discovery.
+	 * last {@link #fetch(ProgressMonitor, Collection, Set)} call. If it is
+	 * possible for such tags to have been included in the transfer this method
+	 * returns true, allowing the caller to attempt tag discovery.
 	 * <p>
 	 * By returning only true/false (and not the actual list of tags obtained)
 	 * the transport itself does not need to be aware of whether or not tags
@@ -113,7 +121,8 @@ public void fetch(final ProgressMonitor monitor, final Collection<Ref> want)
 	public boolean didFetchIncludeTags();
 
 	/**
-	 * Did the last {@link #fetch(ProgressMonitor, Collection)} validate graph?
+	 * Did the last {@link #fetch(ProgressMonitor, Collection, Set)} validate
+	 * graph?
 	 * <p>
 	 * Some transports walk the object graph on the client side, with the client
 	 * looking for what objects it is missing and requesting them individually
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
index bb2d051..09718eb 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
@@ -75,6 +75,9 @@
 	/** Set of refs we will actually wind up asking to obtain. */
 	private final HashMap<ObjectId, Ref> askFor = new HashMap<ObjectId, Ref>();
 
+	/** Objects we know we have locally. */
+	private final HashSet<ObjectId> have = new HashSet<ObjectId>();
+
 	/** Updates to local tracking branches (if any). */
 	private final ArrayList<TrackingRefUpdate> localUpdates = new ArrayList<TrackingRefUpdate>();
 
@@ -133,6 +136,7 @@ else if (tagopt == TagOpt.FETCH_TAGS)
 				// There are more tags that we want to follow, but
 				// not all were asked for on the initial request.
 				//
+				have.addAll(askFor.keySet());
 				askFor.clear();
 				for (final Ref r : additionalTags) {
 					final ObjectId id = r.getPeeledObjectId();
@@ -173,7 +177,7 @@ else if (tagopt == TagOpt.FETCH_TAGS)
 
 	private void fetchObjects(final ProgressMonitor monitor)
 			throws TransportException {
-		conn.fetch(monitor, askFor.values());
+		conn.fetch(monitor, askFor.values(), have);
 		if (transport.isCheckFetchedObjects()
 				&& !conn.didFetchTestConnectivity() && !askForIsComplete())
 			throw new TransportException(transport.getURI(),
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java
index 7d38b02..1734d94 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportBundle.java
@@ -171,7 +171,8 @@ public boolean didFetchTestConnectivity() {
 
 		@Override
 		protected void doFetch(final ProgressMonitor monitor,
-				final Collection<Ref> want) throws TransportException {
+				final Collection<Ref> want, final Set<ObjectId> have)
+				throws TransportException {
 			verifyPrerequisites();
 			try {
 				final IndexPack ip = newIndexPack();
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkFetchConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkFetchConnection.java
index d089f7b..91c5ea8 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkFetchConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkFetchConnection.java
@@ -195,8 +195,9 @@ public boolean didFetchTestConnectivity() {
 
 	@Override
 	protected void doFetch(final ProgressMonitor monitor,
-			final Collection<Ref> want) throws TransportException {
-		markLocalRefsComplete();
+			final Collection<Ref> want, final Set<ObjectId> have)
+			throws TransportException {
+		markLocalRefsComplete(have);
 		queueWants(want);
 
 		while (!monitor.isCancelled() && !workQueue.isEmpty()) {
@@ -642,7 +643,7 @@ private void saveLooseObject(final AnyObjectId id, final byte[] compressed)
 		return null;
 	}
 
-	private void markLocalRefsComplete() throws TransportException {
+	private void markLocalRefsComplete(final Set<ObjectId> have) throws TransportException {
 		for (final Ref r : local.getAllRefs().values()) {
 			try {
 				markLocalObjComplete(revWalk.parseAny(r.getObjectId()));
@@ -651,6 +652,13 @@ private void markLocalRefsComplete() throws TransportException {
 						+ " is missing object(s).", readError);
 			}
 		}
+		for (final ObjectId id : have) {
+			try {
+				markLocalObjComplete(revWalk.parseAny(id));
+			} catch (IOException readError) {
+				throw new TransportException("Missing assumed "+id.name(), readError);
+			}
+		}
 	}
 
 	private void markLocalObjComplete(RevObject obj) throws IOException {
-- 
1.6.1.rc4.301.g5497a

^ permalink raw reply related

* Re: [PATCH] strbuf_readlink semantics update.
From: Linus Torvalds @ 2008-12-23 18:16 UTC (permalink / raw)
  To: Pierre Habouzit; +Cc: git, Junio C Hamano
In-Reply-To: <20081223102127.GA21485@artemis.corp>



On Tue, 23 Dec 2008, Pierre Habouzit wrote:
>
> when readlink fails, the strbuf shall not be destroyed. It's not how
> read_file_or_gitlink works for example.

I disagree.

This patch just makes things worse. Just leave the "strbuf_release()" in 
_one_ place.

Look:

   6 files changed, 15 insertions(+), 5 deletions(-)

you added ten unnecessary lines, and you made the interface harder to use. 
What was the gain here?

> Fix read_old_data possible leaks in case of errors, since even when no
> data has been read, the strbufs may have grown to prepare the reads.
> strbuf_release must be called on them.

That's a separate error, and quite frankly, the best approach to that is 
likely to instead of breaking strbuf_readlink(), just make the S_IFREG() 
case release it.

I'd suggest that strbuf_read_file() should probably also do a 
strbuf_release() if it returns a negative error value, but that's a 
separate issue (and still leaves "read_old_data()" having to release 
things, since read_old_data() wants to see exactly st_size bytes. Although 
I suspect we might want to change that, and just make it test for 
negative too).

		Linus

^ permalink raw reply

* Re: 'Theirs' merge between branches on a binary file.
From: René Scharfe @ 2008-12-23 18:31 UTC (permalink / raw)
  To: Tim Visher; +Cc: Junio C Hamano, git
In-Reply-To: <c115fd3c0812230605x369af9c0n372db761fa11ce39@mail.gmail.com>

Tim Visher schrieb:
> I'm now working on
> compiling git under cygwin as the latest version cygwin installs for
> you is 0.4!

Have you seen msysgit (http://code.google.com/p/msysgit/), the easy
route to git on Windows?  It has all you need to check out and compile
the latest version of git.

René

^ 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