From 2fca824e349f5fecbf71d940c4521644e92cb0dd Mon Sep 17 00:00:00 2001
From: Paul Martin <paul@paulsputer.com>
Date: Wed, 06 Apr 2016 14:49:09 -0400
Subject: [PATCH] Merge pull request #1039 from gitblit/962-Patchset-Revision-Delete

---
 src/main/java/com/gitblit/wicket/pages/TicketPage.java |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/gitblit/wicket/pages/TicketPage.java b/src/main/java/com/gitblit/wicket/pages/TicketPage.java
index 8bf5c6d..b2e63a6 100644
--- a/src/main/java/com/gitblit/wicket/pages/TicketPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/TicketPage.java
@@ -15,6 +15,7 @@
  */
 package com.gitblit.wicket.pages;
 
+import java.io.IOException;
 import java.text.DateFormat;
 import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
@@ -35,6 +36,7 @@
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.PageParameters;
+import org.apache.wicket.RequestCycle;
 import org.apache.wicket.RestartResponseException;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.behavior.SimpleAttributeModifier;
@@ -42,12 +44,17 @@
 import org.apache.wicket.markup.html.image.ContextImage;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
 import org.apache.wicket.markup.html.link.ExternalLink;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.html.link.StatelessLink;
+import org.apache.wicket.markup.html.pages.RedirectPage;
 import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.markup.repeater.data.DataView;
 import org.apache.wicket.markup.repeater.data.ListDataProvider;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.protocol.http.RequestUtils;
 import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.request.target.basic.RedirectRequestTarget;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
@@ -82,13 +89,16 @@
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.utils.JGitUtils.MergeStatus;
+import com.gitblit.utils.CommitCache;
 import com.gitblit.utils.MarkdownUtils;
+import com.gitblit.utils.RefLogUtils;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.TimeUtils;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.TicketsUI;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.panels.AvatarImage;
+import com.gitblit.wicket.panels.BasePanel.JavascriptEventConfirmation;
 import com.gitblit.wicket.panels.BasePanel.JavascriptTextPrompt;
 import com.gitblit.wicket.panels.CommentPanel;
 import com.gitblit.wicket.panels.DiffStatPanel;
@@ -853,6 +863,9 @@
 				if (event.hasPatchset()) {
 					// patchset
 					Patchset patchset = event.patchset;
+					//In the case of using a cached change list
+					item.setVisible(!patchset.isDeleted());
+					
 					String what;
 					if (event.isStatusChange() && (Status.New == event.getStatus())) {
 						what = getString("gb.proposedThisChange");
@@ -880,6 +893,14 @@
 					}
 					item.add(typeLabel);
 
+					Link<Void> deleteLink = createDeletePatchsetLink(repository, patchset);
+					
+					if (user.canDeleteRef(repository)) {
+						item.add(deleteLink.setVisible(patchset.canDelete));
+					} else {
+						item.add(deleteLink.setVisible(false));
+					}
+
 					// show commit diffstat
 					item.add(new DiffStatPanel("patchsetDiffStat", patchset.insertions, patchset.deletions, patchset.rev > 1));
 				} else if (event.hasComment()) {
@@ -887,6 +908,7 @@
 					item.add(new Label("what", getString("gb.commented")));
 					item.add(new Label("patchsetRevision").setVisible(false));
 					item.add(new Label("patchsetType").setVisible(false));
+					item.add(new Label("deleteRevision").setVisible(false));
 					item.add(new Label("patchsetDiffStat").setVisible(false));
 				} else if (event.hasReview()) {
 					// review
@@ -906,11 +928,13 @@
 							.setEscapeModelStrings(false));
 					item.add(new Label("patchsetRevision").setVisible(false));
 					item.add(new Label("patchsetType").setVisible(false));
+					item.add(new Label("deleteRevision").setVisible(false));
 					item.add(new Label("patchsetDiffStat").setVisible(false));
 				} else {
 					// field change
 					item.add(new Label("patchsetRevision").setVisible(false));
 					item.add(new Label("patchsetType").setVisible(false));
+					item.add(new Label("deleteRevision").setVisible(false));
 					item.add(new Label("patchsetDiffStat").setVisible(false));
 
 					String what = "";
@@ -1600,4 +1624,85 @@
 			return copyFragment;
 		}
 	}
+	
+	private Link<Void> createDeletePatchsetLink(final RepositoryModel repositoryModel, final Patchset patchset)
+	{
+		Link<Void> deleteLink = new Link<Void>("deleteRevision") {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onClick() {
+				Repository r = app().repositories().getRepository(repositoryModel.name);
+				UserModel user = GitBlitWebSession.get().getUser();
+				
+				if (r == null) {
+					if (app().repositories().isCollectingGarbage(repositoryModel.name)) {
+						error(MessageFormat.format(getString("gb.busyCollectingGarbage"), repositoryModel.name));
+					} else {
+						error(MessageFormat.format("Failed to find repository {0}", repositoryModel.name));
+					}
+					return;
+				}
+				
+				//Construct the ref name based on the patchset
+				String ticketShard = String.format("%02d", ticket.number);
+				ticketShard = ticketShard.substring(ticketShard.length() - 2);
+				final String refName = String.format("%s%s/%d/%d", Constants.R_TICKETS_PATCHSETS, ticketShard, ticket.number, patchset.number);
+
+				Ref ref = null;
+				boolean success = true;
+				
+				try {
+					ref = r.getRef(refName);
+					
+					if (ref != null) {
+						success = JGitUtils.deleteBranchRef(r, ref.getName());
+					} else {
+						success = false;
+					}
+					
+					if (success) {
+						// clear commit cache
+						CommitCache.instance().clear(repositoryModel.name, refName);
+
+						// optionally update reflog
+						if (RefLogUtils.hasRefLogBranch(r)) {
+							RefLogUtils.deleteRef(user, r, ref);
+						}
+
+						TicketModel updatedTicket = app().tickets().deletePatchset(ticket, patchset, user.username);
+												
+						if (updatedTicket == null) {
+							success = false;
+						}
+					}
+				} catch (IOException e) {
+					logger().error("failed to determine ticket from ref", e);
+					success = false;
+				} finally {
+					r.close();
+				}
+
+				if (success) {
+					getSession().info(MessageFormat.format(getString("gb.deletePatchsetSuccess"), patchset.number));
+					logger().info(MessageFormat.format("{0} deleted patchset {1} from ticket {2}", 
+							user.username, patchset.number, ticket.number));
+				} else {
+					getSession().error(MessageFormat.format(getString("gb.deletePatchsetFailure"),patchset.number));
+				}
+				
+				//Force reload of the page to rebuild ticket change cache
+				String relativeUrl = urlFor(TicketsPage.class, getPageParameters()).toString();
+				String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
+				setResponsePage(new RedirectPage(absoluteUrl));
+			}
+		};
+
+		WicketUtils.setHtmlTooltip(deleteLink, MessageFormat.format(getString("gb.deletePatchset"), patchset.number));
+		
+		deleteLink.add(new JavascriptEventConfirmation("onclick", MessageFormat.format(getString("gb.deletePatchset"), patchset.number)));
+		
+		return deleteLink;
+	}
+	
 }

--
Gitblit v1.9.1