threads / patch / 8847

patchgit-init: set core.worktree if GIT_WORK_TREE is specified

Subject: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

## tl;dr

7 messages between Jul 3, 2007 and Jul 4, 2007. Diffs are folded; open one to read it.

replies: 6people: 5as markdown or json

Matthias Lederhofer· Jul 3, 2007, 22:49 UTC · lore

Now you can do the following to create a repository which has a separate working tree:

    /tmp/foo$ export GIT_DIR=/tmp/bar
    /tmp/foo$ git --work-tree . init
    Initialized empty Git repository in /tmp/bar/
    /tmp/foo$ git config core.worktree
    /tmp/foo
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
Without this I found it quite complicated to create a non bare
repository which is not in a .git directory.
Some stuff I was wondering about while writing this patch:
 * Should we have a function similar to err(3) which prints
   ": " and strerror(errno) after the supplied error message?
   This function could be used instead of die whenever errno contains
   some meaningful value.
 * Should git init create the whole path to the repository and not
   only the last component?  I.e. git --git-dir /tmp/a init suceeds
   but git --git-dir /tmp/a/b/c init fails (unless /tmp/a/b exists).
 * Should git init create the working tree if it does not exist?
 * Is this something which should have a test?  git init doesn't seem
   to have any tests yet beside basic tests if the created repository
   looks ok.
---
 builtin-init-db.c |   40 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 37 insertions(+), 3 deletions(-)
Show changes to builtin-init-db.c +37 −3
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 976f47b..ff5c13b 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -174,7 +174,36 @@ static void copy_templates(const char *git_dir, int len, const char *template_di
 	closedir(dir);
 }
 
-static int create_default_files(const char *git_dir, const char *template_path)
+/*
+ * Get the full path to the working tree specified in $GIT_WORK_TREE
+ * or NULL if no working tree is specified.
+ */
+static const char *get_work_tree(void)
+{
+	const char *git_work_tree;
+	char cwd[PATH_MAX];
+	static char worktree[PATH_MAX];
+
+	git_work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
+	if (!git_work_tree)
+		return NULL;
+	if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
+		die("Unable to read current working directory");
+	if (chdir(git_work_tree))
+		die("Cannot change directory to specified working tree '%s'",
+			git_work_tree);
+	if (git_work_tree[0] != '/') {
+		if (!getcwd(worktree, sizeof(worktree)) || worktree[0] != '/')
+			die("Unable to read current working directory");
+		git_work_tree = worktree;
+	}
+	if (chdir(cwd))
+		die("Cannot come back to cwd");
+	return git_work_tree;
+}
+
+static int create_default_files(const char *git_dir, const char *git_work_tree,
+	const char *template_path)
 {
 	unsigned len = strlen(git_dir);
 	static char path[PATH_MAX];
@@ -253,7 +282,7 @@ static int create_default_files(const char *git_dir, const char *template_path)
 	}
 	git_config_set("core.filemode", filemode ? "true" : "false");
 
-	if (is_bare_repository()) {
+	if (is_bare_repository() && !git_work_tree) {
 		git_config_set("core.bare", "true");
 	}
 	else {
@@ -261,6 +290,8 @@ static int create_default_files(const char *git_dir, const char *template_path)
 		/* allow template config file to override the default */
 		if (log_all_ref_updates == -1)
 		    git_config_set("core.logallrefupdates", "true");
+		if (git_work_tree)
+			git_config_set("core.worktree", git_work_tree);
 	}
 	return reinit;
 }
@@ -277,6 +308,7 @@ static const char init_db_usage[] =
 int cmd_init_db(int argc, const char **argv, const char *prefix)
 {
 	const char *git_dir;
+	const char *git_work_tree;
 	const char *sha1_dir;
 	const char *template_dir = NULL;
 	char *path;
@@ -294,6 +326,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			usage(init_db_usage);
 	}
 
+	git_work_tree = get_work_tree();
+
 	/*
 	 * Set up the default .git directory contents
 	 */
@@ -309,7 +343,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	 */
 	check_repository_format();
 
-	reinit = create_default_files(git_dir, template_dir);
+	reinit = create_default_files(git_dir, git_work_tree, template_dir);
 
 	/*
 	 * And set up the object store.
-- 
1.5.2.2.646.g71e55-dirty
Matthias Lederhofer· Jul 4, 2007, 09:29 UTC · re: Matthias Lederhofer · lore

Re: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

> +	if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
> +		die("Unable to read current working directory");

Dscho just pointed out that this causes problems on windows. The same is also in setup_git_directory_gently and was there before I touched it, introduced by Linus in d288a700. What was the original reason to do this? Are there implementations of getcwd which return a relative path?

Additionally there are other places which need to check if some user supplied path is absolute. Should we have a macro/function for that which depends on the os and checks for path[0] = '/' on unix and perhaps path[1] = ':' on windows?

Johannes Sixt· Jul 4, 2007, 10:41 UTC · re: Matthias Lederhofer · lore

Re: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

Matthias Lederhofer wrote:
Show 14 quoted lines
> 
> > +     if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
> > +             die("Unable to read current working directory");
> 
> Dscho just pointed out that this causes problems on windows.  The same
> is also in setup_git_directory_gently and was there before I touched
> it, introduced by Linus in d288a700.  What was the original reason to
> do this?  Are there implementations of getcwd which return a relative
> path?
> 
> Additionally there are other places which need to check if some user
> supplied path is absolute.  Should we have a macro/function for that
> which depends on the os and checks for path[0] = '/' on unix and
> perhaps path[1] = ':' on windows?

I've modified some places (that check for an absolute path) in the MinGW port to read (path[0] == '/' || path[1] == ':'). I don't think that it's necessary that you cater for this case in your code - I'll take care of it in the MinGW port. Of course, a hint that there is another place to watch out for, or even better a test case in t/, is most appreciated.

I still hope to find some time to rework the MinGW port. Then such details will be hidden behind a is_path_absolute() function. Or maybe getcwd_or_die() ;)

-- Hannes
Johannes Schindelin· Jul 4, 2007, 11:57 UTC · re: Johannes Sixt · lore

Re: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

Hi,
On Wed, 4 Jul 2007, Johannes Sixt wrote:
Show 25 quoted lines
> Matthias Lederhofer wrote:
> > 
> > > +     if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
> > > +             die("Unable to read current working directory");
> > 
> > Dscho just pointed out that this causes problems on windows.  The same
> > is also in setup_git_directory_gently and was there before I touched
> > it, introduced by Linus in d288a700.  What was the original reason to
> > do this?  Are there implementations of getcwd which return a relative
> > path?
> > 
> > Additionally there are other places which need to check if some user
> > supplied path is absolute.  Should we have a macro/function for that
> > which depends on the os and checks for path[0] = '/' on unix and
> > perhaps path[1] = ':' on windows?
> 
> I've modified some places (that check for an absolute path) in the MinGW
> port to read (path[0] == '/' || path[1] == ':'). I don't think that it's
> necessary that you cater for this case in your code - I'll take care of
> it in the MinGW port. Of course, a hint that there is another place to
> watch out for, or even better a test case in t/, is most appreciated.
> 
> I still hope to find some time to rework the MinGW port. Then such
> details will be hidden behind a is_path_absolute() function. Or maybe
> getcwd_or_die() ;)
Yes, but why not start early? is_path_absolute() makes perfect sense.

However, I was asking (out of lack of knowledge): is there any way getcwd() does not return an absolute path?

Ciao, Dscho

Linus Torvalds· Jul 4, 2007, 16:23 UTC · re: Matthias Lederhofer · lore

Re: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

On Wed, 4 Jul 2007, Matthias Lederhofer wrote:
Show 8 quoted lines
> > +	if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
> > +		die("Unable to read current working directory");
> 
> Dscho just pointed out that this causes problems on windows.  The same
> is also in setup_git_directory_gently and was there before I touched
> it, introduced by Linus in d288a700.  What was the original reason to
> do this?  Are there implementations of getcwd which return a relative
> path?
Just remove the check for cwd[0] being '/'.

It's just me being too kernel-oriented - inside the kernel, a d_path() return value pathname can be either a real path, or something like "pipe:[8003]", and the difference is the '/' at the beginning.

In user space, and for getcwd(), the check doesn't make sense. So please just remove it, and sorry for my idiotic "I've worked with the kernel for too damn long" programming mistakes.

		Linus
Junio C Hamano· Jul 4, 2007, 17:07 UTC · re: Linus Torvalds · lore

Re: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

Linus Torvalds <torvalds@linux-foundation.org> writes:
Show 12 quoted lines
> On Wed, 4 Jul 2007, Matthias Lederhofer wrote:
>
>> > +	if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
>> > +		die("Unable to read current working directory");
>> 
>> Dscho just pointed out that this causes problems on windows.  The same
>> is also in setup_git_directory_gently and was there before I touched
>> it, introduced by Linus in d288a700.  What was the original reason to
>> do this?  Are there implementations of getcwd which return a relative
>> path?
>
> Just remove the check for cwd[0] being '/'.
Ok, will do this.
-- >8 --
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Wed, 4 Jul 2007 09:23:17 -0700 (PDT)
Subject: Do not check if getcwd() result begins with a slash

It's just me being too kernel-oriented - inside the kernel, a d_path() return value pathname can be either a real path, or something like "pipe:[8003]", and the difference is the '/' at the beginning.

In user space, and for getcwd(), the check doesn't make sense. So please just remove it, and sorry for my idiotic "I've worked with the kernel for too damn long" programming mistakes.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Forged-signature-by: Junio C Hamano <gitster@pobox.com>
---
 setup.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
Show changes to setup.c +4 −4
diff --git a/setup.c b/setup.c
index 01f74d4..bb26f3a 100644
--- a/setup.c
+++ b/setup.c
@@ -211,7 +211,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 	if (!gitdirenv) {
 		int len, offset;
 
-		if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
+		if (!getcwd(cwd, sizeof(cwd)-1))
 			die("Unable to read current working directory");
 
 		offset = len = strlen(cwd);
@@ -271,7 +271,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 		die("Not a git repository: '%s'", gitdirenv);
 	}
 
-	if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
+	if (!getcwd(cwd, sizeof(cwd)-1))
 		die("Unable to read current working directory");
 	if (chdir(gitdirenv)) {
 		if (nongit_ok) {
@@ -281,7 +281,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 		die("Cannot change directory to $%s '%s'",
 			GIT_DIR_ENVIRONMENT, gitdirenv);
 	}
-	if (!getcwd(gitdir, sizeof(gitdir)-1) || gitdir[0] != '/')
+	if (!getcwd(gitdir, sizeof(gitdir)-1))
 		die("Unable to read current working directory");
 	if (chdir(cwd))
 		die("Cannot come back to cwd");
@@ -340,7 +340,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 			die("Cannot change directory to working tree '%s'",
 				gitworktree);
 	}
-	if (!getcwd(worktree, sizeof(worktree)-1) || worktree[0] != '/')
+	if (!getcwd(worktree, sizeof(worktree)-1))
 		die("Unable to read current working directory");
 	strcat(worktree, "/");
 	inside_work_tree = !prefixcmp(cwd, worktree);
Linus Torvalds· Jul 4, 2007, 17:31 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-init: set core.worktree if GIT_WORK_TREE is specified

On Wed, 4 Jul 2007, Junio C Hamano wrote:
> 
> Ok, will do this.
Ack.
> From: Linus Torvalds <torvalds@linux-foundation.org>

I don't think you need to credit me, or forge my sign-off for stuff like this where I didn't actually send out a patch.

I'd suggest instead just committing it as yours, but maybe with the explanation saying something like "Linus explains: <explanation>" instead.

But hey, you can do it your way too, your choice.
		Linus

← back to recent threads