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

Re: Improve handling of "." and ".." in git-diff-*

From
Alex Riesen <raa.lkml@gmail.com>
Date
Aug 23, 2005, 19:49 UTC
Message-ID
<81b0412b050823124938d735bf@mail.gmail.com>
In-Reply-To
<Pine.LNX.4.58.0508162037080.3553@g5.osdl.org>
On 8/17/05, Linus Torvalds <torvalds@osdl.org> wrote:
> NOTE! This does _not_ handle ".." or "." in the _middle_ of a pathspec. If
> you have people who do
BTW, could this (below) be useful for something?

#include <string.h> #include <stdio.h> #include <stdlib.h>

// an analog of "cd path" from a directory "cwd".
char* pathexpand(const char* cwd, const char* path)
{
    static const char SEP[] = "/";
    if ( !*path ) // empty path -> "." (don't move)
	path = ".";
    if ( !*cwd || *SEP == *path ) // no cwd, or path begins with "/"
	cwd = SEP;
    int len = strlen(cwd);
    char* out = (char*)malloc(len + 1 + strlen(path) + 1);
    char* p = strcpy(out, cwd) + len;
    if ( *SEP != p[-1] )
	*p++ = *SEP;
    for ( ; *path; ++path )
    {
	char * pl = p;
	while ( *path && *SEP != *path )
	    *p++ = *path++;
	*p = '\0';
	if ( p == pl ) /* ..."//"... */
	    ; // just ignore
	/* ..."/./"...  */
	else if ( p - pl == 1 && '.' == *pl )
	    --p; // just ignore
	/* ..."/../"...  */
	else if ( p - pl == 2 && '.' == pl[0] && '.' == pl[1] )
	{
	    // drop last element of the resulting path
	    if ( --pl > out )
		for ( --pl; pl > out && *SEP != *pl; --pl );
	    p = ++pl;
	}
	/* ..."/path/"...  */
	else if ( *path )
	    *p++ = *path; // just add the separator
	if ( !*path )
	    break;
    }
    if ( p > out+1 && *SEP == p[-1] )
	--p;
    *p = '\0';
    return out;
}
#ifdef CHECK_PATHEXPAND
static void check(const char * cwd, const char * path, const char * good)
{
    static int n = 0;
    printf("%-2d: %s$ cd %s", ++n, cwd, path);
    char* t = pathexpand(cwd, path);
    if ( strcmp(t, good) )
	printf(" failed(%s)\n", t);
    else
	printf(" \t\t%s\n", t);
    free(t);
}
int main(int argc, char** argv)
{
    /* 1 */ check("/onelevel", "aa", "/onelevel/aa");
    /* 2 */ check("/", "..", "/");
    /* 3 */ check("/", "../..", "/");
    /* 4 */ check("/one", "aa/../bb", "/one/bb");
    /* 5 */ check("/one/two", "aa//bb", "/one/two/aa/bb");
    /* 6 */ check("", "/aa//bb", "/aa/bb");
    /* 7 */ check("/one/two", "", "/one/two");
    /* 8 */ check("/one/two", "aa/..bb/x/../cc/", "/one/two/aa/..bb/cc");
    /* 9 */ check("/one/two", "aa/x/././cc////", "/one/two/aa/x/cc");
    /* 10 */ check("/one/two", "../../../../aa", "/aa");
    return 0;
}
#endif
Previous: Linus TorvaldsNext: Alex Riesen
Message 3 of 4 in “Improve handling of "." and ".." in git-diff-*”
  1. Linus TorvaldsAug 17, 2005
  2. Linus TorvaldsAug 17, 2005
  3. Alex RiesenAug 23, 2005
  4. Alex RiesenAug 23, 2005

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.