Add ability to back up as tag
This creates the functionality required to create a tag instead of
a branch, which also allows us to store audit information, such as
who triggered the deletion or the push.
Change-Id: I31fd05675a33a6eba20dd7cf6a3703fbfd981ead
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 aab80bb..93f0227 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/refprotection/BackupRef.java
@@ -36,8 +36,13 @@
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.TagBuilder;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,32 +71,81 @@
public void createBackup(RefUpdatedEvent event, ProjectResource project) {
String refName = event.getRefName();
- String backupRef = get(project, refName);
-
- // No-op if the backup branch name is same as the original
- if (backupRef.equals(refName)) {
- return;
- }
try (Repository git = repoManager.openRepository(project.getNameKey())) {
- try (RevWalk revWalk = new RevWalk(git)) {
- CreateBranch.Input input = new CreateBranch.Input();
- input.ref = backupRef;
- // We need to parse the commit to ensure if it's a tag, we get the
- // commit the tag points to!
- input.revision =
- ObjectId.toString(revWalk.parseCommit(ObjectId.fromString(event.refUpdate.oldRev))
- .getId());
+ String backupRef = get(project, refName);
- try {
- createBranchFactory.create(backupRef).apply(project, input);
- } catch (BadRequestException | AuthException | ResourceConflictException
- | IOException e) {
- log.error(e.getMessage(), e);
+ // No-op if the backup branch name is same as the original
+ if (backupRef.equals(refName)) {
+ return;
+ }
+
+ try (RevWalk revWalk = new RevWalk(git)) {
+ if (cfg.getFromGerritConfig(pluginName).getBoolean("createTag",
+ false)) {
+ TagBuilder tag = new TagBuilder();
+ tag.setTagger(
+ new PersonIdent(event.submitter.name, event.submitter.email));
+ tag.setObjectId(revWalk
+ .parseCommit(ObjectId.fromString(event.refUpdate.oldRev)));
+ String update = "Non-fast-forward update to";
+ if (event.refUpdate.newRev.equals(ObjectId.zeroId().getName())) {
+ update = "Deleted";
+ }
+ String type = "branch";
+ if (event.refUpdate.refName.startsWith(R_TAGS)) {
+ type = "tag";
+ }
+ tag.setMessage(update + " " + type + " " + event.refUpdate.refName);
+ tag.setTag(backupRef);
+
+ ObjectInserter inserter = git.newObjectInserter();
+ ObjectId tagId = inserter.insert(tag);
+ inserter.flush();
+ RefUpdate tagRef = git.updateRef(tag.getTag());
+ tagRef.setNewObjectId(tagId);
+ tagRef.setRefLogMessage("tagged deleted branch/tag " + tag.getTag(),
+ false);
+ tagRef.setForceUpdate(false);
+ Result result = tagRef.update();
+ switch (result) {
+ case NEW:
+ case FORCED:
+ log.debug("Successfully created backup tag");
+ break;
+
+ case LOCK_FAILURE:
+ log.error("Failed to lock repository while creating backup tag");
+ break;
+
+ case REJECTED:
+ log.error("Tag already exists while creating backup tag");
+ break;
+
+ default:
+ log.error("Unknown error while creating backup tag");
+ }
+ } else {
+ CreateBranch.Input input = new CreateBranch.Input();
+ input.ref = backupRef;
+ // We need to parse the commit to ensure if it's a tag, we get the
+ // commit the tag points to!
+ input.revision = ObjectId.toString(
+ revWalk.parseCommit(ObjectId.fromString(event.refUpdate.oldRev))
+ .getId());
+
+ try {
+ createBranchFactory.create(backupRef).apply(project, input);
+ } catch (BadRequestException | AuthException
+ | ResourceConflictException | IOException e) {
+ log.error(e.getMessage(), e);
+ }
}
}
+ } catch (RepositoryNotFoundException e) {
+ log.error("Repository does not exist", e);
} catch (IOException e) {
- log.error(e.getMessage(), e);
+ log.error("Could not open repository", e);
}
}