diff options
author | James Moger <james.moger@gitblit.com> | 2012-06-06 22:11:54 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2012-06-06 22:11:54 -0400 |
commit | f96d3233fde0d6dc5b61690e59794d209d77ae90 (patch) | |
tree | 28c3110970993f917d167fc753845ded70da75e0 | |
parent | 94dcbd617f3d06ca294d5d151390698e4bddd2cc (diff) | |
download | gitblit-f96d3233fde0d6dc5b61690e59794d209d77ae90.tar.gz gitblit-f96d3233fde0d6dc5b61690e59794d209d77ae90.zip |
Possible fix for federation branch mirroring issue (issue 86)
-rw-r--r-- | src/com/gitblit/FederationPullExecutor.java | 39 | ||||
-rw-r--r-- | src/com/gitblit/utils/JGitUtils.java | 68 | ||||
-rw-r--r-- | tests/com/gitblit/tests/JGitUtilsTest.java | 19 |
3 files changed, 106 insertions, 20 deletions
diff --git a/src/com/gitblit/FederationPullExecutor.java b/src/com/gitblit/FederationPullExecutor.java index 432e293f..7b9c55ba 100644 --- a/src/com/gitblit/FederationPullExecutor.java +++ b/src/com/gitblit/FederationPullExecutor.java @@ -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
diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index 72e948cc..f5ca5efd 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -1223,6 +1223,74 @@ public class JGitUtils { }
/**
+ * 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.
*
* @param repository
diff --git a/tests/com/gitblit/tests/JGitUtilsTest.java b/tests/com/gitblit/tests/JGitUtilsTest.java index 74531fa4..616ea837 100644 --- a/tests/com/gitblit/tests/JGitUtilsTest.java +++ b/tests/com/gitblit/tests/JGitUtilsTest.java @@ -236,6 +236,25 @@ public class JGitUtilsTest { }
@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");
assertTrue(JGitUtils.createOrphanBranch(repository,
|