From 69007029f122c3f77db044e879188cc12be3c2f6 Mon Sep 17 00:00:00 2001
From: Florian Zschocke <florian.zschocke@cycos.com>
Date: Mon, 26 Aug 2013 06:39:57 -0400
Subject: [PATCH] Add method JGitUtils.createRepository(folder, name, shared) to create a new repository as if it was created with the --shared command line switch of git.
---
src/main/java/com/gitblit/utils/JGitUtils.java | 142 +++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 131 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/gitblit/utils/JGitUtils.java b/src/main/java/com/gitblit/utils/JGitUtils.java
index 7242e33..345375a 100644
--- a/src/main/java/com/gitblit/utils/JGitUtils.java
+++ b/src/main/java/com/gitblit/utils/JGitUtils.java
@@ -58,6 +58,7 @@
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -88,6 +89,8 @@
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.RefModel;
import com.gitblit.models.SubmoduleModel;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
/**
* Collection of static methods for retrieving information from a repository.
@@ -267,6 +270,105 @@
}
}
+ /**
+ * Creates a bare, shared repository.
+ *
+ * @param repositoriesFolder
+ * @param name
+ * @param shared
+ * the setting for the --shared option of "git init".
+ * @return Repository
+ */
+ public static Repository createRepository(File repositoriesFolder, String name, String shared) {
+ try {
+ Repository repo = createRepository(repositoriesFolder, name);
+
+ GitConfigSharedRepository sharedRepository = new GitConfigSharedRepository(shared);
+ if (sharedRepository.isShared()) {
+ StoredConfig config = repo.getConfig();
+ config.setString("core", null, "sharedRepository", sharedRepository.getValue());
+ config.setBoolean("receive", null, "denyNonFastforwards", true);
+ config.save();
+
+ if (! System.getProperty("os.name").toLowerCase().startsWith("windows")) {
+ final CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class);
+
+ //libc.chmod("/path/to/file", 0755);
+ }
+ }
+
+ return repo;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ interface CLibrary extends Library {
+ public int chmod(String path, int mode);
+ }
+ private enum GitConfigSharedRepositoryValue {
+ UMASK("0", 0), FALSE("0", 0), OFF("0", 0), NO("0", 0),
+ GROUP("1", 0660), TRUE("1", 0660), ON("1", 0660), YES("1", 0660),
+ ALL("2", 0664), WORLD("2", 0664), EVERYBODY("2", 0664),
+ Oxxx(null, -1);
+
+ private String configValue;
+ private int permValue;
+ private GitConfigSharedRepositoryValue(String config, int perm) { configValue = config; permValue = perm; };
+
+ public String getConfigValue() { return configValue; };
+ public int getPerm() { return permValue; };
+
+ }
+ private static class GitConfigSharedRepository
+ {
+ private int intValue;
+ GitConfigSharedRepositoryValue enumValue;
+
+ GitConfigSharedRepository(String s)
+ {
+ if ( s == null || s.trim().isEmpty() ) {
+ enumValue = GitConfigSharedRepositoryValue.GROUP;
+ }
+ else {
+ try {
+ // Try one of the string values
+ enumValue = GitConfigSharedRepositoryValue.valueOf(s.trim().toUpperCase());
+ } catch (IllegalArgumentException iae) {
+ try {
+ // Try if this is an octal number
+ int i = Integer.parseInt(s, 8);
+ if ( (i & 0600) != 0600 ) {
+ String msg = String.format("Problem with core.sharedRepository filemode value (0%03o).\nThe owner of files must always have read and write permissions.", i);
+ throw new IllegalArgumentException(msg);
+ }
+ intValue = i & 0666;
+ enumValue = GitConfigSharedRepositoryValue.Oxxx;
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException("Bad configuration value for 'shared': '" + s + "'");
+ }
+ }
+ }
+ }
+
+ String getValue()
+ {
+ if ( enumValue == GitConfigSharedRepositoryValue.Oxxx ) return Integer.toOctalString(intValue);
+ return enumValue.getConfigValue();
+ }
+
+ int getPerm()
+ {
+ if ( enumValue == GitConfigSharedRepositoryValue.Oxxx ) return intValue;
+ return enumValue.getPerm();
+ }
+
+ boolean isShared()
+ {
+ return (enumValue.getPerm() > 0) || enumValue == GitConfigSharedRepositoryValue.Oxxx;
+ }
+ }
+
+
/**
* Returns a list of repository names in the specified folder.
*
@@ -297,6 +399,7 @@
list.addAll(getRepositoryList(repositoriesFolder.getAbsolutePath(), repositoriesFolder,
onlyBare, searchSubfolders, depth, patterns));
StringUtils.sortRepositorynames(list);
+ list.remove(".git"); // issue-256
return list;
}
@@ -438,39 +541,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());
}
/**
--
Gitblit v1.9.1