aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
diff options
context:
space:
mode:
authorDave Borowitz <dborowitz@google.com>2017-07-05 13:45:39 -0400
committerDave Borowitz <dborowitz@google.com>2017-07-25 13:14:50 -0400
commit26962861d4fd50ac32edd642eafca1c10f29a4ba (patch)
tree8451d55f29c57191f7c8f9ac3f3b7de1534838ab /org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
parentcf9e3fad524f5c4a47144decd9091c84c3f07849 (diff)
downloadjgit-26962861d4fd50ac32edd642eafca1c10f29a4ba.tar.gz
jgit-26962861d4fd50ac32edd642eafca1c10f29a4ba.zip
Implement atomic BatchRefUpdates for RefDirectory
The existing packed-refs file provides a mechanism for implementing atomic multi-ref updates without any changes to the on-disk format or lockfile protocol. We just need to make sure that there are no loose refs involved in the transaction, which we can achieve by packing the refs while holding locks on all loose refs. Full details of the algorithm are in the PackedBatchRefUpdate javadoc. This change does not implement reflog support, which will come in a later change. Change-Id: I09829544a0d4e8dbb141d28c748c3b96ef66fee1
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java50
1 files changed, 42 insertions, 8 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
index 4a4db12fbe..aa85cc7b29 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
@@ -82,8 +82,10 @@ public class BatchRefUpdate {
* clock skew between machines on the same LAN using an NTP server also on
* the same LAN should be under 5 seconds. 5 seconds is also not that long
* for a large `git push` operation to complete.
+ *
+ * @since 4.9
*/
- private static final Duration MAX_WAIT = Duration.ofSeconds(5);
+ protected static final Duration MAX_WAIT = Duration.ofSeconds(5);
private final RefDatabase refdb;
@@ -335,6 +337,19 @@ public class BatchRefUpdate {
}
/**
+ * Set push options associated with this update.
+ * <p>
+ * Implementations must call this at the top of {@link #execute(RevWalk,
+ * ProgressMonitor, List)}.
+ *
+ * @param options options passed to {@code execute}.
+ * @since 4.9
+ */
+ protected void setPushOptions(List<String> options) {
+ pushOptions = options;
+ }
+
+ /**
* @return list of timestamps the batch must wait for.
* @since 4.6
*/
@@ -400,7 +415,7 @@ public class BatchRefUpdate {
}
if (options != null) {
- pushOptions = options;
+ setPushOptions(options);
}
monitor.beginTask(JGitText.get().updatingReferences, commands.size());
@@ -553,17 +568,36 @@ public class BatchRefUpdate {
return ref;
}
- static Collection<String> getPrefixes(String s) {
+ /**
+ * Get all path prefixes of a ref name.
+ *
+ * @param name
+ * ref name.
+ * @return path prefixes of the ref name. For {@code refs/heads/foo}, returns
+ * {@code refs} and {@code refs/heads}.
+ * @since 4.9
+ */
+ protected static Collection<String> getPrefixes(String name) {
Collection<String> ret = new HashSet<>();
- addPrefixesTo(s, ret);
+ addPrefixesTo(name, ret);
return ret;
}
- static void addPrefixesTo(String s, Collection<String> out) {
- int p1 = s.indexOf('/');
+ /**
+ * Add prefixes of a ref name to an existing collection.
+ *
+ * @param name
+ * ref name.
+ * @param out
+ * path prefixes of the ref name. For {@code refs/heads/foo},
+ * returns {@code refs} and {@code refs/heads}.
+ * @since 4.9
+ */
+ protected static void addPrefixesTo(String name, Collection<String> out) {
+ int p1 = name.indexOf('/');
while (p1 > 0) {
- out.add(s.substring(0, p1));
- p1 = s.indexOf('/', p1 + 1);
+ out.add(name.substring(0, p1));
+ p1 = name.indexOf('/', p1 + 1);
}
}