All of lore.kernel.org
 help / color / mirror / Atom feed
* [JGIT PATCH 0/5] Add jgit init, clone, receive-pack; transport fixes
@ 2008-12-23 18:03 Shawn O. Pearce
  2008-12-23 18:03 ` [JGIT PATCH 1/5] Add "jgit receive-pack" and permit commands to start not in a repository Shawn O. Pearce
  0 siblings, 1 reply; 13+ messages in thread
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	[flat|nested] 13+ messages in thread

* [JGIT PATCH 1/5] Add "jgit receive-pack" and permit commands to start not in a repository
  2008-12-23 18:03 [JGIT PATCH 0/5] Add jgit init, clone, receive-pack; transport fixes Shawn O. Pearce
@ 2008-12-23 18:03 ` Shawn O. Pearce
  2008-12-23 18:03   ` [JGIT PATCH 2/5] Add "jgit init" command to create a new repository Shawn O. Pearce
  0 siblings, 1 reply; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

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	[flat|nested] 13+ messages in thread

* [JGIT PATCH 2/5] Add "jgit init" command to create a new repository
  2008-12-23 18:03 ` [JGIT PATCH 1/5] Add "jgit receive-pack" and permit commands to start not in a repository Shawn O. Pearce
@ 2008-12-23 18:03   ` Shawn O. Pearce
  2008-12-23 18:03     ` [JGIT PATCH 3/5] Modify "jgit daemon" so it can run outside of a repository Shawn O. Pearce
  0 siblings, 1 reply; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

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	[flat|nested] 13+ messages in thread

* [JGIT PATCH 3/5] Modify "jgit daemon" so it can run outside of a repository
  2008-12-23 18:03   ` [JGIT PATCH 2/5] Add "jgit init" command to create a new repository Shawn O. Pearce
@ 2008-12-23 18:03     ` Shawn O. Pearce
  2008-12-23 18:03       ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Shawn O. Pearce
  0 siblings, 1 reply; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

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	[flat|nested] 13+ messages in thread

