git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 3/4] Automatically detect a bare git repository.

From
Shawn Pearce <spearce@spearce.org>
Date
Dec 31, 2006, 05:26 UTC
Message-ID
<20061231052606.GA5722@spearce.org>
In-Reply-To
<7vy7ook5xj.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
Show 6 quoted lines
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> 
> >  This is in response to Theodore Tso's email asking why 'git log'
> >  doesn't work in a bare repository.  Now it does.  :-)
> 
> Does it?
It did in my testing.  ;-)
 
Show 44 quoted lines
> > @@ -160,36 +178,17 @@ const char *setup_git_directory_gently(int *nongit_ok)
> >  	 * to do any discovery, but we still do repository
> >  	 * validation.
> >  	 */
> > -	if (getenv(GIT_DIR_ENVIRONMENT)) {
> > -		char path[PATH_MAX];
> > -		int len = strlen(getenv(GIT_DIR_ENVIRONMENT));
> > -		if (sizeof(path) - 40 < len)
> > +	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
> > +	if (gitdirenv) {
> > +		if (PATH_MAX - 40 < strlen(gitdirenv))
> >  			die("'$%s' too big", GIT_DIR_ENVIRONMENT);
> > -		memcpy(path, getenv(GIT_DIR_ENVIRONMENT), len);
> > -		
> > -		strcpy(path + len, "/refs");
> > -		if (access(path, X_OK))
> > -			goto bad_dir_environ;
> > -		strcpy(path + len, "/HEAD");
> > -		if (validate_symref(path))
> > -			goto bad_dir_environ;
> > -		if (getenv(DB_ENVIRONMENT)) {
> > -			if (access(getenv(DB_ENVIRONMENT), X_OK))
> > -				goto bad_dir_environ;
> > -		}
> > -		else {
> > -			strcpy(path + len, "/objects");
> > -			if (access(path, X_OK))
> > -				goto bad_dir_environ;
> > -		}
> > -		return NULL;
> > -	bad_dir_environ:
> > +		if (is_git_directory(gitdirenv))
> > +			return NULL;
> >  		if (nongit_ok) {
> >  			*nongit_ok = 1;
> >  			return NULL;
> >  		}
> 
> I do not think this is correct.
>
> What happens when GIT_DIR is set, and nongit_ok is passed?
> Earlier code returned NULL after setting *nongit_ok so that the
> caller knows the environment points at a directory that is not
> yet a git repository control area.
The new code is correct, or at least does what the old code did.

If GIT_DIR is set we call is_git_directory(); if that returns 1 then the checks passed. In this case the old code returned NULL and ignored nongit_ok. We do the same in the new code.

If GIT_DIR is set and we fail is_git_directory() then one of the
checks failed.  In this case the old code jumped to bad_dir_env.
In the new code we don't return NULL and fall through into the if
nongit_ok testing, or into the die("Not a git repository").
 
Show 27 quoted lines
> > @@ -197,11 +196,17 @@ const char *setup_git_directory_gently(int *nongit_ok)
> >  
> >  	offset = len = strlen(cwd);
> >  	for (;;) {
> > -		if (is_toplevel_directory())
> > +		if (is_git_directory(".git"))
> >  			break;
> >  		chdir("..");
> >  		do {
> >  			if (!offset) {
> > +				if (is_git_directory(cwd)) {
> > +					if (chdir(cwd))
> > +						die("Cannot come back to cwd");
> > +					setenv(GIT_DIR_ENVIRONMENT, cwd, 1);
> > +					return NULL;
> > +				}
> >  				if (nongit_ok) {
> >  					if (chdir(cwd))
> >  						die("Cannot come back to cwd");
> 
> I do not know what the new behaviour of this part of the code is
> trying to do.  This is supposed to see if "." is the toplevel
> (equivalently, ".git" is the git_dir, in your implementation),
> otherwise chdir("..") repeatedly until it finds one, and the
> normal return condition is for the working directory of the
> process to be at the toplevel.  So chdir(cwd) you introduced is
> obviously changing the behaviour.
No, its not.

We only bother to look to see if the original cwd (before we started chdir("..")'ing up) is a git directory if we did not find one during that chdir up loop. This means our current working directory is now "/" but we found a valid repository in cwd.

In this case we chdir back to the repository directory before returning back to the caller, as what's the point of being in "/" when running in a bare repository? Probably better to be in the repository directory itself.

One could argue that maybe we should run in "/", or in "/tmp" in this case as there is no working directory associated with this repository, but that argument is about the same as just saying we go back into the now discovered GIT_DIR.

-- 
Shawn.
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 17 in “Replace "GIT_DIR" with GIT_DIR_ENVIRONMENT.”
  1. 2/4 Replace "GIT_DIR" with GIT_DIR_ENVIRONMENT.Shawn O. Pearce, Dec 31, 2006
  2. 3/4 Automatically detect a bare git repository.Shawn O. Pearce, Dec 31, 2006
  3. Junio C HamanoDec 31, 2006
  4. Shawn PearceDec 31, 2006
  5. Junio C HamanoDec 31, 2006
  6. Theodore TsoDec 31, 2006
  7. Shawn O. PearceJan 1, 2007
  8. Martin WaitzDec 31, 2006
  9. Shawn O. PearceJan 1, 2007
  10. 4/4 Disallow working directory commands in a bare repository.Shawn O. Pearce, Dec 31, 2006
  11. Junio C HamanoDec 31, 2006
  12. Shawn O. PearceDec 31, 2006
  13. Junio C HamanoDec 31, 2006
  14. Theodore TsoDec 31, 2006
  15. Johannes SchindelinDec 31, 2006
  16. Junio C HamanoDec 31, 2006
  17. Johannes SchindelinJan 2, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.