git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] jgit: Branch command now supports deletion
@ 2008-08-14 10:13 Charles O'Farrell
  2008-08-14 10:13 ` [PATCH 1/7] Refactor of WalkRemoteObjectDatabase ref writing into common class Charles O'Farrell
  2008-08-15  0:25 ` [JGIT PATCH v2 " Charles O'Farrell
  0 siblings, 2 replies; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Implement branch deletion for jgit, reusing previous packed-refs writing

Charles O'Farrell (7):
  Refactor of WalkRemoteObjectDatabase ref writing into common class
  Refactor of RefUpdate force to call common updateImpl instead of
    duplication
  Minor refactor of constants, including log and ROOT_DIR
  Extract lockAndWriteFile method in RefDatabase for reuse
  Added removePackedRef method to RefDatabase for packed branch
    deletion
  Added ref deletion to RefUpdate
  jgit: Added branch deletion to jgit command

 .../src/org/spearce/jgit/pgm/Branch.java           |   57 ++++++-
 .../src/org/spearce/jgit/lib/Constants.java        |    9 +
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   41 ++++--
 .../src/org/spearce/jgit/lib/RefLogWriter.java     |    2 +-
 .../src/org/spearce/jgit/lib/RefUpdate.java        |  106 ++++++++----
 .../src/org/spearce/jgit/lib/RefWriter.java        |  175 ++++++++++++++++++++
 .../src/org/spearce/jgit/lib/Repository.java       |    2 +-
 .../spearce/jgit/transport/TransportAmazonS3.java  |   10 +-
 .../org/spearce/jgit/transport/TransportSftp.java  |    6 +-
 .../spearce/jgit/transport/WalkPushConnection.java |   18 ++-
 .../jgit/transport/WalkRemoteObjectDatabase.java   |  110 +-----------
 11 files changed, 374 insertions(+), 162 deletions(-)
 create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/RefWriter.java

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

* [PATCH 1/7] Refactor of WalkRemoteObjectDatabase ref writing into common class
  2008-08-14 10:13 [PATCH 0/7] jgit: Branch command now supports deletion Charles O'Farrell
@ 2008-08-14 10:13 ` Charles O'Farrell
  2008-08-14 10:13   ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Charles O'Farrell
  2008-08-15  0:25 ` [JGIT PATCH v2 " Charles O'Farrell
  1 sibling, 1 reply; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

In particular writeInfoRefs and writePackedRefs into common RefWriter
class for reuse with branch deletion in jgit.

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/Constants.java        |    6 +
 .../src/org/spearce/jgit/lib/RefWriter.java        |  175 ++++++++++++++++++++
 .../spearce/jgit/transport/WalkPushConnection.java |   12 +-
 .../jgit/transport/WalkRemoteObjectDatabase.java   |   94 -----------
 4 files changed, 191 insertions(+), 96 deletions(-)
 create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/RefWriter.java

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
index 7c2cef9..7bbd88e 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
@@ -214,6 +214,12 @@ public final class Constants {
 	/** Prefix for tag refs */
 	public static final String TAGS_PREFIX = "refs/tags";
 
+	/** Info refs folder */
+	public static final String INFO_REFS = "info/refs";
+
+	/** Packed refs file */
+	public static final String PACKED_REFS = "packed-refs";
+
 	/**
 	 * Create a new digest function for objects.
 	 * 
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefWriter.java
new file mode 100644
index 0000000..9c784d5
--- /dev/null
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefWriter.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Charles O'Farrell <charleso@charleso.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.lib;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.TreeSet;
+
+/**
+ * Writes out refs to the {@link Constants#INFO_REFS} and
+ * {@link Constants#PACKED_REFS} files.
+ * 
+ * This class is abstract as the writing of the files must be handled by the
+ * caller. This is because it is used by transport classes as well.
+ */
+public abstract class RefWriter {
+
+	private final Collection<Ref> refs;
+
+	/**
+	 * @param refs
+	 *            the complete set of references. This should have been computed
+	 *            by applying updates to the advertised refs already discovered.
+	 */
+	public RefWriter(Collection<Ref> refs) {
+		this.refs = new TreeSet<Ref>(RefComparator.INSTANCE);
+		this.refs.addAll(refs);
+	}
+
+	/**
+	 * Rebuild the {@link Constants#INFO_REFS}.
+	 * <p>
+	 * This method rebuilds the contents of the {@link Constants#INFO_REFS} file
+	 * to match the passed list of references.
+	 * 
+	 * 
+	 * @throws IOException
+	 *             writing is not supported, or attempting to write the file
+	 *             failed, possibly due to permissions or remote disk full, etc.
+	 */
+	public void writeInfoRefs() throws IOException {
+		final StringWriter w = new StringWriter();
+		final char[] tmp = new char[Constants.OBJECT_ID_LENGTH * 2];
+		for (final Ref r : refs) {
+			if (Constants.HEAD.equals(r.getName())) {
+				// Historically HEAD has never been published through
+				// the INFO_REFS file. This is a mistake, but its the
+				// way things are.
+				//
+				continue;
+			}
+
+			r.getObjectId().copyTo(tmp, w);
+			w.write('\t');
+			w.write(r.getName());
+			w.write('\n');
+
+			if (r.getPeeledObjectId() != null) {
+				r.getPeeledObjectId().copyTo(tmp, w);
+				w.write('\t');
+				w.write(r.getName());
+				w.write("^{}\n");
+			}
+		}
+		writeFile(Constants.INFO_REFS, Constants.encodeASCII(w.toString()));
+	}
+
+	/**
+	 * Rebuild the {@link Constants#PACKED_REFS} file.
+	 * <p>
+	 * This method rebuilds the contents of the {@link Constants#PACKED_REFS}
+	 * file to match the passed list of references, including only those refs
+	 * that have a storage type of {@link Ref.Storage#PACKED}.
+	 * 
+	 * @throws IOException
+	 *             writing is not supported, or attempting to write the file
+	 *             failed, possibly due to permissions or remote disk full, etc.
+	 */
+	public void writePackedRefs() throws IOException {
+		boolean peeled = false;
+
+		for (final Ref r : refs) {
+			if (r.getStorage() != Ref.Storage.PACKED)
+				continue;
+			if (r.getPeeledObjectId() != null)
+				peeled = true;
+		}
+
+		final StringWriter w = new StringWriter();
+		if (peeled) {
+			w.write("# pack-refs with:");
+			if (peeled)
+				w.write(" peeled");
+			w.write('\n');
+		}
+
+		final char[] tmp = new char[Constants.OBJECT_ID_LENGTH * 2];
+		for (final Ref r : refs) {
+			if (r.getStorage() != Ref.Storage.PACKED)
+				continue;
+
+			r.getObjectId().copyTo(tmp, w);
+			w.write(' ');
+			w.write(r.getName());
+			w.write('\n');
+
+			if (r.getPeeledObjectId() != null) {
+				w.write('^');
+				r.getPeeledObjectId().copyTo(tmp, w);
+				w.write('\n');
+			}
+		}
+		writeFile(Constants.PACKED_REFS, Constants.encodeASCII(w.toString()));
+	}
+
+	/**
+	 * Handles actual writing of ref files to the git repository, which may
+	 * differ slightly depending on the destination and transport.
+	 * 
+	 * @param file
+	 *            path to ref file.
+	 * @param content
+	 *            byte content of file to be written.
+	 * @throws IOException
+	 */
+	protected abstract void writeFile(String file, byte[] content)
+			throws IOException;
+
+	private static class RefComparator implements Comparator<Ref> {
+
+		private static final RefComparator INSTANCE = new RefComparator();
+
+		public int compare(Ref o1, Ref o2) {
+			return o1.getName().compareTo(o2.getName());
+		}
+	}
+}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java
index 904a699..19071d7 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java
@@ -53,6 +53,7 @@ import org.spearce.jgit.lib.ObjectId;
 import org.spearce.jgit.lib.PackWriter;
 import org.spearce.jgit.lib.ProgressMonitor;
 import org.spearce.jgit.lib.Ref;
+import org.spearce.jgit.lib.RefWriter;
 import org.spearce.jgit.lib.Repository;
 import org.spearce.jgit.lib.Ref.Storage;
 import org.spearce.jgit.transport.RemoteRefUpdate.Status;
@@ -158,9 +159,16 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
 		if (!updates.isEmpty() && isNewRepository())
 			createNewRepository(updates);
 
+		RefWriter refWriter = new RefWriter(newRefs.values()) {
+			@Override
+			protected void writeFile(String file, byte[] content)
+					throws IOException {
+				dest.writeFile("../" + file, content);
+			}
+		};
 		if (!packedRefUpdates.isEmpty()) {
 			try {
-				dest.writePackedRefs(newRefs.values());
+				refWriter.writePackedRefs();
 				for (final RemoteRefUpdate u : packedRefUpdates)
 					u.setStatus(Status.OK);
 			} catch (IOException err) {
@@ -173,7 +181,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
 		}
 
 		try {
-			dest.writeInfoRefs(newRefs.values());
+			refWriter.writeInfoRefs();
 		} catch (IOException err) {
 			throw new TransportException(uri, "failed updating refs", err);
 		}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
index c5a5199..25640dc 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
@@ -44,7 +44,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Map;
@@ -337,99 +336,6 @@ abstract class WalkRemoteObjectDatabase {
 	}
 
 	/**
-	 * Rebuild the {@link #INFO_REFS} for dumb transport clients.
-	 * <p>
-	 * This method rebuilds the contents of the {@link #INFO_REFS} file to match
-	 * the passed list of references.
-	 *
-	 * @param refs
-	 *            the complete set of references the remote side now has. This
-	 *            should have been computed by applying updates to the
-	 *            advertised refs already discovered.
-	 * @throws IOException
-	 *             writing is not supported, or attempting to write the file
-	 *             failed, possibly due to permissions or remote disk full, etc.
-	 */
-	void writeInfoRefs(final Collection<Ref> refs) throws IOException {
-		final StringWriter w = new StringWriter();
-		final char[] tmp = new char[Constants.OBJECT_ID_LENGTH * 2];
-		for (final Ref r : refs) {
-			if (Constants.HEAD.equals(r.getName())) {
-				// Historically HEAD has never been published through
-				// the INFO_REFS file. This is a mistake, but its the
-				// way things are.
-				//
-				continue;
-			}
-
-			r.getObjectId().copyTo(tmp, w);
-			w.write('\t');
-			w.write(r.getName());
-			w.write('\n');
-
-			if (r.getPeeledObjectId() != null) {
-				r.getPeeledObjectId().copyTo(tmp, w);
-				w.write('\t');
-				w.write(r.getName());
-				w.write("^{}\n");
-			}
-		}
-		writeFile(INFO_REFS, Constants.encodeASCII(w.toString()));
-	}
-
-	/**
-	 * Rebuild the {@link #PACKED_REFS} file.
-	 * <p>
-	 * This method rebuilds the contents of the {@link #PACKED_REFS} file to
-	 * match the passed list of references, including only those refs that have
-	 * a storage type of {@link Ref.Storage#PACKED}.
-	 *
-	 * @param refs
-	 *            the complete set of references the remote side now has. This
-	 *            should have been computed by applying updates to the
-	 *            advertised refs already discovered.
-	 * @throws IOException
-	 *             writing is not supported, or attempting to write the file
-	 *             failed, possibly due to permissions or remote disk full, etc.
-	 */
-	void writePackedRefs(final Collection<Ref> refs) throws IOException {
-		boolean peeled = false;
-
-		for (final Ref r : refs) {
-			if (r.getStorage() != Ref.Storage.PACKED)
-				continue;
-			if (r.getPeeledObjectId() != null)
-				peeled = true;
-		}
-
-		final StringWriter w = new StringWriter();
-		if (peeled) {
-			w.write("# pack-refs with:");
-			if (peeled)
-				w.write(" peeled");
-			w.write('\n');
-		}
-
-		final char[] tmp = new char[Constants.OBJECT_ID_LENGTH * 2];
-		for (final Ref r : refs) {
-			if (r.getStorage() != Ref.Storage.PACKED)
-				continue;
-
-			r.getObjectId().copyTo(tmp, w);
-			w.write(' ');
-			w.write(r.getName());
-			w.write('\n');
-
-			if (r.getPeeledObjectId() != null) {
-				w.write('^');
-				r.getPeeledObjectId().copyTo(tmp, w);
-				w.write('\n');
-			}
-		}
-		writeFile(PACKED_REFS, Constants.encodeASCII(w.toString()));
-	}
-
-	/**
 	 * Open a buffered reader around a file.
 	 * <p>
 	 * This is shorthand for calling {@link #open(String)} and then wrapping it
-- 
1.6.0.rc2.35.g04c6e

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

* [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication
  2008-08-14 10:13 ` [PATCH 1/7] Refactor of WalkRemoteObjectDatabase ref writing into common class Charles O'Farrell
@ 2008-08-14 10:13   ` Charles O'Farrell
  2008-08-14 10:13     ` [PATCH 3/7] Minor refactor of constants, including log and ROOT_DIR Charles O'Farrell
  2008-08-14 22:23     ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Shawn O. Pearce
  0 siblings, 2 replies; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   38 ++++---------------
 1 files changed, 8 insertions(+), 30 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 369cb37..1b38fce 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -266,31 +266,8 @@ public class RefUpdate {
 	 *             an unexpected IO error occurred while writing changes.
 	 */
 	public Result forceUpdate() throws IOException {
-		requireCanDoUpdate();
-		try {
-			return result = forceUpdateImpl();
-		} catch (IOException x) {
-			result = Result.IO_FAILURE;
-			throw x;
-		}
-	}
-
-	private Result forceUpdateImpl() throws IOException {
-		final LockFile lock;
-
-		lock = new LockFile(looseFile);
-		if (!lock.lock())
-			return Result.LOCK_FAILURE;
-		try {
-			oldValue = db.idOf(name);
-			if (oldValue == null)
-				return store(lock, Result.NEW);
-			if (oldValue.equals(newValue))
-				return Result.NO_CHANGE;
-			return store(lock, Result.FORCED);
-		} finally {
-			lock.unlock();
-		}
+		force = true;
+		return update();
 	}
 
 	/**
@@ -347,6 +324,12 @@ public class RefUpdate {
 			if (oldValue == null)
 				return store(lock, Result.NEW);
 
+			if (isForceUpdate()) {
+				if (oldValue.equals(newValue))
+					return Result.NO_CHANGE;
+				return store(lock, Result.FORCED);
+			}
+
 			newObj = walk.parseAny(newValue);
 			oldObj = walk.parseAny(oldValue);
 			if (newObj == oldObj)
@@ -355,13 +338,8 @@ public class RefUpdate {
 			if (newObj instanceof RevCommit && oldObj instanceof RevCommit) {
 				if (walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj))
 					return store(lock, Result.FAST_FORWARD);
-				if (isForceUpdate())
-					return store(lock, Result.FORCED);
-				return Result.REJECTED;
 			}
 
-			if (isForceUpdate())
-				return store(lock, Result.FORCED);
 			return Result.REJECTED;
 		} finally {
 			lock.unlock();
-- 
1.6.0.rc2.35.g04c6e

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

* [PATCH 3/7] Minor refactor of constants, including log and ROOT_DIR
  2008-08-14 10:13   ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Charles O'Farrell
@ 2008-08-14 10:13     ` Charles O'Farrell
  2008-08-14 10:13       ` [PATCH 4/7] Extract lockAndWriteFile method in RefDatabase for reuse Charles O'Farrell
  2008-08-14 22:23     ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Shawn O. Pearce
  1 sibling, 1 reply; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/Constants.java        |    3 +++
 .../src/org/spearce/jgit/lib/RefLogWriter.java     |    2 +-
 .../spearce/jgit/transport/TransportAmazonS3.java  |   10 ++++++----
 .../org/spearce/jgit/transport/TransportSftp.java  |    6 +++---
 .../spearce/jgit/transport/WalkPushConnection.java |    8 +++++---
 .../jgit/transport/WalkRemoteObjectDatabase.java   |   16 +++++++++-------
 6 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
index 7bbd88e..9ae3c1d 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Constants.java
@@ -214,6 +214,9 @@ public final class Constants {
 	/** Prefix for tag refs */
 	public static final String TAGS_PREFIX = "refs/tags";
 
+	/** Logs folder name */
+	public static final String LOGS = "logs";
+
 	/** Info refs folder */
 	public static final String INFO_REFS = "info/refs";
 
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java
index 8256d70..3aecaf2 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefLogWriter.java
@@ -70,7 +70,7 @@ public class RefLogWriter {
 		String entry = buildReflogString(repo, oldCommit, commit, message);
 
 		File directory = repo.getDirectory();
-		File reflogfile = new File(directory, "logs/" + refName);
+		File reflogfile = new File(directory, Constants.LOGS + "/" + refName);
 		File reflogdir = reflogfile.getParentFile();
 		if (!reflogdir.exists())
 			if (!reflogdir.mkdirs())
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
index 9aa2567..f9df36d 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportAmazonS3.java
@@ -178,7 +178,7 @@ class TransportAmazonS3 extends WalkTransport {
 			if (subpath.endsWith("/"))
 				subpath = subpath.substring(0, subpath.length() - 1);
 			String k = objectsKey;
-			while (subpath.startsWith("../")) {
+			while (subpath.startsWith(ROOT_DIR)) {
 				k = k.substring(0, k.lastIndexOf('/'));
 				subpath = subpath.substring(3);
 			}
@@ -264,7 +264,8 @@ class TransportAmazonS3 extends WalkTransport {
 		private void readLooseRefs(final TreeMap<String, Ref> avail)
 				throws TransportException {
 			try {
-				for (final String n : s3.list(bucket, resolveKey("../refs")))
+				for (final String n : s3.list(bucket, resolveKey(ROOT_DIR
+						+ "refs")))
 					readRef(avail, "refs/" + n);
 			} catch (IOException e) {
 				throw new TransportException(getURI(), "cannot list refs", e);
@@ -274,8 +275,9 @@ class TransportAmazonS3 extends WalkTransport {
 		private Ref readRef(final TreeMap<String, Ref> avail, final String rn)
 				throws TransportException {
 			final String s;
+			String ref = ROOT_DIR + rn;
 			try {
-				final BufferedReader br = openReader("../" + rn);
+				final BufferedReader br = openReader(ref);
 				try {
 					s = br.readLine();
 				} finally {
@@ -284,7 +286,7 @@ class TransportAmazonS3 extends WalkTransport {
 			} catch (FileNotFoundException noRef) {
 				return null;
 			} catch (IOException err) {
-				throw new TransportException(getURI(), "read ../" + rn, err);
+				throw new TransportException(getURI(), "read " + ref, err);
 			}
 
 			if (s == null)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
index 6a5df07..78f4ad8 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/TransportSftp.java
@@ -372,8 +372,8 @@ class TransportSftp extends WalkTransport {
 		Map<String, Ref> readAdvertisedRefs() throws TransportException {
 			final TreeMap<String, Ref> avail = new TreeMap<String, Ref>();
 			readPackedRefs(avail);
-			readRef(avail, "../HEAD", "HEAD");
-			readLooseRefs(avail, "../refs", "refs/");
+			readRef(avail, ROOT_DIR + "HEAD", "HEAD");
+			readLooseRefs(avail, ROOT_DIR + "refs", "refs/");
 			return avail;
 		}
 
@@ -423,7 +423,7 @@ class TransportSftp extends WalkTransport {
 
 			if (line.startsWith("ref: ")) {
 				final String p = line.substring("ref: ".length());
-				Ref r = readRef(avail, "../" + p, p);
+				Ref r = readRef(avail, ROOT_DIR + p, p);
 				if (r == null)
 					r = avail.get(p);
 				if (r != null) {
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java
index 19071d7..39b967c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkPushConnection.java
@@ -37,6 +37,8 @@
 
 package org.spearce.jgit.transport;
 
+import static org.spearce.jgit.transport.WalkRemoteObjectDatabase.ROOT_DIR;
+
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -163,7 +165,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
 			@Override
 			protected void writeFile(String file, byte[] content)
 					throws IOException {
-				dest.writeFile("../" + file, content);
+				dest.writeFile(ROOT_DIR + file, content);
 			}
 		};
 		if (!packedRefUpdates.isEmpty()) {
@@ -334,7 +336,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
 		try {
 			final String ref = "ref: " + pickHEAD(updates) + "\n";
 			final byte[] bytes = ref.getBytes(Constants.CHARACTER_ENCODING);
-			dest.writeFile("../HEAD", bytes);
+			dest.writeFile(ROOT_DIR + "HEAD", bytes);
 		} catch (IOException e) {
 			throw new TransportException(uri, "cannot create HEAD", e);
 		}
@@ -343,7 +345,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
 			final String config = "[core]\n"
 					+ "\trepositoryformatversion = 0\n";
 			final byte[] bytes = config.getBytes(Constants.CHARACTER_ENCODING);
-			dest.writeFile("../config", bytes);
+			dest.writeFile(ROOT_DIR + "config", bytes);
 		} catch (IOException e) {
 			throw new TransportException(uri, "cannot create config", e);
 		}
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
index 25640dc..8fb5e1e 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/WalkRemoteObjectDatabase.java
@@ -66,6 +66,9 @@ import org.spearce.jgit.util.NB;
  * independent {@link WalkFetchConnection}.
  */
 abstract class WalkRemoteObjectDatabase {
+
+	static final String ROOT_DIR = "../";
+
 	static final String CHARENC = Constants.CHARACTER_ENCODING;
 
 	static final String INFO_PACKS = "info/packs";
@@ -74,9 +77,7 @@ abstract class WalkRemoteObjectDatabase {
 
 	static final String INFO_HTTP_ALTERNATES = "info/http-alternates";
 
-	static final String INFO_REFS = "../info/refs";
-
-	static final String PACKED_REFS = "../packed-refs";
+	static final String INFO_REFS = ROOT_DIR + Constants.INFO_REFS;
 
 	abstract URIish getURI();
 
@@ -271,7 +272,7 @@ abstract class WalkRemoteObjectDatabase {
 	 *             deletion is not supported, or deletion failed.
 	 */
 	void deleteRef(final String name) throws IOException {
-		deleteFile("../" + name);
+		deleteFile(ROOT_DIR + name);
 	}
 
 	/**
@@ -284,7 +285,7 @@ abstract class WalkRemoteObjectDatabase {
 	 *             deletion is not supported, or deletion failed.
 	 */
 	void deleteRefLog(final String name) throws IOException {
-		deleteFile("../logs/" + name);
+		deleteFile(ROOT_DIR + Constants.LOGS + "/" + name);
 	}
 
 	/**
@@ -308,7 +309,7 @@ abstract class WalkRemoteObjectDatabase {
 		value.copyTo(b);
 		b.write('\n');
 
-		writeFile("../" + name, b.toByteArray());
+		writeFile(ROOT_DIR + name, b.toByteArray());
 	}
 
 	/**
@@ -411,7 +412,8 @@ abstract class WalkRemoteObjectDatabase {
 	protected void readPackedRefs(final Map<String, Ref> avail)
 			throws TransportException {
 		try {
-			final BufferedReader br = openReader(PACKED_REFS);
+			final BufferedReader br = openReader(ROOT_DIR
+					+ Constants.PACKED_REFS);
 			try {
 				readPackedRefsImpl(avail, br);
 			} finally {
-- 
1.6.0.rc2.35.g04c6e

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

* [PATCH 4/7] Extract lockAndWriteFile method in RefDatabase for reuse
  2008-08-14 10:13     ` [PATCH 3/7] Minor refactor of constants, including log and ROOT_DIR Charles O'Farrell
@ 2008-08-14 10:13       ` Charles O'Farrell
  2008-08-14 10:13         ` [PATCH 5/7] Added removePackedRef method to RefDatabase for packed branch deletion Charles O'Farrell
  0 siblings, 1 reply; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   25 ++++++++++++--------
 1 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 3e68a8d..3d8280d 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -158,16 +158,7 @@ class RefDatabase {
 	 */
 	void link(final String name, final String target) throws IOException {
 		final byte[] content = ("ref: " + target + "\n").getBytes(CHAR_ENC);
-		final LockFile lck = new LockFile(fileForRef(name));
-		if (!lck.lock())
-			throw new ObjectWritingException("Unable to lock " + name);
-		try {
-			lck.write(content);
-		} catch (IOException ioe) {
-			throw new ObjectWritingException("Unable to write " + name, ioe);
-		}
-		if (!lck.commit())
-			throw new ObjectWritingException("Unable to write " + name);
+		lockAndWriteFile(fileForRef(name), content);
 		setModified();
 		db.fireRefsMaybeChanged();
 	}
@@ -427,6 +418,20 @@ class RefDatabase {
 		}
 	}
 
+	private void lockAndWriteFile(File file, byte[] content) throws IOException {
+		String name = file.getName();
+		final LockFile lck = new LockFile(file);
+		if (!lck.lock())
+			throw new ObjectWritingException("Unable to lock " + name);
+		try {
+			lck.write(content);
+		} catch (IOException ioe) {
+			throw new ObjectWritingException("Unable to write " + name, ioe);
+		}
+		if (!lck.commit())
+			throw new ObjectWritingException("Unable to write " + name);
+	}
+
 	private static String readLine(final File file)
 			throws FileNotFoundException, IOException {
 		final BufferedReader br = openReader(file);
-- 
1.6.0.rc2.35.g04c6e

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

* [PATCH 5/7] Added removePackedRef method to RefDatabase for packed branch deletion
  2008-08-14 10:13       ` [PATCH 4/7] Extract lockAndWriteFile method in RefDatabase for reuse Charles O'Farrell
@ 2008-08-14 10:13         ` Charles O'Farrell
  2008-08-14 10:13           ` [PATCH 6/7] Added ref deletion to RefUpdate Charles O'Farrell
  0 siblings, 1 reply; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/RefDatabase.java      |   16 +++++++++++++++-
 .../src/org/spearce/jgit/lib/Repository.java       |    2 +-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
index 3d8280d..0293ace 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java
@@ -121,7 +121,7 @@ class RefDatabase {
 	}
 
 	/**
-	 * Create a command to update (or create) a ref in this repository.
+	 * Create a command to update, create or delete a ref in this repository.
 	 * 
 	 * @param name
 	 *            name of the ref the caller wants to modify.
@@ -432,6 +432,20 @@ class RefDatabase {
 			throw new ObjectWritingException("Unable to write " + name);
 	}
 
+	void removePackedRef(String name) throws IOException {
+		packedRefs.remove(name);
+		writePackedRefs();
+	}
+
+	private void writePackedRefs() throws IOException {
+		new RefWriter(packedRefs.values()) {
+			@Override
+			protected void writeFile(String name, byte[] content) throws IOException {
+				lockAndWriteFile(new File(db.getDirectory(), name), content);
+			}
+		}.writePackedRefs();
+	}
+
 	private static String readLine(final File file)
 			throws FileNotFoundException, IOException {
 		final BufferedReader br = openReader(file);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 6f7961e..7679e53 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -493,7 +493,7 @@ public class Repository {
 	}
 
 	/**
-	 * Create a command to update (or create) a ref in this repository.
+	 * Create a command to update, create or delete a ref in this repository.
 	 * 
 	 * @param ref
 	 *            name of the ref the caller wants to modify.
-- 
1.6.0.rc2.35.g04c6e

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

* [PATCH 6/7] Added ref deletion to RefUpdate
  2008-08-14 10:13         ` [PATCH 5/7] Added removePackedRef method to RefDatabase for packed branch deletion Charles O'Farrell
@ 2008-08-14 10:13           ` Charles O'Farrell
  2008-08-14 10:13             ` [PATCH 7/7] jgit: Added branch deletion to jgit command Charles O'Farrell
  0 siblings, 1 reply; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

This is mixed in with the update code as they as they are common in
their general behaviour, differing only in the storing of the changes.

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   70 ++++++++++++++++++--
 1 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 1b38fce..e7560e9 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -40,6 +40,7 @@ package org.spearce.jgit.lib;
 import java.io.File;
 import java.io.IOException;
 
+import org.spearce.jgit.lib.Ref.Storage;
 import org.spearce.jgit.revwalk.RevCommit;
 import org.spearce.jgit.revwalk.RevObject;
 import org.spearce.jgit.revwalk.RevWalk;
@@ -146,8 +147,11 @@ public class RefUpdate {
 	/** Result of the update operation. */
 	private Result result = Result.NOT_ATTEMPTED;
 
+	private final Ref ref;
+
 	RefUpdate(final RefDatabase r, final Ref ref, final File f) {
 		db = r;
+		this.ref = ref;
 		name = ref.getName();
 		oldValue = ref.getObjectId();
 		looseFile = f;
@@ -304,14 +308,31 @@ public class RefUpdate {
 	public Result update(final RevWalk walk) throws IOException {
 		requireCanDoUpdate();
 		try {
-			return result = updateImpl(walk);
+			return result = updateImpl(walk, new UpdateStore());
+		} catch (IOException x) {
+			result = Result.IO_FAILURE;
+			throw x;
+		}
+	}
+
+	/**
+	 * Delete the ref.
+	 * 
+	 * @return the result status of the delete.
+	 * @throws IOException
+	 */
+	public Result delete() throws IOException {
+		try {
+			return updateImpl(new RevWalk(db.getRepository()),
+					new DeleteStore());
 		} catch (IOException x) {
 			result = Result.IO_FAILURE;
 			throw x;
 		}
 	}
 
-	private Result updateImpl(final RevWalk walk) throws IOException {
+	private Result updateImpl(final RevWalk walk, final Store store)
+			throws IOException {
 		final LockFile lock;
 		RevObject newObj;
 		RevObject oldObj;
@@ -322,12 +343,12 @@ public class RefUpdate {
 		try {
 			oldValue = db.idOf(name);
 			if (oldValue == null)
-				return store(lock, Result.NEW);
+				return store.store(lock, Result.NEW);
 
 			if (isForceUpdate()) {
 				if (oldValue.equals(newValue))
 					return Result.NO_CHANGE;
-				return store(lock, Result.FORCED);
+				return store.store(lock, Result.FORCED);
 			}
 
 			newObj = walk.parseAny(newValue);
@@ -337,7 +358,7 @@ public class RefUpdate {
 
 			if (newObj instanceof RevCommit && oldObj instanceof RevCommit) {
 				if (walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj))
-					return store(lock, Result.FAST_FORWARD);
+					return store.store(lock, Result.FAST_FORWARD);
 			}
 
 			return Result.REJECTED;
@@ -346,7 +367,7 @@ public class RefUpdate {
 		}
 	}
 
-	private Result store(final LockFile lock, final Result status)
+	private Result updateStore(final LockFile lock, final Result status)
 			throws IOException {
 		lock.setNeedStatInformation(true);
 		lock.write(newValue);
@@ -366,4 +387,41 @@ public class RefUpdate {
 		db.stored(name, newValue, lock.getCommitLastModified());
 		return status;
 	}
+
+	/**
+	 * Handle the abstraction of storing a ref update. This is because both
+	 * updating and deleting of a ref have merge testing in common.
+	 */
+	private abstract class Store {
+		abstract Result store(final LockFile lock, final Result status)
+				throws IOException;
+	}
+
+	private class UpdateStore extends Store {
+
+		@Override
+		Result store(final LockFile lock, final Result status)
+				throws IOException {
+			return updateStore(lock, status);
+		}
+	}
+
+	private class DeleteStore extends Store {
+
+		@Override
+		Result store(LockFile lock, Result status) throws IOException {
+			Storage storage = ref.getStorage();
+			if (storage == Storage.NEW)
+				return status;
+			if (storage.isPacked())
+				db.removePackedRef(ref.getName());
+			if (storage.isLoose())
+				if (!looseFile.delete())
+					throw new IOException("File cannot be deleted: "
+							+ looseFile);
+			new File(db.getRepository().getDirectory(), Constants.LOGS + "/"
+					+ ref.getName()).delete();
+			return status;
+		}
+	}
 }
-- 
1.6.0.rc2.35.g04c6e

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

* [PATCH 7/7] jgit: Added branch deletion to jgit command
  2008-08-14 10:13           ` [PATCH 6/7] Added ref deletion to RefUpdate Charles O'Farrell
@ 2008-08-14 10:13             ` Charles O'Farrell
  0 siblings, 0 replies; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-14 10:13 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/pgm/Branch.java           |   57 +++++++++++++++++++-
 1 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Branch.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Branch.java
index 8415fe2..c89f510 100644
--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Branch.java
+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Branch.java
@@ -37,24 +37,50 @@
 
 package org.spearce.jgit.pgm;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
 
+import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
 import org.spearce.jgit.lib.Constants;
+import org.spearce.jgit.lib.ObjectId;
 import org.spearce.jgit.lib.Ref;
+import org.spearce.jgit.lib.RefUpdate;
+import org.spearce.jgit.lib.RefUpdate.Result;
 
 @Command(common = true, usage = "List, create, or delete branches")
 class Branch extends TextBuiltin {
 
 	@Option(name = "--remote", aliases = { "-r" }, usage = "act on remote-tracking branches")
-	boolean remote = false;
+	private boolean remote = false;
 
 	@Option(name = "--all", aliases = { "-a" }, usage = "list both remote-tracking and local branches")
-	boolean all = false;
+	private boolean all = false;
+
+	@Option(name = "--delete", aliases = { "-d" }, usage = "delete fully merged branch")
+	private boolean delete = false;
+
+	@Option(name = "--delete-force", aliases = { "-D" }, usage = "delete branch (even if not merged)")
+	private boolean deleteForce = false;
+
+	@Option(name = "--verbose", aliases = { "-v" }, usage = "be verbose")
+	private boolean verbose = false;
+
+	@Argument
+	private List<String> branches = new ArrayList<String>();
 
 	@Override
 	protected void run() throws Exception {
+		if (delete || deleteForce)
+			delete(deleteForce);
+		else
+			list();
+	}
+
+	private void list() {
 		Map<String, Ref> refs = db.getAllRefs();
 		Ref head = refs.get(Constants.HEAD);
 		// This can happen if HEAD is stillborn
@@ -80,4 +106,31 @@ class Branch extends TextBuiltin {
 		ref = ref.substring(ref.indexOf('/', 5) + 1);
 		out.println(ref);
 	}
+
+	private void delete(boolean force) throws IOException {
+		String current = db.getBranch();
+		ObjectId head = db.resolve(Constants.HEAD);
+		for (String branch : branches) {
+			if (current.equals(branch)) {
+				String err = "Cannot delete the branch '%s' which you are currently on.";
+				throw die(String.format(err, branch));
+			}
+			RefUpdate update = db.updateRef((remote ? Constants.REMOTES_PREFIX
+					: Constants.HEADS_PREFIX)
+					+ '/' + branch);
+			update.setNewObjectId(head);
+			update.setForceUpdate(force || remote);
+			Result result = update.delete();
+			if (result == Result.REJECTED) {
+				String err = "The branch '%s' is not an ancestor of your current HEAD.\n"
+						+ "If you are sure you want to delete it, run 'jgit branch -D %1$s'.";
+				throw die(String.format(err, branch));
+			} else if (result == Result.NEW)
+				throw die(String.format("branch '%s' not found.", branch));
+			if (remote)
+				out.println(String.format("Deleted remote branch %s", branch));
+			else if (verbose)
+				out.println(String.format("Deleted branch %s", branch));
+		}
+	}
 }
-- 
1.6.0.rc2.35.g04c6e

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

* Re: [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication
  2008-08-14 10:13   ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Charles O'Farrell
  2008-08-14 10:13     ` [PATCH 3/7] Minor refactor of constants, including log and ROOT_DIR Charles O'Farrell
@ 2008-08-14 22:23     ` Shawn O. Pearce
  1 sibling, 0 replies; 11+ messages in thread
From: Shawn O. Pearce @ 2008-08-14 22:23 UTC (permalink / raw)
  To: Charles O'Farrell; +Cc: git

Charles O'Farrell <charleso@charleso.org> wrote:
> @@ -266,31 +266,8 @@ public class RefUpdate {
>  	 *             an unexpected IO error occurred while writing changes.
>  	 */
>  	public Result forceUpdate() throws IOException {
[clipped uinteresting deletions to show only the postimage]
> +		force = true;
> +		return update();
>  	}
>  
>  	/**
> @@ -347,6 +324,12 @@ public class RefUpdate {
>  			if (oldValue == null)
>  				return store(lock, Result.NEW);
>  
> +			if (isForceUpdate()) {
> +				if (oldValue.equals(newValue))
> +					return Result.NO_CHANGE;
> +				return store(lock, Result.FORCED);
> +			}
> +
>  			newObj = walk.parseAny(newValue);
>  			oldObj = walk.parseAny(oldValue);
>  			if (newObj == oldObj)
> @@ -355,13 +338,8 @@ public class RefUpdate {
>  			if (newObj instanceof RevCommit && oldObj instanceof RevCommit) {
>  				if (walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj))
>  					return store(lock, Result.FAST_FORWARD);
> -				if (isForceUpdate())
> -					return store(lock, Result.FORCED);
> -				return Result.REJECTED;

The problem with this change is that calls to just update() which
have isForceUpdate() true but actually turn out to be FAST_FORWARD
types of updates now report FORCED as the result.  We don't want
to always report FORCED if the application is using just update().

Its nice to know that the remote side didn't rewind since we last
saw them (for example).

-- 
Shawn.

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

* [JGIT PATCH v2 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication
  2008-08-14 10:13 [PATCH 0/7] jgit: Branch command now supports deletion Charles O'Farrell
  2008-08-14 10:13 ` [PATCH 1/7] Refactor of WalkRemoteObjectDatabase ref writing into common class Charles O'Farrell
@ 2008-08-15  0:25 ` Charles O'Farrell
  2008-08-15  0:25   ` [JGIT PATCH v2 6/7] Added ref deletion to RefUpdate Charles O'Farrell
  1 sibling, 1 reply; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-15  0:25 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   34 ++-----------------
 1 files changed, 4 insertions(+), 30 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 369cb37..4587fc1 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -258,39 +258,16 @@ public class RefUpdate {
 	/**
 	 * Force the ref to take the new value.
 	 * <p>
-	 * No merge tests are performed, so the value of {@link #isForceUpdate()}
-	 * will not be honored.
+	 * This is just a convenient helper for setting the force flag, and as such
+	 * the merge test is performed.
 	 * 
 	 * @return the result status of the update.
 	 * @throws IOException
 	 *             an unexpected IO error occurred while writing changes.
 	 */
 	public Result forceUpdate() throws IOException {
-		requireCanDoUpdate();
-		try {
-			return result = forceUpdateImpl();
-		} catch (IOException x) {
-			result = Result.IO_FAILURE;
-			throw x;
-		}
-	}
-
-	private Result forceUpdateImpl() throws IOException {
-		final LockFile lock;
-
-		lock = new LockFile(looseFile);
-		if (!lock.lock())
-			return Result.LOCK_FAILURE;
-		try {
-			oldValue = db.idOf(name);
-			if (oldValue == null)
-				return store(lock, Result.NEW);
-			if (oldValue.equals(newValue))
-				return Result.NO_CHANGE;
-			return store(lock, Result.FORCED);
-		} finally {
-			lock.unlock();
-		}
+		force = true;
+		return update();
 	}
 
 	/**
@@ -355,9 +332,6 @@ public class RefUpdate {
 			if (newObj instanceof RevCommit && oldObj instanceof RevCommit) {
 				if (walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj))
 					return store(lock, Result.FAST_FORWARD);
-				if (isForceUpdate())
-					return store(lock, Result.FORCED);
-				return Result.REJECTED;
 			}
 
 			if (isForceUpdate())
-- 
1.6.0.rc2.35.g04c6e

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

* [JGIT PATCH v2 6/7] Added ref deletion to RefUpdate
  2008-08-15  0:25 ` [JGIT PATCH v2 " Charles O'Farrell
@ 2008-08-15  0:25   ` Charles O'Farrell
  0 siblings, 0 replies; 11+ messages in thread
From: Charles O'Farrell @ 2008-08-15  0:25 UTC (permalink / raw)
  To: git; +Cc: Charles O'Farrell

This is mixed in with the update code as they as they are common in
their general behaviour, differing only in the storing of the changes.

Signed-off-by: Charles O'Farrell <charleso@charleso.org>
---
 .../src/org/spearce/jgit/lib/RefUpdate.java        |   70 ++++++++++++++++++--
 1 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
index 4587fc1..858ba46 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefUpdate.java
@@ -40,6 +40,7 @@ package org.spearce.jgit.lib;
 import java.io.File;
 import java.io.IOException;
 
+import org.spearce.jgit.lib.Ref.Storage;
 import org.spearce.jgit.revwalk.RevCommit;
 import org.spearce.jgit.revwalk.RevObject;
 import org.spearce.jgit.revwalk.RevWalk;
@@ -146,8 +147,11 @@ public class RefUpdate {
 	/** Result of the update operation. */
 	private Result result = Result.NOT_ATTEMPTED;
 
+	private final Ref ref;
+
 	RefUpdate(final RefDatabase r, final Ref ref, final File f) {
 		db = r;
+		this.ref = ref;
 		name = ref.getName();
 		oldValue = ref.getObjectId();
 		looseFile = f;
@@ -304,14 +308,31 @@ public class RefUpdate {
 	public Result update(final RevWalk walk) throws IOException {
 		requireCanDoUpdate();
 		try {
-			return result = updateImpl(walk);
+			return result = updateImpl(walk, new UpdateStore());
+		} catch (IOException x) {
+			result = Result.IO_FAILURE;
+			throw x;
+		}
+	}
+
+	/**
+	 * Delete the ref.
+	 * 
+	 * @return the result status of the delete.
+	 * @throws IOException
+	 */
+	public Result delete() throws IOException {
+		try {
+			return updateImpl(new RevWalk(db.getRepository()),
+					new DeleteStore());
 		} catch (IOException x) {
 			result = Result.IO_FAILURE;
 			throw x;
 		}
 	}
 
-	private Result updateImpl(final RevWalk walk) throws IOException {
+	private Result updateImpl(final RevWalk walk, final Store store)
+			throws IOException {
 		final LockFile lock;
 		RevObject newObj;
 		RevObject oldObj;
@@ -322,7 +343,7 @@ public class RefUpdate {
 		try {
 			oldValue = db.idOf(name);
 			if (oldValue == null)
-				return store(lock, Result.NEW);
+				return store.store(lock, Result.NEW);
 
 			newObj = walk.parseAny(newValue);
 			oldObj = walk.parseAny(oldValue);
@@ -331,18 +352,18 @@ public class RefUpdate {
 
 			if (newObj instanceof RevCommit && oldObj instanceof RevCommit) {
 				if (walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj))
-					return store(lock, Result.FAST_FORWARD);
+					return store.store(lock, Result.FAST_FORWARD);
 			}
 
 			if (isForceUpdate())
-				return store(lock, Result.FORCED);
+				return store.store(lock, Result.FORCED);
 			return Result.REJECTED;
 		} finally {
 			lock.unlock();
 		}
 	}
 
-	private Result store(final LockFile lock, final Result status)
+	private Result updateStore(final LockFile lock, final Result status)
 			throws IOException {
 		lock.setNeedStatInformation(true);
 		lock.write(newValue);
@@ -362,4 +383,41 @@ public class RefUpdate {
 		db.stored(name, newValue, lock.getCommitLastModified());
 		return status;
 	}
+
+	/**
+	 * Handle the abstraction of storing a ref update. This is because both
+	 * updating and deleting of a ref have merge testing in common.
+	 */
+	private abstract class Store {
+		abstract Result store(final LockFile lock, final Result status)
+				throws IOException;
+	}
+
+	private class UpdateStore extends Store {
+
+		@Override
+		Result store(final LockFile lock, final Result status)
+				throws IOException {
+			return updateStore(lock, status);
+		}
+	}
+
+	private class DeleteStore extends Store {
+
+		@Override
+		Result store(LockFile lock, Result status) throws IOException {
+			Storage storage = ref.getStorage();
+			if (storage == Storage.NEW)
+				return status;
+			if (storage.isPacked())
+				db.removePackedRef(ref.getName());
+			if (storage.isLoose())
+				if (!looseFile.delete())
+					throw new IOException("File cannot be deleted: "
+							+ looseFile);
+			new File(db.getRepository().getDirectory(), Constants.LOGS + "/"
+					+ ref.getName()).delete();
+			return status;
+		}
+	}
 }
-- 
1.6.0.rc2.35.g04c6e

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

end of thread, other threads:[~2008-08-15  0:27 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-14 10:13 [PATCH 0/7] jgit: Branch command now supports deletion Charles O'Farrell
2008-08-14 10:13 ` [PATCH 1/7] Refactor of WalkRemoteObjectDatabase ref writing into common class Charles O'Farrell
2008-08-14 10:13   ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Charles O'Farrell
2008-08-14 10:13     ` [PATCH 3/7] Minor refactor of constants, including log and ROOT_DIR Charles O'Farrell
2008-08-14 10:13       ` [PATCH 4/7] Extract lockAndWriteFile method in RefDatabase for reuse Charles O'Farrell
2008-08-14 10:13         ` [PATCH 5/7] Added removePackedRef method to RefDatabase for packed branch deletion Charles O'Farrell
2008-08-14 10:13           ` [PATCH 6/7] Added ref deletion to RefUpdate Charles O'Farrell
2008-08-14 10:13             ` [PATCH 7/7] jgit: Added branch deletion to jgit command Charles O'Farrell
2008-08-14 22:23     ` [PATCH 2/7] Refactor of RefUpdate force to call common updateImpl instead of duplication Shawn O. Pearce
2008-08-15  0:25 ` [JGIT PATCH v2 " Charles O'Farrell
2008-08-15  0:25   ` [JGIT PATCH v2 6/7] Added ref deletion to RefUpdate Charles O'Farrell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).