* [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific
  2008-12-23 18:03     ` [JGIT PATCH 3/5] Modify "jgit daemon" so it can run outside of a repository Shawn O. Pearce
@ 2008-12-23 18:03       ` Shawn O. Pearce
  2008-12-23 18:03         ` [JGIT PATCH 5/5] Fix "fetch pulled too many objects" when auto-following tags Shawn O. Pearce
  2008-12-31  7:12         ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Robin Rosenberg
  0 siblings, 2 replies; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

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	[flat|nested] 13+ messages in thread

* [JGIT PATCH 5/5] Fix "fetch pulled too many objects" when auto-following tags
  2008-12-23 18:03       ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Shawn O. Pearce
@ 2008-12-23 18:03         ` Shawn O. Pearce
  2008-12-31  7:12         ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Robin Rosenberg
  1 sibling, 0 replies; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-23 18:03 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

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	[flat|nested] 13+ messages in thread

* Re: [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific
  2008-12-23 18:03       ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Shawn O. Pearce
  2008-12-23 18:03         ` [JGIT PATCH 5/5] Fix "fetch pulled too many objects" when auto-following tags Shawn O. Pearce
@ 2008-12-31  7:12         ` Robin Rosenberg
  2008-12-31  7:35           ` Shawn O. Pearce
  1 sibling, 1 reply; 13+ messages in thread
From: Robin Rosenberg @ 2008-12-31  7:12 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

Would it be hard to get the progress look better?

-- robin

EGIT.contrib/jgit clone git://repo.or.cz/libgit2.git LIBGIT2
Initialized empty Git repository in /home/me/SW/LIBGIT2/.git                  
Counting objects:       547                                                   
Compressing objects:    100% (192/192)                                        
ts:                     100% (192/192)                                        
Compressing objects:    100% (192/192)                                        
ng objects:             100% (192/192)                                        
Compressing objects:    100% (192/192)                                        
bjects:                 100% (192/192)                                        
Compressing objects:    100% (192/192)
pressing objects:       100% (192/192)
ts:                     100% (192/192)
Compressing objects:    100% (192/192)
Receiving objects:      100% (547/547)
jects:                  100% (192/192)
Compressing objects:    100% (192/192)
ressing objects:        100% (192/192)
s:                      100% (192/192)
Compressing objects:    100% (192/192)
ssing objects:          100% (192/192)
ts:                     100% (192/192)
Compressing objects:    100% (192/192)
 objects:               100% (192/192)
Compressing objects:    100% (192/192)
essing objects:         100% (192/192)
cts:                    100% (192/192)
Compressing objects:    100% (192/192)
g objects:              100% (192/192)
Compressing objects:    100% (192/192)
ressing objects:        100% (192/192)
Resolving deltas:       100% (358/358)
From git://repo.or.cz/libgit2.git
 * [new branch]      master     -> origin/master

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific
  2008-12-31  7:12         ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Robin Rosenberg
@ 2008-12-31  7:35           ` Shawn O. Pearce
  2008-12-31 19:04             ` [JGIT PATCH] Improve the sideband progress scaper to be more accurate Shawn O. Pearce
  0 siblings, 1 reply; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-31  7:35 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

Robin Rosenberg <robin.rosenberg@dewire.com> wrote:
> Would it be hard to get the progress look better?

This happens because we are scanning the progress channel wrong in
some cases.  Its random; most of the time we can get it right, but
every once in a while we get out of sync and get these short names.

This is a general problem with the progress client side code, not
the new server side code I've introduced.  We also see it going
against a standard C git daemon.  I haven't been able to figure
out a way to smooth out the messages.

FWIW, git-gui also gets this sort of progress corruption sometimes
when it does a clone.  So I've reproduced the same parsing bug in
two different languages and two different implementations... ;-)

 
> EGIT.contrib/jgit clone git://repo.or.cz/libgit2.git LIBGIT2
> Initialized empty Git repository in /home/me/SW/LIBGIT2/.git                  
> Counting objects:       547                                                   
> Compressing objects:    100% (192/192)                                        
> ts:                     100% (192/192)                                        
> Compressing objects:    100% (192/192)                                        
> ng objects:             100% (192/192)                                        
> Compressing objects:    100% (192/192)                                        
> bjects:                 100% (192/192)                                        
> Compressing objects:    100% (192/192)
> pressing objects:       100% (192/192)
> ts:                     100% (192/192)
> Compressing objects:    100% (192/192)
> Receiving objects:      100% (547/547)
> jects:                  100% (192/192)
> Compressing objects:    100% (192/192)
> ressing objects:        100% (192/192)
> s:                      100% (192/192)
> Compressing objects:    100% (192/192)
> ssing objects:          100% (192/192)
> ts:                     100% (192/192)
> Compressing objects:    100% (192/192)
>  objects:               100% (192/192)
> Compressing objects:    100% (192/192)
> essing objects:         100% (192/192)
> cts:                    100% (192/192)
> Compressing objects:    100% (192/192)
> g objects:              100% (192/192)
> Compressing objects:    100% (192/192)
> ressing objects:        100% (192/192)
> Resolving deltas:       100% (358/358)
> From git://repo.or.cz/libgit2.git
>  * [new branch]      master     -> origin/master

-- 
Shawn.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [JGIT PATCH] Improve the sideband progress scaper to be more accurate
  2008-12-31  7:35           ` Shawn O. Pearce
@ 2008-12-31 19:04             ` Shawn O. Pearce
  2009-01-03 22:12               ` Robin Rosenberg
  0 siblings, 1 reply; 13+ messages in thread
From: Shawn O. Pearce @ 2008-12-31 19:04 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

By matching only whole lines we should be able to improve the
progress scaper so we avoid ugly output like we had been seeing:

  EGIT.contrib/jgit clone git://repo.or.cz/libgit2.git LIBGIT2
  Initialized empty Git repository in /home/me/SW/LIBGIT2/.git
  Counting objects:       547
  Compressing objects:    100% (192/192)
  ts:                     100% (192/192)
  Compressing objects:    100% (192/192)
  ng objects:             100% (192/192)

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 Robin Rosenberg <robin.rosenberg@dewire.com> wrote:
 > Would it be hard to get the progress look better?

 Maybe this does the trick.  Its hard to reproduce so its hard to
 come up with the condition that was giving us the problem before.
 I suspect its because we were getting line fragments on the sideband
 channel, but I'm not sure that was really the case.

 .../jgit/transport/SideBandInputStream.java        |   37 +++++++++++++++++--
 1 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/SideBandInputStream.java b/org.spearce.jgit/src/org/spearce/jgit/transport/SideBandInputStream.java
index 3ec9bff..f0ba3d3 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/SideBandInputStream.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/SideBandInputStream.java
@@ -73,10 +73,10 @@
 	private static final int CH_ERROR = 3;
 
 	private static Pattern P_UNBOUNDED = Pattern.compile(
-			".*?([\\w ]+): (\\d+)(, done)?.*", Pattern.DOTALL);
+			"^([\\w ]+): (\\d+)( |, done)?.*", Pattern.DOTALL);
 
 	private static Pattern P_BOUNDED = Pattern.compile(
-			".*?([\\w ]+):.*\\((\\d+)/(\\d+)\\).*", Pattern.DOTALL);
+			"^([\\w ]+):.*\\((\\d+)/(\\d+)\\).*", Pattern.DOTALL);
 
 	private final PacketLineIn pckIn;
 
