[PATCH/RFC] init, clone: support --real-git-dir for .git file

Subsystems: the rest

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

[PATCH/RFC] init, clone: support --real-git-dir for .git file

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:50:42

Instead of creating the repository at $GIT_DIR, --real-git-dir will
tell git to put the repository there, then make $GIT_DIR a .git file
that points to --real-git-dir.

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 This makes '.git symbolic link' (what's its official name?) more
 convenient to use. Previously whenever I need to create a .git link,
 I need to open docs to see its format. Now all I need to do is

  git init --real-git-dir=/where/real/git/is
  git clone --real-git-dir=/where/real/git/is something

 I intend to make 'git init --real-git-dir' move current repo to
 somewhere else if called on existing repo.

 Long term I'd like to see a init/clone hook, where I can tell git
 "when I ask you to create a repo/worktree at foo, put the real repo
 at ~/git/foo"

 I could use a better option name too, any suggestions?

 builtin/clone.c   |    7 ++++++-
 builtin/init-db.c |   38 +++++++++++++++++++++++++++++++++++++-
 cache.h           |    1 +
 3 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 60d9a64..74e487a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -42,6 +42,7 @@ static int option_local, option_no_hardlinks, option_shared, option_recursive;
 static char *option_template, *option_reference, *option_depth;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
+static const char *real_git_dir;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
 static int option_progress;
@@ -80,6 +81,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_STRING(0, "real-git-dir", &real_git_dir, "git-dir",
+		   "directory where real repository is cloned to"),
 
 	OPT_END()
 };
@@ -466,7 +469,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 	if (safe_create_leading_directories_const(git_dir) < 0)
 		die("could not create leading directories of '%s'", git_dir);
