forgit
forgit copied to clipboard
Issues with special characters in filenames
Check list
- [x] I have read through the README
- [x] I have the latest version of forgit
- [x] I have searched through the existing issues
Environment info
- OS
- [x] Linux
- [ ] Mac OS X
- [ ] Windows
- [ ] Others:
- Shell
- [ ] bash
- [x] zsh
- [ ] fish
Problem / Steps to reproduce
git clone https://github.com/wfxr/forgit.git
cd forgit
echo "hello world" > my_filé
Git add with ga
does not work
fatal: pathspec 'my_fil\303\251' did not match any files
Nothing to add.
Add the file manually and commit:
git add my_filé
git commit -m "add file"
Try to view log with glo
, it works. Then press "enter" in this commit, it show empty screen for the file "my_fil\303\251".
Git escapes paths by default, leading to the described behavior. You can disable this with git config core.quotePath false
. Afterwards you should be able to work with the file you mentioned in forgit. For more details, see the git documentation on core.quotePath.
Let me know if that fixes the issue for you.
Yes, thanks!
Is it easy to fix it in forgit? If not, it may be usefull to add this workaround in the README.
It does not appear to be a super easy fix, but seems doable. I'll leave this issue open and will take a closer look once I find the time if nobody beats me to it. You are of course also more than welcome to send in a PR to fix the issue, if you like to. Note to myself and anybody trying to solve this:
git has a -z
option for many commands that prevents escaping. Unfortunately it appears to also disable colored output which we make use of in _forgit_add
.
Looking further into this, I see the following options:
- Add a
_forgit_git
function that simply runs git with the core.quotePath option set to false like this
_forgit_git() {
git -c core.quotePath=false "$@"
}
and replace all git calls with the function. This would also allow to quickly configure other git behavior for all functions, but is tedious. 2. Set the option before running any forgit function and reset it afterwards:
old_quote=$(git config core.quotePath)
git config core.quotePath false
_forgit_"${cmd}" "$@"
git config core.quotePath "$old_quote"
This is a bit ugly, but should work reliably and is the smallest change.
- Leave the current behavior as is and add it to the documentation.
I think I would prefer option 1. Would be interested in other peoples ideas/preferred approach. Any suggestions @carlfriedrich @cjappl?
Thanks for digging into this @sandr01d. Solution 2 definitely seems ugly.
I haven't understood, yet, why this happens in forgit but not with git directly. Where is the difference? We're calling git as well, so why does it behave differently?
I haven't understood, yet, why this happens in forgit but not with git directly. Where is the difference? We're calling git as well, so why does it behave differently?
When core.quotePath is set to unset or true, git escapes "unusual" file names in its output, but does not expect to receive quoted file names as input. The issue then arises when we consume quoted file nams from git and feed it back into other git commands, as we do in _forgit_add
where we consume output from git status
and feed it back into git add
.
I see, thanks for the explanation. That makes sense and should definitely go into a comment for why we are doing this. And in this case I would also prefer option 1.