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 |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/gitblit/utils/JGitUtils.java b/src/main/java/com/gitblit/utils/JGitUtils.java
index 8676d74..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.
 	 * 

--
Gitblit v1.9.1