From e41e8f8c3bc9f5edab1d271464364f95620ece8c Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 19 Nov 2015 17:55:38 -0500
Subject: [PATCH] Create filestore directory on startup

---
 src/main/java/com/gitblit/tickets/BranchTicketService.java |  136 ++++++++++++++++++++++++++++++++++++--------
 1 files changed, 110 insertions(+), 26 deletions(-)

diff --git a/src/main/java/com/gitblit/tickets/BranchTicketService.java b/src/main/java/com/gitblit/tickets/BranchTicketService.java
index fc0bd8f..8396693 100644
--- a/src/main/java/com/gitblit/tickets/BranchTicketService.java
+++ b/src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -30,8 +30,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
-import javax.inject.Inject;
-
 import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.dircache.DirCache;
@@ -45,6 +43,8 @@
 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.RefRename;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.RefUpdate.Result;
 import org.eclipse.jgit.lib.Repository;
@@ -58,6 +58,7 @@
 import com.gitblit.Constants;
 import com.gitblit.git.ReceiveCommandEvent;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -71,6 +72,8 @@
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.utils.StringUtils;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
 
 /**
  * Implementation of a ticket service based on an orphan branch.  All tickets
@@ -80,9 +83,10 @@
  * @author James Moger
  *
  */
+@Singleton
 public class BranchTicketService extends ITicketService implements RefsChangedListener {
 
-	public static final String BRANCH = "refs/gitblit/tickets";
+	public static final String BRANCH = "refs/meta/gitblit/tickets";
 
 	private static final String JOURNAL = "journal.json";
 
@@ -93,11 +97,13 @@
 	@Inject
 	public BranchTicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
 
 		super(runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager);
@@ -110,6 +116,7 @@
 
 	@Override
 	public BranchTicketService start() {
+		log.info("{} started", getClass().getSimpleName());
 		return this;
 	}
 
@@ -190,23 +197,45 @@
 	}
 
 	/**
-	 * Returns a RefModel for the refs/gitblit/tickets branch in the repository.
+	 * Returns a RefModel for the refs/meta/gitblit/tickets branch in the repository.
 	 * If the branch can not be found, null is returned.
 	 *
 	 * @return a refmodel for the gitblit tickets branch or null
 	 */
 	private RefModel getTicketsBranch(Repository db) {
-		List<RefModel> refs = JGitUtils.getRefs(db, Constants.R_GITBLIT);
+		List<RefModel> refs = JGitUtils.getRefs(db, "refs/");
+		Ref oldRef = null;
 		for (RefModel ref : refs) {
 			if (ref.reference.getName().equals(BRANCH)) {
 				return ref;
+			} else if (ref.reference.getName().equals("refs/gitblit/tickets")) {
+				oldRef = ref.reference;
+			}
+		}
+		if (oldRef != null) {
+			// rename old ref to refs/meta/gitblit/tickets
+			RefRename cmd;
+			try {
+				cmd = db.renameRef(oldRef.getName(), BRANCH);
+				cmd.setRefLogIdent(new PersonIdent("Gitblit", "gitblit@localhost"));
+				cmd.setRefLogMessage("renamed " + oldRef.getName() + " => " + BRANCH);
+				Result res = cmd.rename();
+				switch (res) {
+				case RENAMED:
+					log.info(db.getDirectory() + " " + cmd.getRefLogMessage());
+					return getTicketsBranch(db);
+				default:
+					log.error("failed to rename " + oldRef.getName() + " => " + BRANCH + " (" + res.name() + ")");
+				}
+			} catch (IOException e) {
+				log.error("failed to rename tickets branch", e);
 			}
 		}
 		return null;
 	}
 
 	/**
-	 * Creates the refs/gitblit/tickets branch.
+	 * Creates the refs/meta/gitblit/tickets branch.
 	 * @param db
 	 */
 	private void createTicketsBranch(Repository db) {
@@ -219,7 +248,7 @@
 	 * folder with the remaining characters as a subfolder within that folder.
 	 *
 	 * @param ticketId
-	 * @return the root path of the ticket content on the refs/gitblit/tickets branch
+	 * @return the root path of the ticket content on the refs/meta/gitblit/tickets branch
 	 */
 	private String toTicketPath(long ticketId) {
 		StringBuilder sb = new StringBuilder();
@@ -268,7 +297,7 @@
 			log.error("failed to read " + file, e);
 		} finally {
 			if (rw != null) {
-				rw.release();
+				rw.close();
 			}
 		}
 		return null;
@@ -324,7 +353,7 @@
 		} catch (IOException e) {
 			log.error("", e);
 		} finally {
-			inserter.release();
+			inserter.close();
 		}
 	}
 
