From 7847af6e63e7adef6ec8d99a1809e91472d2bc2d Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 05 Sep 2013 09:14:22 -0400
Subject: [PATCH] Restore blockpush and localclone hooks to binaries (issue-303)

---
 src/main/java/com/gitblit/utils/JGitUtils.java |  109 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 93 insertions(+), 16 deletions(-)

diff --git a/src/main/java/com/gitblit/utils/JGitUtils.java b/src/main/java/com/gitblit/utils/JGitUtils.java
index 1e0ea5d..3f01eea 100644
--- a/src/main/java/com/gitblit/utils/JGitUtils.java
+++ b/src/main/java/com/gitblit/utils/JGitUtils.java
@@ -297,6 +297,7 @@
 		list.addAll(getRepositoryList(repositoriesFolder.getAbsolutePath(), repositoriesFolder,
 				onlyBare, searchSubfolders, depth, patterns));
 		StringUtils.sortRepositorynames(list);
+		list.remove(".git"); // issue-256
 		return list;
 	}
 
@@ -438,39 +439,56 @@
 		}
 		return false;
 	}
+	
+	/**
+	 * Encapsulates the result of cloning or pulling from a repository.
+	 */
+	public static class LastChange {
+		public Date when;
+		public String who;
+		
+		LastChange() {
+			when = new Date(0);			
+		}
+		
+		LastChange(long lastModified) {
+			this.when = new Date(lastModified);
+		}
+	}
 
 	/**
-	 * Returns the date of the most recent commit on a branch. If the repository
-	 * does not exist Date(0) is returned. If it does exist but is empty, the
-	 * last modified date of the repository folder is returned.
+	 * Returns the date and author of the most recent commit on a branch. If the
+	 * repository does not exist Date(0) is returned. If it does exist but is
+	 * empty, the last modified date of the repository folder is returned.
 	 * 
 	 * @param repository
-	 * @return
+	 * @return a LastChange object
 	 */
-	public static Date getLastChange(Repository repository) {
+	public static LastChange getLastChange(Repository repository) {
 		if (!hasCommits(repository)) {
 			// null repository
 			if (repository == null) {
-				return new Date(0);
+				return new LastChange();
 			}
 			// fresh repository
-			return new Date(repository.getDirectory().lastModified());
+			return new LastChange(repository.getDirectory().lastModified());
 		}
 
 		List<RefModel> branchModels = getLocalBranches(repository, true, -1);
 		if (branchModels.size() > 0) {
 			// find most recent branch update
-			Date lastChange = new Date(0);
+			LastChange lastChange = new LastChange();			
 			for (RefModel branchModel : branchModels) {
-				if (branchModel.getDate().after(lastChange)) {
-					lastChange = branchModel.getDate();
+				if (branchModel.getDate().after(lastChange.when)) {
+					lastChange.when = branchModel.getDate();
+					lastChange.who = branchModel.getAuthorIdent().getName();
 				}
 			}
 			return lastChange;
 		}
 		
 		// default to the repository folder modification date
-		return new Date(repository.getDirectory().lastModified());
+		return new LastChange(repository.getDirectory().lastModified());
 	}
 
 	/**
@@ -548,6 +566,8 @@
 		try {
 			if (tree == null) {
 				ObjectId object = getDefaultBranch(repository);
+				if (object == null)
+					return null;
 				RevCommit commit = rw.parseCommit(object);
 				tree = commit.getTree();
 			}
@@ -771,6 +791,51 @@
 	}
 
 	/**
+	 * Returns the list of files changed in a specified commit. If the
+	 * repository does not exist or is empty, an empty list is returned.
+	 * 
+	 * @param repository
+	 * @param startCommit
+	 *            earliest commit
+	 * @param endCommit
+	 *            most recent commit. if null, HEAD is assumed.
+	 * @return list of files changed in a commit range
+	 */
+	public static List<PathChangeModel> getFilesInRange(Repository repository, RevCommit startCommit, RevCommit endCommit) {
+		List<PathChangeModel> list = new ArrayList<PathChangeModel>();
+		if (!hasCommits(repository)) {
+			return list;
+		}
+		try {
+			DiffFormatter df = new DiffFormatter(null);
+			df.setRepository(repository);
+			df.setDiffComparator(RawTextComparator.DEFAULT);
+			df.setDetectRenames(true);
+
+			List<DiffEntry> diffEntries = df.scan(startCommit.getTree(), endCommit.getTree());
+			for (DiffEntry diff : diffEntries) {
+				
+				if (diff.getChangeType().equals(ChangeType.DELETE)) {
+					list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff
+							.getNewMode().getBits(), diff.getOldId().name(), null, diff
+							.getChangeType()));
+				} else if (diff.getChangeType().equals(ChangeType.RENAME)) {
+					list.add(new PathChangeModel(diff.getOldPath(), diff.getNewPath(), 0, diff
+							.getNewMode().getBits(), diff.getNewId().name(), null, diff
+							.getChangeType()));
+				} else {
+					list.add(new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff
+							.getNewMode().getBits(), diff.getNewId().name(), null, diff
+							.getChangeType()));
+				}
+			}			
+			Collections.sort(list);
+		} catch (Throwable t) {
+			error(t, repository, "{0} failed to determine files in range {1}..{2}!", startCommit, endCommit);
+		}
+		return list;
+	}
+	/**
 	 * Returns the list of files in the repository on the default branch that
 	 * match one of the specified extensions. This is a CASE-SENSITIVE search.
 	 * If the repository does not exist or is empty, an empty list is returned.
@@ -981,18 +1046,30 @@
 		}
 		try {
 			// resolve branch
-			ObjectId branchObject;
+			ObjectId startRange = null;
+			ObjectId endRange;
 			if (StringUtils.isEmpty(objectId)) {
-				branchObject = getDefaultBranch(repository);
+				endRange = getDefaultBranch(repository);
 			} else {
-				branchObject = repository.resolve(objectId);
+				if( objectId.contains("..") ) {
+					// range expression
+					String[] parts = objectId.split("\\.\\.");
+					startRange = repository.resolve(parts[0]);
+					endRange = repository.resolve(parts[1]);
+				} else {
+					// objectid
+					endRange= repository.resolve(objectId);
+				}
 			}
-			if (branchObject == null) {
+			if (endRange == null) {
 				return list;
 			}
 
 			RevWalk rw = new RevWalk(repository);
-			rw.markStart(rw.parseCommit(branchObject));
+			rw.markStart(rw.parseCommit(endRange));
+			if (startRange != null) {
+				rw.markUninteresting(rw.parseCommit(startRange));	
+			}
 			if (!StringUtils.isEmpty(path)) {
 				TreeFilter filter = AndTreeFilter.create(
 						PathFilterGroup.createFromStrings(Collections.singleton(path)),

--
Gitblit v1.9.1