Browse Source

Possible fix for federation branch mirroring issue (issue 86)

tags/v1.0.0
James Moger 12 years ago
parent
commit
f96d3233fd

+ 19
- 20
src/com/gitblit/FederationPullExecutor.java View File

@@ -33,10 +33,6 @@ import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -243,25 +239,28 @@ public class FederationPullExecutor implements Runnable {
if (registration.mirror) {
// mirror
if (fetched) {
// find the first branch name that FETCH_HEAD points to
List<RefModel> refs = JGitUtils.getAllRefs(r).get(commit.getId());
if (!ArrayUtils.isEmpty(refs)) {
for (RefModel ref : refs) {
if (ref.displayName.startsWith(org.eclipse.jgit.lib.Constants.R_REMOTES)) {
newFetchHead = ref.displayName;
break;
}
// update local branches to match the remote tracking branches
for (RefModel ref : JGitUtils.getRemoteBranches(r, false, -1)) {
if (ref.displayName.startsWith("origin/")) {
String branch = org.eclipse.jgit.lib.Constants.R_HEADS
+ ref.displayName.substring(ref.displayName.indexOf('/') + 1);
String hash = ref.getReferencedObjectId().getName();
JGitUtils.setBranchRef(r, branch, hash);
logger.info(MessageFormat.format(" resetting {0} of {1} to {2}", branch,
repository.name, hash));
}
}
// reset HEAD to the FETCH_HEAD branch.
// if no branch was found, reset HEAD to the commit id.
Git git = new Git(r);
ResetCommand reset = git.reset();
reset.setMode(ResetType.SOFT);
reset.setRef(newFetchHead);
Ref ref = reset.call();
String newHead;
if (StringUtils.isEmpty(repository.HEAD)) {
newHead = newFetchHead;
} else {
newHead = repository.HEAD;
}
JGitUtils.setHEADtoRef(r, newHead);
logger.info(MessageFormat.format(" resetting HEAD of {0} to {1}",
repository.name, ref.getObjectId().getName()));
repository.name, newHead));
registration.updateStatus(repository, FederationPullStatus.MIRRORED);
} else {
// indicate no commits pulled

+ 68
- 0
src/com/gitblit/utils/JGitUtils.java View File

@@ -1222,6 +1222,74 @@ public class JGitUtils {
return false;
}
/**
* Sets the local branch ref to point to the specified commit id.
*
* @param repository
* @param branch
* @param commitId
* @return true if successful
*/
public static boolean setBranchRef(Repository repository, String branch, String commitId) {
String branchName = branch;
if (!branchName.startsWith(Constants.R_HEADS)) {
branchName = Constants.R_HEADS + branch;
}
try {
RefUpdate refUpdate = repository.updateRef(branchName, false);
refUpdate.setNewObjectId(ObjectId.fromString(commitId));
RefUpdate.Result result = refUpdate.forceUpdate();
switch (result) {
case NEW:
case FORCED:
case NO_CHANGE:
case FAST_FORWARD:
return true;
default:
LOGGER.error(MessageFormat.format("{0} {1} update to {2} returned result {3}",
repository.getDirectory().getAbsolutePath(), branchName, commitId, result));
}
} catch (Throwable t) {
error(t, repository, "{0} failed to set {1} to {2}", branchName, commitId);
}
return false;
}
/**
* Deletes the specified branch ref.
*
* @param repository
* @param branch
* @return true if successful
*/
public static boolean deleteBranchRef(Repository repository, String branch) {
String branchName = branch;
if (!branchName.startsWith(Constants.R_HEADS)) {
branchName = Constants.R_HEADS + branch;
}
try {
RefUpdate refUpdate = repository.updateRef(branchName, false);
refUpdate.setForceUpdate(true);
RefUpdate.Result result = refUpdate.delete();
switch (result) {
case NEW:
case FORCED:
case NO_CHANGE:
case FAST_FORWARD:
return true;
default:
LOGGER.error(MessageFormat.format("{0} failed to delete to {1} returned result {2}",
repository.getDirectory().getAbsolutePath(), branchName, result));
}
} catch (Throwable t) {
error(t, repository, "{0} failed to delete {1}", branchName);
}
return false;
}
/**
* Get the full branch and tag ref names for any potential HEAD targets.
*

+ 19
- 0
tests/com/gitblit/tests/JGitUtilsTest.java View File

@@ -235,6 +235,25 @@ public class JGitUtilsTest {
repository.close();
}
@Test
public void testRelinkBranch() throws Exception {
Repository repository = GitBlitSuite.getJGitRepository();
// create/set the branch
JGitUtils.setBranchRef(repository, "refs/heads/reftest", "3b358ce514ec655d3ff67de1430994d8428cdb04");
assertEquals(1, JGitUtils.getAllRefs(repository).get(ObjectId.fromString("3b358ce514ec655d3ff67de1430994d8428cdb04")).size());
assertEquals(null, JGitUtils.getAllRefs(repository).get(ObjectId.fromString("755dfdb40948f5c1ec79e06bde3b0a78c352f27f")));
// reset the branch
JGitUtils.setBranchRef(repository, "refs/heads/reftest", "755dfdb40948f5c1ec79e06bde3b0a78c352f27f");
assertEquals(null, JGitUtils.getAllRefs(repository).get(ObjectId.fromString("3b358ce514ec655d3ff67de1430994d8428cdb04")));
assertEquals(1, JGitUtils.getAllRefs(repository).get(ObjectId.fromString("755dfdb40948f5c1ec79e06bde3b0a78c352f27f")).size());
// delete the branch
assertTrue(JGitUtils.deleteBranchRef(repository, "refs/heads/reftest"));
repository.close();
}
@Test
public void testCreateOrphanedBranch() throws Exception {
Repository repository = JGitUtils.createRepository(GitBlitSuite.REPOSITORIES, "orphantest");

Loading…
Cancel
Save