threads / bug / 53864

Git bug - Windows subst/net use, Windows drive letter prefix

Subject: Git bug - Windows subst/net use, Windows drive letter prefix

## tl;dr

3 messages between Jul 16, 2020 and Jul 20, 2020.

replies: 2people: 2as markdown or json

Paul D. Smith· Jul 16, 2020, 11:03 UTC · lore
I believe there is a subtle bug in Git that can mean that a "git add" fails, complaining that "fatal: <filename>: '<filename>' is outside repository at '//<server>/<share>/<directory> /'
It may be possible to reproduce this with simpler steps, but this is what I have that fails.
1. A Git repo on system <server> below directory <directory> that can be reached via the Windows share <share>
2. On a second system, perform "net use z: file://%3cserver%3e/%3cshare>"
3. Now you can "cd /d z:\<directory>" and run "git status" quite happily 
4. At this point I can also so this:
	a. "cd /d z:" then "git add <z:\some-changed-file>"
		i. Note the drive letter prefixing the full-filename
5. Now do a subst or a net use as follows:
	a. subst v: z:\directory
	b. net use w: file://%3cserver%3e/%3cshare%3e/%3cdirectory>
6. You can do both of these
	a. "cd /d v:" then "git status"
	b. "cd /d w:" then "git status"
7. However both of these FAIL:
	a. "cd /d v:" then "git add <v:\some-changed-file>"
	b. "cd /d w:" then "git add <w:\some-changed-file>"
		i. Note the drive letter prefixing the full-filename
8. Performing the above requests WITHOUT the drive letter prefixing the filename works!
I assume that this is supposed to work and there is some subtle error merging the repository root and the filename-with-drive-prefix.

Regards, Paul D.Smith.

Torsten Bögershausen· Jul 19, 2020, 06:31 UTC · re: Paul D. Smith · lore

Re: Git bug - Windows subst/net use, Windows drive letter prefix

On Thu, Jul 16, 2020 at 11:03:22AM +0000, Paul D. Smith wrote:
Show 27 quoted lines
> I believe there is a subtle bug in Git that can mean that a "git add" fails, complaining that "fatal: <filename>: '<filename>' is outside repository at '//<server>/<share>/<directory> /'
>
> It may be possible to reproduce this with simpler steps, but this is what I have that fails.
>
> 1. A Git repo on system <server> below directory <directory> that can be reached via the Windows share <share>
> 2. On a second system, perform "net use z: file://%3cserver%3e/%3cshare>"
> 3. Now you can "cd /d z:\<directory>" and run "git status" quite happily
> 4. At this point I can also so this:
> 	a. "cd /d z:" then "git add <z:\some-changed-file>"
> 		i. Note the drive letter prefixing the full-filename
> 5. Now do a subst or a net use as follows:
> 	a. subst v: z:\directory
> 	b. net use w: file://%3cserver%3e/%3cshare%3e/%3cdirectory>
> 6. You can do both of these
> 	a. "cd /d v:" then "git status"
> 	b. "cd /d w:" then "git status"
> 7. However both of these FAIL:
> 	a. "cd /d v:" then "git add <v:\some-changed-file>"
> 	b. "cd /d w:" then "git add <w:\some-changed-file>"
> 		i. Note the drive letter prefixing the full-filename
> 8. Performing the above requests WITHOUT the drive letter prefixing the filename works!
>
> I assume that this is supposed to work and there is some subtle error merging the repository root and the filename-with-drive-prefix.
>
> Regards,
> Paul D.Smith.
>

Thanks for reporting your issue. It's good to get well-written reports like this.

As a general note, this is specific to the "Git for Windows" project, and issues can be reported there: https://github.com/git-for-windows/git

More specific, I could reproduce the issue without using a network:

C: cd Users/tb mkdir 200719-git-test-subst cd 200719-git-test-subst git init echo FILE >FILE.txt

Now I can use git add C:\Users\tb\200719-git-test-subst\FILE.txt

That surborised me a little bit, since an absolute path name was given to Git. However, Git is able to figure out, that

C:\Users\tb\200719-git-test-subst\FILE.txt is the same as FILE.txt

as you can see running git ls-files

The file names (and path components) in Git are always tracked "relative". Relative to the root of the Git repo. And here Git translates "C:\Users\tb\200719-git-test-subst\FILE.txt" into "FILE.txt"

In that sense, drive letters are not trackesd at all, you can clone that repo to any drive letter, or even to a network share.

If I now use subst T: C:\Users\tb\200719-git-test-subst

I can use the same repo under T:\

file/path names are still relative, so if you change into T:\ and run git ls-files you will still see FILE.txt

Now mixing those 2 does not work. Git is unable to figure out the "T:\" is the same as "C:\Users\tb\200719-git-test-subst"

In general, different drive letters host different file systems, so Git assumes that they don't point to the same directory.

