aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java13
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectory.java27
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryRename.java12
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryUpdate.java27
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java59
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java18
6 files changed, 104 insertions, 52 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
index 22d0c1ad3b..21e7041b32 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -114,19 +114,6 @@ public abstract class RefDatabase {
public abstract boolean isNameConflicting(String name) throws IOException;
/**
- * Create a symbolic reference from one name to another.
- *
- * @param name
- * the name of the reference. Should be {@link Constants#HEAD} or
- * starting with {@link Constants#R_REFS}.
- * @param target
- * the target of the reference.
- * @throws IOException
- * the reference could not be created or overwritten.
- */
- public abstract void link(String name, String target) throws IOException;
-
- /**
* Create a new update command to create, modify or delete a reference.
*
* @param name
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectory.java
index 9fdb48fe83..90ac0bf47e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectory.java
@@ -439,24 +439,11 @@ public class RefDirectory extends RefDatabase {
return leaf;
}
- @Override
- public void link(String name, String target) throws IOException {
- LockFile lck = new LockFile(fileFor(name));
- if (!lck.lock())
- throw new IOException("Cannot lock " + name);
- lck.setNeedStatInformation(true);
- try {
- lck.write(encode(SYMREF + target + '\n'));
- if (!lck.commit())
- throw new IOException("Cannot write " + name);
- } finally {
- lck.unlock();
- }
- putLooseRef(newSymbolicRef(lck.getCommitLastModified(), name, target));
+ void storedSymbolicRef(RefDirectoryUpdate u, long modified, String target) {
+ putLooseRef(newSymbolicRef(modified, u.getRef().getName(), target));
fireRefsChanged();
}
- @Override
public RefDirectoryUpdate newUpdate(String name, boolean detach)
throws IOException {
final RefList<Ref> packed = getPackedRefs();
@@ -536,7 +523,8 @@ public class RefDirectory extends RefDatabase {
fireRefsChanged();
}
- void log(final RefUpdate update, final String msg) throws IOException {
+ void log(final RefUpdate update, final String msg, final boolean deref)
+ throws IOException {
final ObjectId oldId = update.getOldObjectId();
final ObjectId newId = update.getNewObjectId();
final Ref ref = update.getRef();
@@ -558,9 +546,12 @@ public class RefDirectory extends RefDatabase {
r.append('\n');
final byte[] rec = encode(r.toString());
- if (ref.isSymbolic())
+ if (deref && ref.isSymbolic()) {
+ log(ref.getName(), rec);
+ log(ref.getLeaf().getName(), rec);
+ } else {
log(ref.getName(), rec);
- log(ref.getLeaf().getName(), rec);
+ }
}
private void log(final String refName, final byte[] rec) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryRename.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryRename.java
index e43d2a5617..fec00d9325 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryRename.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryRename.java
@@ -208,8 +208,16 @@ class RefDirectoryRename extends RefRename {
private boolean linkHEAD(RefUpdate target) {
try {
- refdb.link(Constants.HEAD, target.getName());
- return true;
+ RefUpdate u = refdb.newUpdate(Constants.HEAD, false);
+ u.disableRefLog();
+ switch (u.link(target.getName())) {
+ case NEW:
+ case FORCED:
+ case NO_CHANGE:
+ return true;
+ default:
+ return false;
+ }
} catch (IOException e) {
return false;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryUpdate.java
index 113b74b44e..447be104ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDirectoryUpdate.java
@@ -44,6 +44,8 @@
package org.eclipse.jgit.lib;
+import static org.eclipse.jgit.lib.Constants.encode;
+
import java.io.IOException;
/** Updates any reference stored by {@link RefDirectory}. */
@@ -68,8 +70,10 @@ class RefDirectoryUpdate extends RefUpdate {
}
@Override
- protected boolean tryLock() throws IOException {
- Ref dst = getRef().getLeaf();
+ protected boolean tryLock(boolean deref) throws IOException {
+ Ref dst = getRef();
+ if (deref)
+ dst = dst.getLeaf();
String name = dst.getName();
lock = new LockFile(database.fileFor(name));
if (lock.lock()) {
@@ -105,7 +109,7 @@ class RefDirectoryUpdate extends RefUpdate {
msg = strResult;
}
}
- database.log(this, msg);
+ database.log(this, msg, true);
}
if (!lock.commit())
return Result.LOCK_FAILURE;
@@ -132,4 +136,21 @@ class RefDirectoryUpdate extends RefUpdate {
database.delete(this);
return status;
}
+
+ @Override
+ protected Result doLink(final String target) throws IOException {
+ lock.setNeedStatInformation(true);
+ lock.write(encode(RefDirectory.SYMREF + target + '\n'));
+
+ String msg = getRefLogMessage();
+ if (msg != null)
+ database.log(this, msg, false);
+ if (!lock.commit())
+ return Result.LOCK_FAILURE;
+ database.storedSymbolicRef(this, lock.getCommitLastModified(), target);
+
+ if (getRef().getStorage() == Ref.Storage.NEW)
+ return Result.NEW;
+ return Result.FORCED;
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
index 33e12a110d..553266284b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
@@ -183,13 +183,17 @@ public abstract class RefUpdate {
* If the locking was successful the implementor must set the current
* identity value by calling {@link #setOldObjectId(ObjectId)}.
*
+ * @param deref
+ * true if the lock should be taken against the leaf level
+ * reference; false if it should be taken exactly against the
+ * current reference.
* @return true if the lock was acquired and the reference is likely
* protected from concurrent modification; false if it failed.
* @throws IOException
* the lock couldn't be taken due to an unexpected storage
* failure, and not because of a concurrent update.
*/
- protected abstract boolean tryLock() throws IOException;
+ protected abstract boolean tryLock(boolean deref) throws IOException;
/** Releases the lock taken by {@link #tryLock} if it succeeded. */
protected abstract void unlock();
@@ -209,6 +213,13 @@ public abstract class RefUpdate {
protected abstract Result doDelete(Result desiredResult) throws IOException;
/**
+ * @param target
+ * @return {@link Result#NEW} on success.
+ * @throws IOException
+ */
+ protected abstract Result doLink(String target) throws IOException;
+
+ /**
* Get the name of the ref this update will operate on.
*
* @return name of underlying ref.
@@ -499,6 +510,50 @@ public abstract class RefUpdate {
}
}
+ /**
+ * Replace this reference with a symbolic reference to another reference.
+ * <p>
+ * This exact reference (not its traversed leaf) is replaced with a symbolic
+ * reference to the requested name.
+ *
+ * @param target
+ * name of the new target for this reference. The new target name
+ * must be absolute, so it must begin with {@code refs/}.
+ * @return {@link Result#NEW} or {@link Result#FORCED} on success.
+ * @throws IOException
+ */
+ public Result link(String target) throws IOException {
+ if (!target.startsWith(Constants.R_REFS))
+ throw new IllegalArgumentException("Not " + Constants.R_REFS);
+ if (getRefDatabase().isNameConflicting(getName()))
+ return Result.LOCK_FAILURE;
+ try {
+ if (!tryLock(false))
+ return Result.LOCK_FAILURE;
+
+ final Ref old = getRefDatabase().getRef(getName());
+ if (old != null && old.isSymbolic()) {
+ final Ref dst = old.getTarget();
+ if (target.equals(dst.getName()))
+ return result = Result.NO_CHANGE;
+ }
+
+ if (old != null && old.getObjectId() != null)
+ setOldObjectId(old.getObjectId());
+
+ final Ref dst = getRefDatabase().getRef(target);
+ if (dst != null && dst.getObjectId() != null)
+ setNewObjectId(dst.getObjectId());
+
+ return result = doLink(target);
+ } catch (IOException x) {
+ result = Result.IO_FAILURE;
+ throw x;
+ } finally {
+ unlock();
+ }
+ }
+
private Result updateImpl(final RevWalk walk, final Store store)
throws IOException {
RevObject newObj;
@@ -507,7 +562,7 @@ public abstract class RefUpdate {
if (getRefDatabase().isNameConflicting(getName()))
return Result.LOCK_FAILURE;
try {
- if (!tryLock())
+ if (!tryLock(true))
return Result.LOCK_FAILURE;
if (expValue != null) {
final ObjectId o;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index ecae243a41..ca86e36a47 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -276,8 +276,10 @@ public class Repository {
objectDatabase.create();
new File(gitDir, "branches").mkdir();
- final String master = Constants.R_HEADS + Constants.MASTER;
- refs.link(Constants.HEAD, master);
+
+ RefUpdate head = updateRef(Constants.HEAD);
+ head.disableRefLog();
+ head.link(Constants.R_HEADS + Constants.MASTER);
cfg.setInt("core", null, "repositoryformatversion", 0);
cfg.setBoolean("core", null, "filemode", true);
@@ -899,18 +901,6 @@ public class Repository {
objectDatabase.openPack(pack, idx);
}
- /**
- * Writes a symref (e.g. HEAD) to disk
- *
- * @param name symref name
- * @param target pointed to ref
- * @throws IOException
- */
- public void writeSymref(final String name, final String target)
- throws IOException {
- refs.link(name, target);
- }
-
public String toString() {
return "Repository[" + getDirectory() + "]";
}