Add configuration for backup branch names
This enables backup branches to follow two different naming schemes:
it can be backed up by a time/date stamp, or it can use an
incrementing counter to create a unique name. The time/date stamp
option is default to preserve legacy behavior.
Change-Id: I7493e9d020055685da409119ac64a46f6af6cf07
diff --git a/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java b/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java
index b35e930..e4d7fc8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java
@@ -23,14 +23,20 @@
*/
package com.googlesource.gerrit.plugins.refprotection;
+import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener.Event;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.CreateBranch;
import com.google.gerrit.server.project.ProjectResource;
import com.google.inject.Inject;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,6 +53,9 @@
private static final Logger log =
LoggerFactory.getLogger(BackupRef.class);
private final CreateBranch.Factory createBranchFactory;
+ @Inject private static PluginConfigFactory cfg;
+ @Inject private static GitRepositoryManager repoManager;
+ @Inject @PluginName private static String pluginName;
@Inject
BackupRef(CreateBranch.Factory createBranchFactory) {
@@ -55,7 +64,7 @@
public void createBackup(Event event, ProjectResource project) {
String refName = event.getRefName();
- String backupRef = get(refName);
+ String backupRef = get(project, refName);
// No-op if the backup branch name is same as the original
if (backupRef.equals(refName)) {
@@ -74,7 +83,16 @@
}
}
- static String get(String refName) {
+ static String get(ProjectResource project, String refName) {
+ if (cfg.getFromGerritConfig(pluginName).getBoolean("useTimestamp", true)) {
+ return getTimestampBranch(refName);
+ }
+ else {
+ return getSequentialBranch(project, refName);
+ }
+ }
+
+ private static String getTimestampBranch(String refName) {
if (refName.startsWith(R_HEADS) || refName.startsWith(R_TAGS)) {
return String.format("%s-%s",
R_BACKUPS + refName.replaceFirst(R_REFS, ""),
@@ -83,4 +101,27 @@
return refName;
}
+
+ private static String getSequentialBranch(ProjectResource project, String branchName) {
+ Integer rev = 1;
+ String deletedName = branchName.replaceFirst(R_REFS, "");
+ try (Repository git = repoManager.openRepository(project.getNameKey())) {
+ for (Ref ref : git.getAllRefs().values()) {
+ String name = ref.getName();
+ if (name.startsWith(R_BACKUPS + deletedName + "/")) {
+ Integer thisNum =
+ Integer.parseInt(name.substring(name.lastIndexOf('/') + 1));
+ if (thisNum >= rev) {
+ rev = thisNum + 1;
+ }
+ }
+ }
+ } catch (RepositoryNotFoundException e) {
+ log.error("Repository does not exist", e);
+ } catch (IOException e) {
+ log.error("Could not determine latest revision of deleted branch", e);
+ }
+
+ return R_BACKUPS + deletedName + "/" + rev;
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/refprotection/RefProtectionModule.java b/src/main/java/com/googlesource/gerrit/plugins/refprotection/RefProtectionModule.java
index 96d250c..48de79a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/refprotection/RefProtectionModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/refprotection/RefProtectionModule.java
@@ -32,5 +32,6 @@
protected void configure() {
DynamicSet.bind(binder(), GitReferenceUpdatedListener.class).to(
RefUpdateListener.class);
+ requestStaticInjection(BackupRef.class);
}
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/refprotection/BackupRefNameTest.java b/src/test/java/com/googlesource/gerrit/plugins/refprotection/BackupRefNameTest.java
index 0ad095f..d38f3b5 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/refprotection/BackupRefNameTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/refprotection/BackupRefNameTest.java
@@ -7,22 +7,22 @@
public class BackupRefNameTest {
@Test
- public void backupRefNameForTag() throws Exception {
- String name = BackupRef.get("refs/tags/v1.0");
+ public void backupTimestampRefNameForTag() throws Exception {
+ String name = BackupRef.get(null, "refs/tags/v1.0");
String expected_prefix = BackupRef.R_BACKUPS + "tags/v1.0-";
assertThat(name).startsWith(expected_prefix);
}
@Test
- public void backupRefNameForBranch() throws Exception {
- String name = BackupRef.get("refs/heads/master");
+ public void backupTimestampRefNameForBranch() throws Exception {
+ String name = BackupRef.get(null, "refs/heads/master");
String expected_prefix = BackupRef.R_BACKUPS + "heads/master-";
assertThat(name).startsWith(expected_prefix);
}
@Test
- public void backupRefNameForUnsupportedNamespace() throws Exception {
+ public void backupTimestampRefNameForUnsupportedNamespace() throws Exception {
String ref = "refs/changes/45/12345/1";
- assertThat(BackupRef.get(ref)).isEqualTo(ref);
+ assertThat(BackupRef.get(null, ref)).isEqualTo(ref);
}
}