Adding this functionality may be possible, I don't know the Windows APIs good enough. But: That will cost sone time (in terms of development) and give a run-time penalty for Git itself for many Git invocations. It may even open up for security issues, since the "check if X: is the same as Y:" needs to be done in one step, and the the operation needs to be done in the next step, opening a small timing window, where bad things may happen.

This was my limited view on how things work, there may be details missed (or wrong).
Paul D. Smith· Jul 20, 2020, 07:37 UTC · re: Torsten Bögershausen · lore

RE: Git bug - Windows subst/net use, Windows drive letter prefix

-----Original Message-----
From: Torsten Bögershausen <tboegi@web.de> 
Sent: 19 July 2020 07:32
To: Paul D. Smith <Paul.D.Smith@metaswitch.com>
Cc: git@vger.kernel.org
Subject: Re: Git bug - Windows subst/net use, Windows drive letter prefix
NOTE: Message is from an external sender
On Thu, Jul 16, 2020 at 11:03:22AM +0000, Paul D. Smith wrote:
Show 27 quoted lines
> I believe there is a subtle bug in Git that can mean that a "git add" fails, complaining that "fatal: <filename>: '<filename>' is outside repository at '//<server>/<share>/<directory> /'
>
> It may be possible to reproduce this with simpler steps, but this is what I have that fails.
>
> 1. A Git repo on system <server> below directory <directory> that can 
> be reached via the Windows share <share> 2. On a second system, perform "net use z: file://%3cserver%3e/%3cshare>"
> 3. Now you can "cd /d z:\<directory>" and run "git status" quite 
> happily 4. At this point I can also so this:
>       a. "cd /d z:" then "git add <z:\some-changed-file>"
>               i. Note the drive letter prefixing the full-filename 5. 
> Now do a subst or a net use as follows:
>       a. subst v: z:\directory
>       b. net use w: file://%3cserver%3e/%3cshare%3e/%3cdirectory>
> 6. You can do both of these
>       a. "cd /d v:" then "git status"
>       b. "cd /d w:" then "git status"
> 7. However both of these FAIL:
>       a. "cd /d v:" then "git add <v:\some-changed-file>"
>       b. "cd /d w:" then "git add <w:\some-changed-file>"
>               i. Note the drive letter prefixing the full-filename 8. 
> Performing the above requests WITHOUT the drive letter prefixing the filename works!
>
> I assume that this is supposed to work and there is some subtle error merging the repository root and the filename-with-drive-prefix.
>
> Regards,
> Paul D.Smith.
>

Thanks for reporting your issue. It's good to get well-written reports like this.

As a general note, this is specific to the "Git for Windows" project, and issues can be reported there: https://nam01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgit-for-windows%2Fgit&amp;data=02%7C01%7CPaul.D.Smith%40metaswitch.com%7C62bef1d2ef71432c41da08d82bad70d9%7C9d9e56ebf6134ddbb27bbfcdf14b2cdb%7C1%7C1%7C637307371245564042&amp;sdata=qFq0Fqg5Vjx1w9rYk55fcwYcNvEP0Z5W0MXvFrMuuys%3D&amp;reserved=0

More specific, I could reproduce the issue without using a network:

C: cd Users/tb mkdir 200719-git-test-subst cd 200719-git-test-subst git init echo FILE >FILE.txt

Now I can use git add C:\Users\tb\200719-git-test-subst\FILE.txt

That surborised me a little bit, since an absolute path name was given to Git. However, Git is able to figure out, that

C:\Users\tb\200719-git-test-subst\FILE.txt is the same as FILE.txt

as you can see running git ls-files

The file names (and path components) in Git are always tracked "relative". Relative to the root of the Git repo. And here Git translates "C:\Users\tb\200719-git-test-subst\FILE.txt" into "FILE.txt"

In that sense, drive letters are not trackesd at all, you can clone that repo to any drive letter, or even to a network share.

If I now use subst T: C:\Users\tb\200719-git-test-subst

I can use the same repo under T:\
file/path names are still relative, so if you change into T:\ and run git ls-files you will still see FILE.txt

Now mixing those 2 does not work. Git is unable to figure out the "T:\" is the same as "C:\Users\tb\200719-git-test-subst"

In general, different drive letters host different file systems, so Git assumes that they don't point to the same directory.

Adding this functionality may be possible, I don't know the Windows APIs good enough. But: That will cost sone time (in terms of development) and give a run-time penalty for Git itself for many Git invocations. It may even open up for security issues, since the "check if X: is the same as Y:" needs to be done in one step, and the the operation needs to be done in the next step, opening a small timing window, where bad things may happen.

This was my limited view on how things work, there may be details missed (or wrong).

---------- Torsten,

Thanks for the response.  It's not an important bug for me now that I know what is going on; I was able to rewrite the code I inherited slightly to avoid problems.
If there is a sensible place to put it, it might be good to document this effect; I don't know if there is any way that it could be mentioned in the error text when commands fail as a "Are you doing this?" hint to users?

Regards, Paul D.Smith

← back to recent threads