|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/masters", B); |
|
|
"refs/heads/masters", B); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, OK, REJECTED_NONFASTFORWARD); |
|
|
assertResults(cmds, OK, REJECTED_NONFASTFORWARD); |
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/masters", B); |
|
|
"refs/heads/masters", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void simpleNoForceRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
writeLooseRef("refs/heads/masters", B); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
refdir.exactRef("refs/heads/masters"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(B, A, "refs/heads/masters", |
|
|
|
|
|
UPDATE_NONFASTFORWARD)); |
|
|
|
|
|
execute(newBatchUpdate(cmds)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void simpleForce() throws IOException { |
|
|
public void simpleForce() throws IOException { |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/masters", A); |
|
|
"refs/heads/masters", A); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void simpleForceRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
writeLooseRef("refs/heads/masters", B); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
refdir.exactRef("refs/heads/masters"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(B, A, "refs/heads/masters", |
|
|
|
|
|
UPDATE_NONFASTFORWARD)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertResults(cmds, OK); |
|
|
assertResults(cmds, OK); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void nonFastForwardDoesNotDoExpensiveMergeCheckRefsChangedEvents() |
|
|
|
|
|
throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", B); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(B, A, |
|
|
|
|
|
"refs/heads/master", UPDATE_NONFASTFORWARD)); |
|
|
|
|
|
try (RevWalk rw = new RevWalk(diskRepo) { |
|
|
|
|
|
@Override |
|
|
|
|
|
public boolean isMergedInto(RevCommit base, RevCommit tip) { |
|
|
|
|
|
throw new AssertionError("isMergedInto() should not be called"); |
|
|
|
|
|
} |
|
|
|
|
|
}) { |
|
|
|
|
|
newBatchUpdate(cmds).setAllowNonFastForwards(true).execute(rw, |
|
|
|
|
|
new StrictWorkMonitor()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/masters", B); |
|
|
"refs/heads/masters", B); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// Non-atomic updates are applied in order: master succeeds, then master/x |
|
|
// Non-atomic updates are applied in order: master succeeds, then master/x |
|
|
// fails due to conflict. |
|
|
// fails due to conflict. |
|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/masters", B); |
|
|
"refs/heads/masters", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void fileDirectoryConflictRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
writeLooseRef("refs/heads/masters", B); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
refdir.exactRef("refs/heads/masters"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), A, "refs/heads/master/x", CREATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), A, "refs/heads", CREATE)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void conflictThanksToDelete() throws IOException { |
|
|
public void conflictThanksToDelete() throws IOException { |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/masters/x", A); |
|
|
"refs/heads/masters/x", A); |
|
|
if (atomic) { |
|
|
|
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
|
|
|
// The non-atomic case actually produces 5 events, but that's an |
|
|
|
|
|
// implementation detail. We expect at least 4 events, one for the |
|
|
|
|
|
// initial read due to writeLooseRef(), and then one for each |
|
|
|
|
|
// successful ref update. |
|
|
|
|
|
assertTrue(refsChangedEvents >= 4); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void conflictThanksToDeleteRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
writeLooseRef("refs/heads/masters", B); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
refdir.exactRef("refs/heads/masters"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), A, "refs/heads/masters/x", CREATE), |
|
|
|
|
|
new ReceiveCommand(B, zeroId(), "refs/heads/masters", DELETE)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 3, refsChangedEvents); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, REJECTED_MISSING_OBJECT, TRANSACTION_ABORTED); |
|
|
assertResults(cmds, REJECTED_MISSING_OBJECT, TRANSACTION_ABORTED); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, REJECTED_MISSING_OBJECT, OK); |
|
|
assertResults(cmds, REJECTED_MISSING_OBJECT, OK); |
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/foo2", B); |
|
|
"refs/heads/foo2", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void updateToMissingObjectRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
ObjectId bad = ObjectId |
|
|
|
|
|
.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); |
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, bad, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void addMissingObject() throws IOException { |
|
|
public void addMissingObject() throws IOException { |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, TRANSACTION_ABORTED, REJECTED_MISSING_OBJECT); |
|
|
assertResults(cmds, TRANSACTION_ABORTED, REJECTED_MISSING_OBJECT); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, OK, REJECTED_MISSING_OBJECT); |
|
|
assertResults(cmds, OK, REJECTED_MISSING_OBJECT); |
|
|
assertRefs("refs/heads/master", B); |
|
|
assertRefs("refs/heads/master", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void addMissingObjectRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
ObjectId bad = ObjectId |
|
|
|
|
|
.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); |
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), bad, "refs/heads/foo2", CREATE)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void oneNonExistentRef() throws IOException { |
|
|
public void oneNonExistentRef() throws IOException { |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED); |
|
|
assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, LOCK_FAILURE, OK); |
|
|
assertResults(cmds, LOCK_FAILURE, OK); |
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/master", A, |
|
|
"refs/heads/foo2", B); |
|
|
"refs/heads/foo2", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void oneRefWrongOldValueRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(B, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void nonExistentRef() throws IOException { |
|
|
public void nonExistentRef() throws IOException { |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE); |
|
|
assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, OK, LOCK_FAILURE); |
|
|
assertResults(cmds, OK, LOCK_FAILURE); |
|
|
assertRefs("refs/heads/master", B); |
|
|
assertRefs("refs/heads/master", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void nonExistentRefRefsChangedEvents() throws IOException { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(A, zeroId(), "refs/heads/foo2", DELETE)); |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void noRefLog() throws IOException { |
|
|
public void noRefLog() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
Map<String, ReflogEntry> oldLogs = |
|
|
Map<String, ReflogEntry> oldLogs = |
|
|
getLastReflogs("refs/heads/master", "refs/heads/branch"); |
|
|
getLastReflogs("refs/heads/master", "refs/heads/branch"); |
|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/branch", B); |
|
|
"refs/heads/branch", B); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/master"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/master"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/branch"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/branch"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void reflogDefaultIdent() throws IOException { |
|
|
public void reflogDefaultIdent() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/branch2", A); |
|
|
writeRef("refs/heads/branch2", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
Map<String, ReflogEntry> oldLogs = getLastReflogs( |
|
|
Map<String, ReflogEntry> oldLogs = getLastReflogs( |
|
|
"refs/heads/master", "refs/heads/branch1", "refs/heads/branch2"); |
|
|
"refs/heads/master", "refs/heads/branch1", "refs/heads/branch2"); |
|
|
|
|
|
|
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/branch1", B, |
|
|
"refs/heads/branch1", B, |
|
|
"refs/heads/branch2", A); |
|
|
"refs/heads/branch2", A); |
|
|
assertEquals(atomic ? 3 : 4, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog"), |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog"), |
|
|
getLastReflog("refs/heads/master")); |
|
|
getLastReflog("refs/heads/master")); |
|
|
|
|
|
|
|
|
public void reflogAppendStatusNoMessage() throws IOException { |
|
|
public void reflogAppendStatusNoMessage() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/branch1", B); |
|
|
writeRef("refs/heads/branch1", B); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
|
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/branch1", A, |
|
|
"refs/heads/branch1", A, |
|
|
"refs/heads/branch2", A); |
|
|
"refs/heads/branch2", A); |
|
|
assertEquals(atomic ? 3 : 5, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 3, |
|
|
|
|
|
refsChangedEvents); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
// Always forced; setAllowNonFastForwards(true) bypasses the check. |
|
|
// Always forced; setAllowNonFastForwards(true) bypasses the check. |
|
|
reflog(A, B, new PersonIdent(diskRepo), "forced-update"), |
|
|
reflog(A, B, new PersonIdent(diskRepo), "forced-update"), |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void reflogAppendStatusFastForward() throws IOException { |
|
|
public void reflogAppendStatusFastForward() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertResults(cmds, OK); |
|
|
assertResults(cmds, OK); |
|
|
assertRefs("refs/heads/master", B); |
|
|
assertRefs("refs/heads/master", B); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(A, B, new PersonIdent(diskRepo), "fast-forward"), |
|
|
reflog(A, B, new PersonIdent(diskRepo), "fast-forward"), |
|
|
getLastReflog("refs/heads/master")); |
|
|
getLastReflog("refs/heads/master")); |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void reflogAppendStatusWithMessage() throws IOException { |
|
|
public void reflogAppendStatusWithMessage() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
|
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/branch", A); |
|
|
"refs/heads/branch", A); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog: fast-forward"), |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog: fast-forward"), |
|
|
getLastReflog("refs/heads/master")); |
|
|
getLastReflog("refs/heads/master")); |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void reflogCustomIdent() throws IOException { |
|
|
public void reflogCustomIdent() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
|
|
|
.setRefLogIdent(ident)); |
|
|
.setRefLogIdent(ident)); |
|
|
|
|
|
|
|
|
assertResults(cmds, OK, OK); |
|
|
assertResults(cmds, OK, OK); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/branch", B); |
|
|
"refs/heads/branch", B); |
|
|
|
|
|
|
|
|
public void reflogDelete() throws IOException { |
|
|
public void reflogDelete() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/branch", A); |
|
|
writeRef("refs/heads/branch", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
assertEquals( |
|
|
assertEquals( |
|
|
2, getLastReflogs("refs/heads/master", "refs/heads/branch").size()); |
|
|
2, getLastReflogs("refs/heads/master", "refs/heads/branch").size()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertResults(cmds, OK, OK); |
|
|
assertResults(cmds, OK, OK); |
|
|
assertRefs("refs/heads/branch", B); |
|
|
assertRefs("refs/heads/branch", B); |
|
|
assertEquals(atomic ? 3 : 4, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertNull(getLastReflog("refs/heads/master")); |
|
|
assertNull(getLastReflog("refs/heads/master")); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog"), |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog"), |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void reflogFileDirectoryConflict() throws IOException { |
|
|
public void reflogFileDirectoryConflict() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
new ReceiveCommand(A, zeroId(), "refs/heads/master", DELETE), |
|
|
new ReceiveCommand(A, zeroId(), "refs/heads/master", DELETE), |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertResults(cmds, OK, OK); |
|
|
assertResults(cmds, OK, OK); |
|
|
assertRefs("refs/heads/master/x", A); |
|
|
assertRefs("refs/heads/master/x", A); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertNull(getLastReflog("refs/heads/master")); |
|
|
assertNull(getLastReflog("refs/heads/master")); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(zeroId(), A, new PersonIdent(diskRepo), "a reflog"), |
|
|
reflog(zeroId(), A, new PersonIdent(diskRepo), "a reflog"), |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void reflogOnLockFailure() throws IOException { |
|
|
public void reflogOnLockFailure() throws IOException { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
Map<String, ReflogEntry> oldLogs = |
|
|
Map<String, ReflogEntry> oldLogs = |
|
|
getLastReflogs("refs/heads/master", "refs/heads/branch"); |
|
|
getLastReflogs("refs/heads/master", "refs/heads/branch"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE); |
|
|
assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(initialRefsChangedEvents, refsChangedEvents); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/master"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/master"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/branch"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/branch"); |
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, OK, LOCK_FAILURE); |
|
|
assertResults(cmds, OK, LOCK_FAILURE); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog"), |
|
|
reflog(A, B, new PersonIdent(diskRepo), "a reflog"), |
|
|
getLastReflog("refs/heads/master")); |
|
|
getLastReflog("refs/heads/master")); |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void overrideRefLogMessage() throws Exception { |
|
|
public void overrideRefLogMessage() throws Exception { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
|
|
|
.setRefLogMessage("a reflog", true)); |
|
|
.setRefLogMessage("a reflog", true)); |
|
|
|
|
|
|
|
|
assertResults(cmds, OK, OK); |
|
|
assertResults(cmds, OK, OK); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(A, B, ident, "custom log"), |
|
|
reflog(A, B, ident, "custom log"), |
|
|
getLastReflog("refs/heads/master"), |
|
|
getLastReflog("refs/heads/master"), |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void overrideDisableRefLog() throws Exception { |
|
|
public void overrideDisableRefLog() throws Exception { |
|
|
writeRef("refs/heads/master", A); |
|
|
writeRef("refs/heads/master", A); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
Map<String, ReflogEntry> oldLogs = |
|
|
Map<String, ReflogEntry> oldLogs = |
|
|
getLastReflogs("refs/heads/master", "refs/heads/branch"); |
|
|
getLastReflogs("refs/heads/master", "refs/heads/branch"); |
|
|
|
|
|
|
|
|
execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true)); |
|
|
execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true)); |
|
|
|
|
|
|
|
|
assertResults(cmds, OK, OK); |
|
|
assertResults(cmds, OK, OK); |
|
|
assertEquals(atomic ? 2 : 3, refsChangedEvents); |
|
|
|
|
|
|
|
|
assertEquals(atomic ? initialRefsChangedEvents + 1 |
|
|
|
|
|
: initialRefsChangedEvents + 2, refsChangedEvents); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/master"); |
|
|
assertReflogUnchanged(oldLogs, "refs/heads/master"); |
|
|
assertReflogEquals( |
|
|
assertReflogEquals( |
|
|
reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog: created"), |
|
|
reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog: created"), |
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED); |
|
|
assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// Only operates on loose refs, doesn't care that packed-refs is locked. |
|
|
// Only operates on loose refs, doesn't care that packed-refs is locked. |
|
|
assertResults(cmds, OK, OK); |
|
|
assertResults(cmds, OK, OK); |
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/master", B, |
|
|
"refs/heads/branch", B); |
|
|
"refs/heads/branch", B); |
|
|
assertEquals(3, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} finally { |
|
|
} finally { |
|
|
myLock.unlock(); |
|
|
myLock.unlock(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void packedRefsLockFailureRefsChangedEvents() throws Exception { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE)); |
|
|
|
|
|
|
|
|
|
|
|
LockFile myLock = refdir.lockPackedRefs(); |
|
|
|
|
|
try { |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals( |
|
|
|
|
|
atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 2, |
|
|
|
|
|
refsChangedEvents); |
|
|
|
|
|
} finally { |
|
|
|
|
|
myLock.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void oneRefLockFailure() throws Exception { |
|
|
public void oneRefLockFailure() throws Exception { |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
|
|
|
if (atomic) { |
|
|
if (atomic) { |
|
|
assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE); |
|
|
assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertRefs("refs/heads/master", A); |
|
|
assertEquals(1, refsChangedEvents); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
assertResults(cmds, OK, LOCK_FAILURE); |
|
|
assertResults(cmds, OK, LOCK_FAILURE); |
|
|
assertRefs( |
|
|
assertRefs( |
|
|
"refs/heads/branch", B, |
|
|
"refs/heads/branch", B, |
|
|
"refs/heads/master", A); |
|
|
"refs/heads/master", A); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
} |
|
|
} |
|
|
} finally { |
|
|
} finally { |
|
|
myLock.unlock(); |
|
|
myLock.unlock(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void oneRefLockFailureRefsChangedEvents() throws Exception { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE), |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); |
|
|
|
|
|
|
|
|
|
|
|
LockFile myLock = new LockFile(refdir.fileFor("refs/heads/master")); |
|
|
|
|
|
assertTrue(myLock.lock()); |
|
|
|
|
|
try { |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals( |
|
|
|
|
|
atomic ? initialRefsChangedEvents |
|
|
|
|
|
: initialRefsChangedEvents + 1, |
|
|
|
|
|
refsChangedEvents); |
|
|
|
|
|
} finally { |
|
|
|
|
|
myLock.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void singleRefUpdateDoesNotRequirePackedRefsLock() throws Exception { |
|
|
public void singleRefUpdateDoesNotRequirePackedRefsLock() throws Exception { |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertFalse(getLockFile("refs/heads/master").exists()); |
|
|
assertFalse(getLockFile("refs/heads/master").exists()); |
|
|
assertResults(cmds, OK); |
|
|
assertResults(cmds, OK); |
|
|
assertEquals(2, refsChangedEvents); |
|
|
|
|
|
assertRefs("refs/heads/master", B); |
|
|
assertRefs("refs/heads/master", B); |
|
|
} finally { |
|
|
} finally { |
|
|
myLock.unlock(); |
|
|
myLock.unlock(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void singleRefUpdateDoesNotRequirePackedRefsLockRefsChangedEvents() |
|
|
|
|
|
throws Exception { |
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays |
|
|
|
|
|
.asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); |
|
|
|
|
|
|
|
|
|
|
|
LockFile myLock = refdir.lockPackedRefs(); |
|
|
|
|
|
try { |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} finally { |
|
|
|
|
|
myLock.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void atomicUpdateRespectsInProcessLock() throws Exception { |
|
|
public void atomicUpdateRespectsInProcessLock() throws Exception { |
|
|
assumeTrue(atomic); |
|
|
assumeTrue(atomic); |
|
|
|
|
|
|
|
|
"refs/heads/branch", B); |
|
|
"refs/heads/branch", B); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void atomicUpdateRespectsInProcessLockRefsChangedEvents() |
|
|
|
|
|
throws Exception { |
|
|
|
|
|
assumeTrue(atomic); |
|
|
|
|
|
|
|
|
|
|
|
writeLooseRef("refs/heads/master", A); |
|
|
|
|
|
refdir.exactRef("refs/heads/master"); |
|
|
|
|
|
int initialRefsChangedEvents = refsChangedEvents; |
|
|
|
|
|
|
|
|
|
|
|
List<ReceiveCommand> cmds = Arrays.asList( |
|
|
|
|
|
new ReceiveCommand(A, B, "refs/heads/master", UPDATE), |
|
|
|
|
|
new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE)); |
|
|
|
|
|
|
|
|
|
|
|
Thread t = new Thread(() -> { |
|
|
|
|
|
try { |
|
|
|
|
|
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
ReentrantLock l = refdir.inProcessPackedRefsLock; |
|
|
|
|
|
l.lock(); |
|
|
|
|
|
try { |
|
|
|
|
|
t.start(); |
|
|
|
|
|
long timeoutSecs = 10; |
|
|
|
|
|
|
|
|
|
|
|
// Hold onto the lock until we observe the worker thread has |
|
|
|
|
|
// attempted to |
|
|
|
|
|
// acquire it. |
|
|
|
|
|
while (l.getQueueLength() == 0) { |
|
|
|
|
|
Thread.sleep(3); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Once we unlock, the worker thread should finish the update |
|
|
|
|
|
// promptly. |
|
|
|
|
|
l.unlock(); |
|
|
|
|
|
t.join(SECONDS.toMillis(timeoutSecs)); |
|
|
|
|
|
} finally { |
|
|
|
|
|
if (l.isHeldByCurrentThread()) { |
|
|
|
|
|
l.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
assertEquals(initialRefsChangedEvents + 1, refsChangedEvents); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private void setLogAllRefUpdates(boolean enable) throws Exception { |
|
|
private void setLogAllRefUpdates(boolean enable) throws Exception { |
|
|
StoredConfig cfg = diskRepo.getConfig(); |
|
|
StoredConfig cfg = diskRepo.getConfig(); |
|
|
cfg.load(); |
|
|
cfg.load(); |