[PATCH] Implement selectable group ownership in git-init

Subsystems: the rest

DORMANTno replies

2 messages, 1 author, 2016-06-15 · open the first message on its own page

[PATCH] Implement selectable group ownership in git-init

From: Francesco Pretto <hidden>
Date: 2016-06-15 22:43:46

Rationale: continuing the *nix tradition, git is very tied to fs permissions. Groups ownership of git repositories can in fact perfectly resemble projects work groups.
The problem came when sysadmins or git admins create shared repositories: it does not have sense to create repositories with :root group ownership, if you have to put users in the root group to let them use it (!). But the same stands for the administrative git:git user (if you have one): having all the commit users in the git group means that it's impossible to selectively give (or prevent) access to users to different projects. For this reason, git-init should give the possibility to create shared repositories of a selectable group. Moreover, it should warn the user if no specific group is provided, just to warn the user in the case of wrong usage pattern (like :root or :git repositories). The following patch implements this possibility (and the warning), please review it.

---
 builtin-init-db.c |   26 ++++++++++++++++++++++++--
 cache.h           |    2 ++
 environment.c     |    2 ++
 path.c            |    3 +++
 4 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 763fa55..c8bed1e 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -321,7 +321,7 @@ static void guess_repository_type(const char *git_dir)
 }
 
 static const char init_db_usage[] =
-"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
+"git-init [-q | --quiet] [--template=<template-directory>] [--shared] [--group=<project-group>]";
 
 /*
  * If you want to, you can share the DB area with any number of branches.
@@ -346,6 +346,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			shared_repository = PERM_GROUP;
 		else if (!prefixcmp(arg, "--shared="))
 			shared_repository = git_config_perm("arg", arg+9);
+		else if (!prefixcmp(arg, "--group=")) {
+			owner_group = arg+8;
+			grouped_repository = 1;
+		}
 		else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet"))
 		        quiet = 1;
 		else
@@ -376,6 +380,20 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	}
 
 	/*
+	 * Complain if the repository is shared and no owner group have
+	 * been selected. 
+	 */
+	if (shared_repository && !grouped_repository)
+		printf("WARNING: You haven't selected any owner group!\n");
+	
+	/*
+	 * Catch the error early if the group provided doesn't exist
+	 */
+	if (getgrnam(owner_group) == NULL)
+		die("The group '%s' doesn't esist",
+		    owner_group);
+
+	/*
 	 * Set up the default .git directory contents
 	 */
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
@@ -417,11 +435,15 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		git_config_set("receive.denyNonFastforwards", "true");
 	}
 
-	if (!quiet)
+	if (!quiet) {
 		printf("%s%s Git repository in %s/\n",
 		       reinit ? "Reinitialized existing" : "Initialized empty",
 		       shared_repository ? " shared" : "",
 		       git_dir);
+		if (shared_repository)
+			printf("Put the commit users in the '%s' group\n",
+		       	       grouped_repository ? owner_group : getgrgid(getgid())->gr_name);
+	}
 
 	return 0;
 }
diff --git a/cache.h b/cache.h
index bfffa05..282b0f6 100644
--- a/cache.h
+++ b/cache.h
@@ -306,6 +306,8 @@ extern int prefer_symlink_refs;
 extern int log_all_ref_updates;
 extern int warn_ambiguous_refs;
 extern int shared_repository;
+extern int grouped_repository;
+extern const char *owner_group;
 extern const char *apply_default_whitespace;
 extern int zlib_compression_level;
 extern int core_compression_level;
diff --git a/environment.c b/environment.c
index b5a6c69..a518619 100644
--- a/environment.c
+++ b/environment.c
@@ -23,6 +23,8 @@ int repository_format_version;
 const char *git_commit_encoding;
 const char *git_log_output_encoding;
 int shared_repository = PERM_UMASK;
+int grouped_repository = 0;
+const char *owner_group = NULL;
 const char *apply_default_whitespace;
 int zlib_compression_level = Z_BEST_SPEED;
 int core_compression_level;
diff --git a/path.c b/path.c
index 4260952..1ec1379 100644
--- a/path.c
+++ b/path.c
@@ -286,6 +286,9 @@ int adjust_shared_perm(const char *path)
 		mode |= S_ISGID;
 	if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
 		return -2;
+	if (grouped_repository)
+		if (chown(path, getuid(), getgrnam(owner_group)->gr_gid) < 0 )
+			return -3;
 	return 0;
 }
 

Re: [PATCH] Implement selectable group ownership in git-init

From: Francesco Pretto <hidden>
Date: 2016-06-15 22:43:46

2007/11/3, Francesco Pretto [off-list ref]:
Rationale ...
Just to point, I wrote this patch for usability purpose and because i
think git still need a strong imprinting about its correct usage
pattern (i've read around that people using it with shared
repositories are already having problems with file permissions,
wrongly thinking it's inflexible for their needs). If you stand with
my reasoning, please help me to integrate this patch :-), I have other
ideas following this. NB: i'm not a C developer (that was my first
patch in pure C), have mercy...

The function adjust_shared_perm is used in other places: is there
other git commands that maybe needs to create files/dirs of a specific
group (not being in a g+sx dir)? Hopefully not, but i don't know git
source much. These are the occurrences (with the exclusion of
builtin-init-db.c):

refs.c: adjust_shared_perm(log_file);
refs.c: if (adjust_shared_perm(git_HEAD)) {
..
builtin-pack-objects.c: return adjust_shared_perm(path);
...
builtin-rerere.c:           (mkdir(rr_cache, 0777) ||
adjust_shared_perm(rr_cache)))
...
lockfile.c:             if (adjust_shared_perm(lk->filename))
...
sha1_file.c:            else if (adjust_shared_perm(path)) {
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help