Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--path-rename with spaces #56

Closed
m1nkeh opened this issue Feb 12, 2020 · 7 comments
Closed

--path-rename with spaces #56

m1nkeh opened this issue Feb 12, 2020 · 7 comments

Comments

@m1nkeh
Copy link

m1nkeh commented Feb 12, 2020

Hi,

I can't get the --path-rename command to function if there is a space in the path..

Works:
git filter-repo --path new.folder/ --path-rename new.folder/:'' --force --dry-run

Fails:
git filter-repo --path 'new folder/' --path-rename 'new folder/':'' --force --dry-run

This simply throws the exception..

Traceback (most recent call last):
  File "C:\Python38\Scripts\\git-filter-repo", line 3871, in <module>  
    args = FilteringOptions.parse_args(sys.argv[1:])
  File "C:\Python38\Scripts\\git-filter-repo", line 2141, in parse_args
    args = parser.parse_args(input_args)
  File "C:\Python38\lib\argparse.py", line 1768, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "C:\Python38\lib\argparse.py", line 1800, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "C:\Python38\lib\argparse.py", line 2006, in _parse_known_args
    start_index = consume_optional(start_index)
  File "C:\Python38\lib\argparse.py", line 1946, in consume_optional
    take_action(action, args, option_string)
  File "C:\Python38\lib\argparse.py", line 1874, in take_action
    action(self, namespace, argument_values, option_string)
  File "C:\Python38\Scripts\\git-filter-repo", line 1611, in __call__
    if values[0] and values[1] and not (
IndexError: list index out of range

Is this a python version issue? I have tried all kinds of combinations, double quotes, escape chars, etc.

@m1nkeh
Copy link
Author

m1nkeh commented Feb 12, 2020

urghh, figured it out!

git filter-repo --path 'new folder/' --path-rename 'new folder/:' --force --dry-run

i must say this in slight contrary to the comment here: https://github.com/newren/git-filter-repo#solving-this-with-filter-repo

"the single quotes are unnecessary, but make it clearer to a human"

d'oh! 🍺

@newren
Copy link
Owner

newren commented Feb 12, 2020

Indeed, this isn't a python issue at all but one of how the shell passes arguments to programs. For example, let's say you had a repository with the following three files, one of them oddly named:

README.md
foo.py
README.md --path foo.py

Then the command

git filter-repo --path README.md --path foo.py

would clearly be passing two --path arguments and asking for those two paths to be kept, while the command

git filter-repo --path 'README.md --path foo.py'

would be passing just one --path argument and asking for the funnily named path to be kept.

Also, this isn't contrary to the documentation comment at all as the example didn't have any spaces or special characters that needed to be quoted to keep the shell from interpreting the characters in a funny way.

Anyway, glad you figured it out.

@newren newren closed this as completed Feb 12, 2020
@m1nkeh
Copy link
Author

m1nkeh commented Feb 12, 2020

sorry, maybe contrary was not the right word... but i didn't want to go so far as 'confusing'.. perhaps, unclear?

i.e. the example on that page cannot be extended to:
git filter-repo --path 'some path/' --path-rename 'some path/:'''

this also does not work:
git filter-repo --path "some path/" --path-rename "some path/:''"

nor this:
git filter-repo --path 'some path/' --path-rename 'some path/:""'

essentially i couldn't take the example of adding '' for human readability, and extend it in some way that was immediately obvious..

so, i guess to close this out properly what is the right way to escape this please? 🙂

@newren
Copy link
Owner

newren commented Feb 12, 2020

The most straightforward translation is

git filter-repo --path 'some path/' --rename-path 'some path/':''

although this also works:

git filter-repo --path 'some path/' --rename-path 'some path/:'

The first of your examples is actually fine, though dropping the two final quotes is perhaps clearer since it literally ends up with filter-repo getting the exact same arguments. The other two of your examples try to replace
some path/
with either of the following two literal strings
''
or
""
i.e. it'd rename a path like
some path/foo.c
to
''foo.c
with the literal quotes as part of the filename.

None of this is a filter-repo issue, but one of understanding how shells work. It may be instructive with a simple helper program named arguments.py with the following contents:

#!/usr/bin/env python3

import sys
print("Arguments (1 per line):\n  :" + ":\n  :".join(sys.argv) + ":")

Now, if we try that program with the last two examples you provided, you can what filter-repo was actually told by the shell:

$ ./arguments.py git filter-repo --path 'some path/' --rename-path "some path/:''"
Arguments (1 per line):
  :./arguments.py:
  :git:
  :filter-repo:
  :--path:
  :some path/:
  :--rename-path:
  :some path/:'':
$ ./arguments.py git filter-repo --path 'some path/' --rename-path 'some path/:""'
Arguments (1 per line):
  :./arguments.py:
  :git:
  :filter-repo:
  :--path:
  :some path/:
  :--rename-path:
  :some path/:"":

which shows why filter-repo believes it was told to replace 'some path/' with '""'. In contrast, with either of the versions I specified:

$ ./arguments.py git filter-repo --path 'some path/' --rename-path 'some path/':''
Arguments (1 per line):
  :./arguments.py:
  :git:
  :filter-repo:
  :--path:
  :some path/:
  :--rename-path:
  :some path/::
$ ./arguments.py git filter-repo --path 'some path/' --rename-path 'some path/':
Arguments (1 per line):
  :./arguments.py:
  :git:
  :filter-repo:
  :--path:
  :some path/:
  :--rename-path:
  :some path/::

which shows that 'some path/' should be replaced by nothing. Also, we can run your original example both with three trailing quotes or just one to show that they result in the filter-repo getting the exact same input arguments:

$ ./arguments.py git filter-repo --path 'some path/' --rename-path 'some path/:'''
Arguments (1 per line):
  :./arguments.py:
  :git:
  :filter-repo:
  :--path:
  :some path/:
  :--rename-path:
  :some path/::
$ ./arguments.py git filter-repo --path 'some path/' --rename-path 'some path/:'
Arguments (1 per line):
  :./arguments.py:
  :git:
  :filter-repo:
  :--path:
  :some path/:
  :--rename-path:
  :some path/::

@newren
Copy link
Owner

newren commented Feb 12, 2020

Oh, also, as this is entirely a shell issue, I should point out that quotes aren't necessary at all, even with spaces; The following:

  git filter-repo --path some\ path/ --rename-path some\ path/:

would have also worked. The whole problem is how do you prevent the shell from breaking arguments at the space character; so that you can pass a simple OLDPREFIX:NEWPREFIX string as a single argument to filter-repo.

@m1nkeh
Copy link
Author

m1nkeh commented Feb 12, 2020

Oooookkkkay. So, the issue all along was that my Git client of choice, PowerShell for Git (https://github.com/dahlbyk/posh-git), seems to not be respecting any of this!!

Your last comment, something which i had explicitly tried to do earlier today made me suddenly think it could be the client. And of course, in the vanilla Git Bash.. it works le sigh 😕.

Honestly thought i was going mad with you saying it worked, and me literally copy+pasting the command it not working!

Thanks for your patience 🙂.

🤦

@newren
Copy link
Owner

newren commented Feb 12, 2020

Ah, PowerShell has even funnier quoting rules/requirements than posix shells, eh? Good to know, thanks for the heads up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants