From: Linus Torvalds Date: Sat, 26 Nov 2005 04:05:46 GMT Subject: Re: [PATCH] Rename git-config-set to git-repo-config Message-ID: In-Reply-To: <7vy83cdu7r.fsf@assigned-by-dhcp.cox.net> On Fri, 25 Nov 2005, Junio C Hamano wrote: > > Johannes Schindelin writes: > > >> - Natively, they work only from the project toplevel. Period. > > > > How about changing *that*? > > I once advocated for an environment to name the top of working > tree directory --- it might make sense to resurrect that one. Please don't. We should just make the scripts do it automatically instead. "git-rev-parse" already has support for all of this, and you can do GIT_DIR=$(git-rev-parse --git-dir) GIT_PREFIX=$(git-rev-parse --show-prefix) where the first one shows the GIT_DIR, and the second one shows where in a git directory we are (empty if we're at the root). And most of the git commands written in C (where it makes sense) can already handle being inside a subdirectory. So can a number of the shell-scripts (for example, doing a "git log" inside a subdirectory already does the log for just that subdirectory). In fact, I'd prefer if _every_ command just did the right thing inside a subdirectory. I sent out this patch a week or two ago - it still applies, and it still mostly does the right thing. It makes at least "gitk" work right inside a subdirectory, and might make things like "git commit" and friends do the same. More testing still needed, but I think this is going in the right direction. Comments? I got none the first time around. Linus ---- NOTE! This has some seriously far-reaching implications. One of them is that a few programs will automagically start working inside some random directories. And probably others won't. Instead of saying "Not a git archive", they might run and do strange things. The patch is definitely a big step in the right direction: it makes the shell scripts that include "git-sh-setup" act a lot more like the programs that automatically find the git directory. But everybody that includes git-sh-setup should be verified. This fixes gitk to also work the same way, btw. --- diff --git a/git-sh-setup.sh b/git-sh-setup.sh index dbb9884..044b0b4 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -3,7 +3,7 @@ # Set up GIT_DIR and GIT_OBJECT_DIRECTORY # and return true if everything looks ok # -: ${GIT_DIR=.git} +: ${GIT_DIR=$(git-rev-parse --git-dir)} || exit : ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"} # Having this variable in your environment would break scripts because diff --git a/gitk b/gitk index a9d37d9..a934255 100755 --- a/gitk +++ b/gitk @@ -12,7 +12,7 @@ proc gitdir {} { if {[info exists env(GIT_DIR)]} { return $env(GIT_DIR) } else { - return ".git" + return [exec git-rev-parse --git-dir] } } diff --git a/setup.c b/setup.c index c487d7e..96085dd 100644 --- a/setup.c +++ b/setup.c @@ -53,11 +53,10 @@ const char **get_pathspec(const char *pr const char **p; int prefixlen; - if (!prefix && !entry) - return NULL; - if (!entry) { static const char *spec[2]; + if (!prefix || !*prefix) + return NULL; spec[0] = prefix; spec[1] = NULL; return spec; @@ -120,9 +119,19 @@ const char *setup_git_directory(void) if (offset == len) return NULL; - /* Make "offset" point to past the '/', and add a '/' at the end */ offset++; + + /* + * If we're inside the ".git" directory, we have an empty prefix + */ + if (!strncmp(cwd + offset, ".git", 4)) { + switch (cwd[offset+4]) { + case '\0': case '/': + return ""; + } + } + cwd[len++] = '/'; cwd[len] = 0; return cwd + offset;