@@ -84,6 +84,8 @@
 
 	private final ProgressMonitor monitor;
 
+	private String progressBuffer = "";
+
 	private String currentTask;
 
 	private int lastCnt;
@@ -160,7 +162,31 @@ private void needDataPacket() throws IOException {
 		}
 	}
 
-	private void progress(final String msg) {
+	private void progress(String pkt) {
+		pkt = progressBuffer + pkt;
+		for (;;) {
+			final int lf = pkt.indexOf('\n');
+			final int cr = pkt.indexOf('\r');
+			final int s;
+			if (0 <= lf && 0 <= cr)
+				s = Math.min(lf, cr);
+			else if (0 <= lf)
+				s = lf;
+			else if (0 <= cr)
+				s = cr;
+			else
+				break;
+
+			final String msg = pkt.substring(0, s);
+			if (doProgressLine(msg))
+				pkt = pkt.substring(s + 1);
+			else
+				break;
+		}
+		progressBuffer = pkt;
+	}
+
+	private boolean doProgressLine(final String msg) {
 		Matcher matcher;
 
 		matcher = P_BOUNDED.matcher(msg);
@@ -175,7 +201,7 @@ private void progress(final String msg) {
 			final int cnt = Integer.parseInt(matcher.group(2));
 			monitor.update(cnt - lastCnt);
 			lastCnt = cnt;
-			return;
+			return true;
 		}
 
 		matcher = P_UNBOUNDED.matcher(msg);
@@ -189,7 +215,10 @@ private void progress(final String msg) {
 			final int cnt = Integer.parseInt(matcher.group(2));
 			monitor.update(cnt - lastCnt);
 			lastCnt = cnt;
+			return true;
 		}
+
+		return false;
 	}
 
 	private String readString(final int len) throws IOException {
-- 
1.6.1.59.g6f6746


-- 
Shawn.

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [JGIT PATCH] Improve the sideband progress scaper to be more accurate
  2008-12-31 19:04             ` [JGIT PATCH] Improve the sideband progress scaper to be more accurate Shawn O. Pearce
@ 2009-01-03 22:12               ` Robin Rosenberg
  2009-01-06 19:23                 ` Nicolas Pitre
  0 siblings, 1 reply; 13+ messages in thread
From: Robin Rosenberg @ 2009-01-03 22:12 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

onsdag 31 december 2008 20:04:01 skrev Shawn O. Pearce:
> By matching only whole lines we should be able to improve the
> progress scaper so we avoid ugly output like we had been seeing:
> 
>   EGIT.contrib/jgit clone git://repo.or.cz/libgit2.git LIBGIT2
>   Initialized empty Git repository in /home/me/SW/LIBGIT2/.git
>   Counting objects:       547
>   Compressing objects:    100% (192/192)
>   ts:                     100% (192/192)
>   Compressing objects:    100% (192/192)
>   ng objects:             100% (192/192)
> 
> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
> ---
>  Robin Rosenberg <robin.rosenberg@dewire.com> wrote:
>  > Would it be hard to get the progress look better?
> 
>  Maybe this does the trick.  Its hard to reproduce so its hard to
>  come up with the condition that was giving us the problem before.
>  I suspect its because we were getting line fragments on the sideband
>  channel, but I'm not sure that was really the case.

Nasty. I couldn't reproduce it myself. I'll hold onto this one for a while and
see if I'll get the opportunity to test it live with this problem.

-- robin

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [JGIT PATCH] Improve the sideband progress scaper to be more accurate
  2009-01-03 22:12               ` Robin Rosenberg
@ 2009-01-06 19:23                 ` Nicolas Pitre
  2009-01-06 19:27                   ` Shawn O. Pearce
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Pitre @ 2009-01-06 19:23 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: Shawn O. Pearce, git

On Sat, 3 Jan 2009, Robin Rosenberg wrote:

> onsdag 31 december 2008 20:04:01 skrev Shawn O. Pearce:
> > By matching only whole lines we should be able to improve the
> > progress scaper so we avoid ugly output like we had been seeing:
> > 
> >   EGIT.contrib/jgit clone git://repo.or.cz/libgit2.git LIBGIT2
> >   Initialized empty Git repository in /home/me/SW/LIBGIT2/.git
> >   Counting objects:       547
> >   Compressing objects:    100% (192/192)
> >   ts:                     100% (192/192)
> >   Compressing objects:    100% (192/192)
> >   ng objects:             100% (192/192)
> > 
> > Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
> > ---
> >  Robin Rosenberg <robin.rosenberg@dewire.com> wrote:
> >  > Would it be hard to get the progress look better?
> > 
> >  Maybe this does the trick.  Its hard to reproduce so its hard to
> >  come up with the condition that was giving us the problem before.
> >  I suspect its because we were getting line fragments on the sideband
> >  channel, but I'm not sure that was really the case.
> 
> Nasty. I couldn't reproduce it myself. I'll hold onto this one for a while and
> see if I'll get the opportunity to test it live with this problem.

There may indeed be line fragments sent over the sideband channel, as 
well as the opposite which is multiple lines sent at once in a single 
packet.  If you look at sideband.c you'll find about all those cases.

In general, what you have to do is:

 - for each packet:
   - split into multiple chunks on line breaks ('\r' or '\n')
   - for each chunk:
     - if last chunk didn't end with a line break, or if current 
       chunk is empty or only contains a line break, then skip printing 
       the "remote:" prefix.  Otherwise print it.
     - print the current chunk up to any line break
     - if current chunk contains a line break and other characters then
       print a sequence to clear the remaining of the screen line
     - print the line break if any

That should cover all cases.  Note that the case where a previous chunk 
didn't end with a line break is always seen when moving from one packet 
to another, so that state cannot be local to the inner loop.


Nicolas

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [JGIT PATCH] Improve the sideband progress scaper to be more accurate
  2009-01-06 19:23                 ` Nicolas Pitre
@ 2009-01-06 19:27                   ` Shawn O. Pearce
  2009-01-06 20:55                     ` Nicolas Pitre
  0 siblings, 1 reply; 13+ messages in thread
From: Shawn O. Pearce @ 2009-01-06 19:27 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Robin Rosenberg, git

Nicolas Pitre <nico@cam.org> wrote:
> There may indeed be line fragments sent over the sideband channel, as 
> well as the opposite which is multiple lines sent at once in a single 
> packet.  If you look at sideband.c you'll find about all those cases.

Thanks, that's what I thought...
 
> In general, what you have to do is:
> 
>  - for each packet:
>    - split into multiple chunks on line breaks ('\r' or '\n')
>    - for each chunk:
>      - if last chunk didn't end with a line break, or if current 
>        chunk is empty or only contains a line break, then skip printing 
>        the "remote:" prefix.  Otherwise print it.
>      - print the current chunk up to any line break
>      - if current chunk contains a line break and other characters then
>        print a sequence to clear the remaining of the screen line
>      - print the line break if any

Hmm.  I should note that C Git still screws this up sometimes.  I've
seen 1.6.1 git fetch mess up the output from repo.or.cz's sideband.
I'm sure Pasky isn't running JGit's daemon, its too damn fast. :-)

I don't have a spew of it handy, but late last week I saw it screw
up while doing a clone off repo.or.cz.

Robin, maybe we should apply this patch?  Its along the lines
Nico is describing above, but because our progress code doesn't do
direct display its a little less complex, we don't have to worry
about clearing the current line.  But I think I'm doing the chunk
splitting and filtering he's talking about.

-- 
Shawn.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [JGIT PATCH] Improve the sideband progress scaper to be more accurate
  2009-01-06 19:27                   ` Shawn O. Pearce
@ 2009-01-06 20:55                     ` Nicolas Pitre
  0 siblings, 0 replies; 13+ messages in thread
From: Nicolas Pitre @ 2009-01-06 20:55 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Robin Rosenberg, git

On Tue, 6 Jan 2009, Shawn O. Pearce wrote:

> Nicolas Pitre <nico@cam.org> wrote:
> > There may indeed be line fragments sent over the sideband channel, as 
> > well as the opposite which is multiple lines sent at once in a single 
> > packet.  If you look at sideband.c you'll find about all those cases.
> 
> Thanks, that's what I thought...
>  
> > In general, what you have to do is:
> > 
> >  - for each packet:
> >    - split into multiple chunks on line breaks ('\r' or '\n')
> >    - for each chunk:
> >      - if last chunk didn't end with a line break, or if current 
> >        chunk is empty or only contains a line break, then skip printing 
> >        the "remote:" prefix.  Otherwise print it.
> >      - print the current chunk up to any line break
> >      - if current chunk contains a line break and other characters then
> >        print a sequence to clear the remaining of the screen line
> >      - print the line break if any
> 
> Hmm.  I should note that C Git still screws this up sometimes.  I've
> seen 1.6.1 git fetch mess up the output from repo.or.cz's sideband.
> I'm sure Pasky isn't running JGit's daemon, its too damn fast. :-)
> 
> I don't have a spew of it handy, but late last week I saw it screw
> up while doing a clone off repo.or.cz.

Next time you see such things please send me a snapshot.

What is still possible and IMHO not worth the effort to fix is some 
interaction between local and remote displays which, if intermixed in 
some unlucky way, do screw up the final appearance.  For example, if the 
remote has sent a partial line, and before the remaining of it is 
received/printed you actually have some local process also displaying a 
line of its own.  If that was to become a real issue, then the fix would 
involve caching any partial line sent from the remote until the 
associated line break is received.


Nicolas

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2009-01-06 20:56 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-12-23 18:03 [JGIT PATCH 0/5] Add jgit init, clone, receive-pack; transport fixes Shawn O. Pearce
2008-12-23 18:03 ` [JGIT PATCH 1/5] Add "jgit receive-pack" and permit commands to start not in a repository Shawn O. Pearce
2008-12-23 18:03   ` [JGIT PATCH 2/5] Add "jgit init" command to create a new repository Shawn O. Pearce
2008-12-23 18:03     ` [JGIT PATCH 3/5] Modify "jgit daemon" so it can run outside of a repository Shawn O. Pearce
2008-12-23 18:03       ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Shawn O. Pearce
2008-12-23 18:03         ` [JGIT PATCH 5/5] Fix "fetch pulled too many objects" when auto-following tags Shawn O. Pearce
2008-12-31  7:12         ` [JGIT PATCH 4/5] Add "jgit clone" to support cloning off URLs that are JGit specific Robin Rosenberg
2008-12-31  7:35           ` Shawn O. Pearce
2008-12-31 19:04             ` [JGIT PATCH] Improve the sideband progress scaper to be more accurate Shawn O. Pearce
2009-01-03 22:12               ` Robin Rosenberg
2009-01-06 19:23                 ` Nicolas Pitre
2009-01-06 19:27                   ` Shawn O. Pearce
2009-01-06 20:55                     ` Nicolas Pitre

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.