Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Path doesn't work with %20 for space in filename in Git console

Tags:

git

My filename contains a space, so when I did the following:

git add first%20file.txt

the command above returned invalid path to me in my console

like image 491
Ricki Vandenbroek Avatar asked Nov 02 '13 13:11

Ricki Vandenbroek


People also ask

How do you indicate a space in a filename?

There are two main ways to handle such files or directories; one uses escape characters, i.e., backslash (\<space>), and the second is using apostrophes or quotation marks. Using backslash can be confusing; it's easy and better to use quotation marks or apostrophes.

How do I add a file to a Git space?

Surround the folder or file with a space in it with quotes! On Mac and Linux, you can add single quotes, but on Windows you'll have to use double quotes. …and everything worked as expected! This works for all the git commands: so add and diff , for instance, are included.

How do I fix the filename is too long in git?

You can solve this problem by using another Git client on Windows or set core. longpaths to true as explained in other answers. The limitation to 260 chars in a path is not specific to MSYS, it's a general Windows API imitation.


3 Answers

How about escaping space:

git add first\ file.txt
like image 104
wwn Avatar answered Oct 20 '22 09:10

wwn


As mentioned by sschuberth in comments - You only use %20 to escape spaces in URLs, not in file names on the command line.

You have two options to add these files

1) Escape spaces in file name

git add first\ file.txt
git add first\ file\ name.txt

2) Add the filename within quotes

git add "first file.txt"
git add "first file name.txt"

FWIW, you can also use tab completion in case you have only one file with name starting with string first

like image 24
Anshul Goyal Avatar answered Oct 20 '22 09:10

Anshul Goyal


Git 2.18 should improve completion of files with spaces in their filename.
(And Git 2.21, Q1 2019, should too, see the second part of this answer)

See commit f12785a (16 Apr 2018) by SZEDER Gábor (szeder).

completion: improve handling quoted paths on the command line

Our git-aware path completion doesn't work when it has to complete a word already containing quoted and/or backslash-escaped characters on the command line.
The root cause of the issue is that completion functions see all words on the command line verbatim, i.e. including all backslash, single and double quote characters that the shell would eventually remove when executing the finished command.
These quoting/escaping characters cause different issues depending on which path component of the word to be completed contains them:

  • The quoting/escaping is in the prefix path component(s).
    Let's suppose we have a directory called 'New Dir', containing two untracked files 'file.c' and 'file.o', and we have a gitignore rule ignoring object files.
    In this case all of these:

    git add New\ Dir/<TAB>
    git add "New Dir/<TAB>
    git add 'New Dir/<TAB>
    

should uniquely complete 'file.c' right away, but Bash offers both 'file.c' and 'file.o' instead.
The reason for this behavior is that our completion script uses the prefix directory name like 'git -C "New\ Dir/" ls-files ...", i.e. with the backslash inside double quotes.
Git then tries to enter a directory called 'New\ Dir', which (most likely) fails because such a directory doesn't exists.
As a result our completion script doesn't list any files, leaves the COMPREPLY array empty, which in turn causes Bash to fall back to its simple filename completion and lists all files in that directory, i.e. both 'file.c' and 'file.o'.

  • The quoting/escaping is in the path component to be completed.
    Let's suppose we have two untracked files 'New File.c' and 'New File.o', and we have a gitignore rule ignoring object files.
    In this case all of these:

    git add New\ Fi<TAB>
    git add "New Fi<TAB>
    git add 'New Fi<TAB>
    

should uniquely complete 'New File.c' right away, but Bash offers both 'New File.c' and 'New File.o' instead.
The reason for this behavior is that our completion script uses this 'New\ Fi' or '"New Fi' etc. word to filter matching paths, and of course none of the potential filenames will match because of the included backslash or double quote.
The end result is the same as above:
the completion script doesn't list any files, Bash falls back to its filename completion, which then lists the matching object file as well.

Add the new helper function __git_dequote(), which removes the quoting and escaping from the word it gets as argument.
To minimize the overhead of calling this function, store its result in the variable $dequoted_word, supposed to be declared local in the caller; simply printing the result would require a command substitution imposing the overhead of fork()ing a subshell.
Use this function in __git_complete_index_file() to dequote the current word, i.e. the path, to be completed, to avoid the above described quoting-related issues, thereby fixing two of the failing quoted path completion tests.


Git 2.21 (Q1 2019) will improve zsh "git cmd path<TAB>", which was completed to "git cmd path name" when the completed path has a special character like SP in it, without any attempt to keep "path name" a single filename.

This has been fixed to complete it to "git cmd path\ name" just like Bash completion does.

See commit 6d54f52, commit 7a478b3 (01 Jan 2019) by Chayoung You (yous).
(Merged by Junio C Hamano -- gitster -- in commit b84e297, 18 Jan 2019)

completion: treat results of git ls-tree as file paths

Let's say there are files named 'foo bar.txt', and 'abc def/test.txt' in repository.
When following commands trigger a completion:

git show HEAD:fo<Tab>
git show HEAD:ab<Tab>

The completion results in bash/zsh:

git show HEAD:foo bar.txt
git show HEAD:abc def/

Where the both of them have an unescaped space in paths, so they'll be misread by Git.
All entries of git ls-tree either a filename or a directory, so __gitcomp_file() is proper rather than __gitcomp_nl().

Note the commit f12785a, Git v2.18.0-rc0, which handles quoted paths properly.
Like this case, we should dequote $cur_ for ?*:* case.

For example, let's say there is untracked directory 'abc deg', then trigger a completion:

git show HEAD:abc\ de<Tab>
git show HEAD:'abc de<Tab>
git show HEAD:"abc de<Tab>

should uniquely complete 'abc def', but bash completes 'abc def' and 'abc deg' instead.

In zsh, triggering a completion:

git show HEAD:abc\ def/<Tab>

should complete 'test.txt', but nothing comes.
The both problems will be resolved by dequoting paths.

__git_complete_revlist_file() passes arguments to __gitcomp_nl() where the first one is a list something like:

abc def/Z
foo bar.txt Z

where Z is the mark of the EOL.

  • The trailing space of blob in __git ls-tree | sed.
    It makes the completion results become:

    git show HEAD:foo\ bar.txt\ <CURSOR>
    

So Git will try to find a file named 'foo bar.txt ' instead.

  • The trailing slash of tree in __git ls-tree | sed.
    It makes the completion results on zsh become:

    git show HEAD:abc\ def/ <CURSOR>
    

So that the last space on command like should be removed on zsh to complete filenames under 'abc def/'.

like image 23
VonC Avatar answered Oct 20 '22 07:10

VonC