@@ -354,6 +383,37 @@
 	}
 
 	/**
+	 * Returns the assigned ticket ids.
+	 *
+	 * @return the assigned ticket ids
+	 */
+	@Override
+	public synchronized Set<Long> getIds(RepositoryModel repository) {
+		Repository db = repositoryManager.getRepository(repository.name);
+		try {
+			if (getTicketsBranch(db) == null) {
+				return Collections.emptySet();
+			}
+			Set<Long> ids = new TreeSet<Long>();
+			List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
+			for (PathModel path : paths) {
+				String name = path.name.substring(path.name.lastIndexOf('/') + 1);
+				if (!JOURNAL.equals(name)) {
+					continue;
+				}
+				String tid = path.path.split("/")[2];
+				long ticketId = Long.parseLong(tid);
+				ids.add(ticketId);
+			}
+			return ids;
+		} finally {
+			if (db != null) {
+				db.close();
+			}
+		}
+	}
+
+	/**
 	 * Assigns a new ticket id.
 	 *
 	 * @param repository
@@ -374,16 +434,10 @@
 			}
 			AtomicLong lastId = lastAssignedId.get(repository.name);
 			if (lastId.get() <= 0) {
-				List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
-				for (PathModel path : paths) {
-					String name = path.name.substring(path.name.lastIndexOf('/') + 1);
-					if (!JOURNAL.equals(name)) {
-						continue;
-					}
-					String tid = path.path.split("/")[2];
-					long ticketId = Long.parseLong(tid);
-					if (ticketId > lastId.get()) {
-						lastId.set(ticketId);
+				Set<Long> ids = getIds(repository);
+				for (long id : ids) {
+					if (id > lastId.get()) {
+						lastId.set(id);
 					}
 				}
 			}
@@ -496,6 +550,28 @@
 				ticket.number = ticketId;
 			}
 			return ticket;
+		} finally {
+			db.close();
+		}
+	}
+
+	/**
+	 * Retrieves the journal for the ticket.
+	 *
+	 * @param repository
+	 * @param ticketId
+	 * @return a journal, if it exists, otherwise null
+	 */
+	@Override
+	protected List<Change> getJournalImpl(RepositoryModel repository, long ticketId) {
+		Repository db = repositoryManager.getRepository(repository.name);
+		try {
+			List<Change> changes = getJournal(db, ticketId);
+			if (ArrayUtils.isEmpty(changes)) {
+				log.warn("Empty journal for {}:{}", repository, ticketId);
+				return null;
+			}
+			return changes;
 		} finally {
 			db.close();
 		}
@@ -635,7 +711,9 @@
 						ticket.number, db.getDirectory()), t);
 			} finally {
 				// release the treewalk
-				treeWalk.release();
+				if (treeWalk != null) {
+					treeWalk.close();
+				}
 			}
 		} finally {
 			db.close();
@@ -733,7 +811,7 @@
 			// finish the index
 			builder.finish();
 		} finally {
-			inserter.release();
+			inserter.close();
 		}
 		return newIndex;
 	}
@@ -750,8 +828,12 @@
 		List<DirCacheEntry> list = new ArrayList<DirCacheEntry>();
 		TreeWalk tw = null;
 		try {
-			tw = new TreeWalk(db);
 			ObjectId treeId = db.resolve(BRANCH + "^{tree}");
+			if (treeId == null) {
+				// branch does not exist yet, could be migrating tickets
+				return list;
+			}
+			tw = new TreeWalk(db);
 			int hIdx = tw.addTree(treeId);
 			tw.setRecursive(true);
 
@@ -773,7 +855,7 @@
 			}
 		} finally {
 			if (tw != null) {
-				tw.release();
+				tw.close();
 			}
 		}
 		return list;
@@ -831,10 +913,10 @@
 							rc));
 				}
 			} finally {
-				revWalk.release();
+				revWalk.close();
 			}
 		} finally {
-			odi.release();
+			odi.close();
 		}
 		return success;
 	}
@@ -851,7 +933,9 @@
 		} catch (Exception e) {
 			log.error(null, e);
 		} finally {
-			db.close();
+			if (db != null) {
+				db.close();
+			}
 		}
 		return false;
 	}

--
Gitblit v1.9.1