From 2987f602e112d37ff7db522c3cd9e653847a9865 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Mon, 06 Aug 2012 17:34:44 -0400
Subject: [PATCH] Restore original team or user object on failure to update (issue 118)
---
src/com/gitblit/utils/JGitUtils.java | 143 +++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 129 insertions(+), 14 deletions(-)
diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java
index 72e948c..4415982 100644
--- a/src/com/gitblit/utils/JGitUtils.java
+++ b/src/com/gitblit/utils/JGitUtils.java
@@ -20,7 +20,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -30,12 +29,14 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.diff.DiffFormatter;
@@ -258,8 +259,12 @@
* @return Repository
*/
public static Repository createRepository(File repositoriesFolder, String name) {
- Git git = Git.init().setDirectory(new File(repositoriesFolder, name)).setBare(true).call();
- return git.getRepository();
+ try {
+ Git git = Git.init().setDirectory(new File(repositoriesFolder, name)).setBare(true).call();
+ return git.getRepository();
+ } catch (GitAPIException e) {
+ throw new RuntimeException(e);
+ }
}
/**
@@ -271,16 +276,26 @@
* false all repositories are included.
* @param searchSubfolders
* recurse into subfolders to find grouped repositories
+ * @param depth
+ * optional recursion depth, -1 = infinite recursion
+ * @param exclusions
+ * list of regex exclusions for matching to folder names
* @return list of repository names
*/
public static List<String> getRepositoryList(File repositoriesFolder, boolean onlyBare,
- boolean searchSubfolders) {
+ boolean searchSubfolders, int depth, List<String> exclusions) {
List<String> list = new ArrayList<String>();
if (repositoriesFolder == null || !repositoriesFolder.exists()) {
return list;
}
+ List<Pattern> patterns = new ArrayList<Pattern>();
+ if (!ArrayUtils.isEmpty(exclusions)) {
+ for (String regex : exclusions) {
+ patterns.add(Pattern.compile(regex));
+ }
+ }
list.addAll(getRepositoryList(repositoriesFolder.getAbsolutePath(), repositoriesFolder,
- onlyBare, searchSubfolders));
+ onlyBare, searchSubfolders, depth, patterns));
StringUtils.sortRepositorynames(list);
return list;
}
@@ -297,25 +312,55 @@
* repositories are included.
* @param searchSubfolders
* recurse into subfolders to find grouped repositories
+ * @param depth
+ * recursion depth, -1 = infinite recursion
+ * @param patterns
+ * list of regex patterns for matching to folder names
* @return
*/
private static List<String> getRepositoryList(String basePath, File searchFolder,
- boolean onlyBare, boolean searchSubfolders) {
+ boolean onlyBare, boolean searchSubfolders, int depth, List<Pattern> patterns) {
File baseFile = new File(basePath);
List<String> list = new ArrayList<String>();
+ if (depth == 0) {
+ return list;
+ }
+
+ int nextDepth = (depth == -1) ? -1 : depth - 1;
for (File file : searchFolder.listFiles()) {
if (file.isDirectory()) {
+ boolean exclude = false;
+ for (Pattern pattern : patterns) {
+ String path = FileUtils.getRelativePath(baseFile, file).replace('\\', '/');
+ if (pattern.matcher(path).matches()) {
+ LOGGER.debug(MessageFormat.format("excluding {0} because of rule {1}", path, pattern.pattern()));
+ exclude = true;
+ break;
+ }
+ }
+ if (exclude) {
+ // skip to next file
+ continue;
+ }
+
File gitDir = FileKey.resolve(new File(searchFolder, file.getName()), FS.DETECTED);
if (gitDir != null) {
if (onlyBare && gitDir.getName().equals(".git")) {
continue;
}
- // determine repository name relative to base path
- String repository = FileUtils.getRelativePath(baseFile, file);
- list.add(repository);
+ if (gitDir.equals(file) || gitDir.getParentFile().equals(file)) {
+ // determine repository name relative to base path
+ String repository = FileUtils.getRelativePath(baseFile, file);
+ list.add(repository);
+ } else if (searchSubfolders && file.canRead()) {
+ // look for repositories in subfolders
+ list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders,
+ nextDepth, patterns));
+ }
} else if (searchSubfolders && file.canRead()) {
// look for repositories in subfolders
- list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders));
+ list.addAll(getRepositoryList(basePath, file, onlyBare, searchSubfolders,
+ nextDepth, patterns));
}
}
}
@@ -543,14 +588,15 @@
* @param tree
* if null, the RevTree from HEAD is assumed.
* @param blobPath
+ * @param charsets optional
* @return UTF-8 string content
*/
- public static String getStringContent(Repository repository, RevTree tree, String blobPath) {
+ public static String getStringContent(Repository repository, RevTree tree, String blobPath, String... charsets) {
byte[] content = getByteContent(repository, tree, blobPath);
if (content == null) {
return null;
}
- return new String(content, Charset.forName(Constants.CHARACTER_ENCODING));
+ return StringUtils.decodeString(content, charsets);
}
/**
@@ -589,14 +635,15 @@
*
* @param repository
* @param objectId
+ * @param charsets optional
* @return UTF-8 string content
*/
- public static String getStringContent(Repository repository, String objectId) {
+ public static String getStringContent(Repository repository, String objectId, String... charsets) {
byte[] content = getByteContent(repository, objectId);
if (content == null) {
return null;
}
- return new String(content, Charset.forName(Constants.CHARACTER_ENCODING));
+ return StringUtils.decodeString(content, charsets);
}
/**
@@ -1223,6 +1270,74 @@
}
/**
+ * Sets the local branch ref to point to the specified commit id.
+ *
+ * @param repository
+ * @param branch
+ * @param commitId
+ * @return true if successful
+ */
+ public static boolean setBranchRef(Repository repository, String branch, String commitId) {
+ String branchName = branch;
+ if (!branchName.startsWith(Constants.R_HEADS)) {
+ branchName = Constants.R_HEADS + branch;
+ }
+
+ try {
+ RefUpdate refUpdate = repository.updateRef(branchName, false);
+ refUpdate.setNewObjectId(ObjectId.fromString(commitId));
+ RefUpdate.Result result = refUpdate.forceUpdate();
+
+ switch (result) {
+ case NEW:
+ case FORCED:
+ case NO_CHANGE:
+ case FAST_FORWARD:
+ return true;
+ default:
+ LOGGER.error(MessageFormat.format("{0} {1} update to {2} returned result {3}",
+ repository.getDirectory().getAbsolutePath(), branchName, commitId, result));
+ }
+ } catch (Throwable t) {
+ error(t, repository, "{0} failed to set {1} to {2}", branchName, commitId);
+ }
+ return false;
+ }
+
+ /**
+ * Deletes the specified branch ref.
+ *
+ * @param repository
+ * @param branch
+ * @return true if successful
+ */
+ public static boolean deleteBranchRef(Repository repository, String branch) {
+ String branchName = branch;
+ if (!branchName.startsWith(Constants.R_HEADS)) {
+ branchName = Constants.R_HEADS + branch;
+ }
+
+ try {
+ RefUpdate refUpdate = repository.updateRef(branchName, false);
+ refUpdate.setForceUpdate(true);
+ RefUpdate.Result result = refUpdate.delete();
+ switch (result) {
+ case NEW:
+ case FORCED:
+ case NO_CHANGE:
+ case FAST_FORWARD:
+ return true;
+ default:
+ LOGGER.error(MessageFormat.format("{0} failed to delete to {1} returned result {2}",
+ repository.getDirectory().getAbsolutePath(), branchName, result));
+ }
+ } catch (Throwable t) {
+ error(t, repository, "{0} failed to delete {1}", branchName);
+ }
+ return false;
+ }
+
+ /**
* Get the full branch and tag ref names for any potential HEAD targets.
*
* @param repository
--
Gitblit v1.9.1