-	set_git_dir(make_absolute_path(git_dir));
+	set_git_dir_init(git_dir, real_git_dir);
+	if (real_git_dir)
+		git_dir = real_git_dir;
 
 	if (0 <= option_verbosity)
 		printf("Cloning into %s%s...\n",
diff --git a/builtin/init-db.c b/builtin/init-db.c
index fbeb380..7a0fb50 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -21,6 +21,7 @@
 static int init_is_bare_repository = 0;
 static int init_shared_repository = -1;
 static const char *init_db_template_dir;
+static const char *git_link;
 
 static void safe_create_dir(const char *dir, int share)
 {
@@ -311,10 +312,42 @@ static void create_object_directory(void)
 	free(path);
 }
 
+int set_git_dir_init(const char *git_dir, const char *real_git_dir)
+{
+	if (real_git_dir) {
+		struct stat st;
+
+		if (!stat(git_dir, &st))
+			die("%s already exists", git_dir);
+		git_link = git_dir;
+	}
+	else {
+		real_git_dir = git_dir;
+		git_link = NULL;
+	}
+	set_git_dir(make_absolute_path(real_git_dir));
+	return 0;
+}
+
 int init_db(const char *template_dir, unsigned int flags)
 {
 	int reinit;
 
+	if (git_link) {
+		struct stat st;
+		FILE *fp;
+
+		/* TODO: allow --real-git-dir to move repo elsewhere */
+		if (!lstat(git_link, &st))
+			die("%s already exists", git_link);
+
+		fp = fopen(git_link, "w");
+		if (!fp)
+			die("Could not create git link %s", git_link);
+		fprintf(fp, "gitdir: %s\n", get_git_dir());
+		fclose(fp);
+	}
+
 	safe_create_dir(get_git_dir(), 0);
 
 	init_is_bare_repository = is_bare_repository();
@@ -414,6 +447,7 @@ static const char *const init_db_usage[] = {
 int cmd_init_db(int argc, const char **argv, const char *prefix)
 {
 	const char *git_dir;
+	const char *real_git_dir = NULL;
 	const char *work_tree;
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
@@ -427,6 +461,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			"specify that the git repository is to be shared amongst several users",
 			PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
 		OPT_BIT('q', "quiet", &flags, "be quiet", INIT_DB_QUIET),
+		OPT_STRING(0, "real-git-dir", &real_git_dir, "git-dir",
+			   "directory where real .git is initialized"),
 		OPT_END()
 	};
 
@@ -522,7 +558,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			set_git_work_tree(make_absolute_path(work_tree));
 	}
 
-	set_git_dir(make_absolute_path(git_dir));
+	set_git_dir_init(git_dir, real_git_dir);
 
 	return init_db(template_dir, flags);
 }
diff --git a/cache.h b/cache.h
index 08a9022..0b006b8 100644
--- a/cache.h
+++ b/cache.h
@@ -436,6 +436,7 @@ extern void verify_non_filename(const char *prefix, const char *name);
 
 #define INIT_DB_QUIET 0x0001
 
+extern int set_git_dir_init(const char *git_dir, const char *real_git_dir);
 extern int init_db(const char *template_dir, unsigned int flags);
 
 #define alloc_nr(x) (((x)+16)*3/2)
-- 
1.7.4.74.g639db

Re: [PATCH/RFC] init, clone: support --real-git-dir for .git file

From: Piotr Krukowiecki <hidden>
Date: 2016-06-15 22:50:42

W dniu 03.03.2011 13:43, Nguyễn Thái Ngọc Duy pisze:
Instead of creating the repository at $GIT_DIR, --real-git-dir will
tell git to put the repository there, then make $GIT_DIR a .git file
that points to --real-git-dir.

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 This makes '.git symbolic link' (what's its official name?) more
 convenient to use. Previously whenever I need to create a .git link,
 I need to open docs to see its format. Now all I need to do is
Took me a while to find documentation for .git file format. Probably my
fault, missed the gitrepository-layout link.

Anyway, tried following:
   $ echo path > .git
   $ git info
   fatal: Invalid gitfile format: .git

Maybe one solution is to improve the message - patch attached:
   $ git info
   fatal: Invalid gitfile format: .git
   Use gitdir: <PATH>

 
  git init --real-git-dir=/where/real/git/is
  git clone --real-git-dir=/where/real/git/is something

 I intend to make 'git init --real-git-dir' move current repo to
 somewhere else if called on existing repo.

 Long term I'd like to see a init/clone hook, where I can tell git
 "when I ask you to create a repo/worktree at foo, put the real repo
 at ~/git/foo"
Is this needed? As I understand
    git init --real-git-dir=/where/real/git/is

should do the same as
    git --git-dir=/where/real/git/is && \
    echo "gitdir: /where/real/git/is" > ${GIT_DIR:-.git} 

The other actions seems to be similarly simple.

 I could use a better option name too, any suggestions?
I don't understand why is this needed. It's a bit complicated at first as well.
Adds extra layer to already existing .gitdir/.gitfile/GIT_DIR/--git-dir


---8<---
From e83caf00dc007b9a2e515bb718f0d9ddb080891e Mon Sep 17 00:00:00 2001
From: Piotr Krukowiecki <redacted>
Date: Thu, 3 Mar 2011 21:51:34 +0100
Subject: [PATCH] Improve error message when gitfile has wrong format

Add information what format of .git file is expected.

Signed-off-by: Piotr Krukowiecki <redacted>
---
 setup.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/setup.c b/setup.c
index 021d013..d2d9d0b 100644
--- a/setup.c
+++ b/setup.c
@@ -291,7 +291,7 @@ const char *read_gitfile_gently(const char *path)
 		die("Error reading %s", path);
 	buf[len] = '\0';
 	if (prefixcmp(buf, "gitdir: "))
-		die("Invalid gitfile format: %s", path);
+		die("Invalid gitfile format: %s\nUse gitdir: <PATH>", path);
 	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
 		len--;
 	if (len < 9)
-- 
1.7.1


-- 
Piotr Krukowiecki

Re: [PATCH/RFC] init, clone: support --real-git-dir for .git file

From: Nguyen Thai Ngoc Duy <hidden>
Date: 2016-06-15 22:50:42

2011/3/4 Piotr Krukowiecki [off-list ref]:
quoted
 This makes '.git symbolic link' (what's its official name?) more
 convenient to use. Previously whenever I need to create a .git link,
 I need to open docs to see its format. Now all I need to do is
Took me a while to find documentation for .git file format. Probably my
fault, missed the gitrepository-layout link.
Exactly why I wrote this patch. I do remember there is a prefix before
the path, but what is it? gitdir: or git-dir: or dir:? No I don't want
to look at the document every time I need to create a link. Trial and
error is not preferred either. Also manual manipulation on repos
should be avoided if possible.
-- 
Duy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help