AGWA / git-crypt

Transparent file encryption in git
https://www.agwa.name/projects/git-crypt/
GNU General Public License v3.0
8.11k stars 472 forks source link

Don't hard code git-crypt path in .git/config (even when invoked with absolute path) #217

Open alerque opened 3 years ago

alerque commented 3 years ago

When initializing a repository with git crypt init, the current behavior is to try to resolve the full path to the executable and save a section in the config such as:

[filter "git-crypt"]
    smudge = \"/usr/bin/git-crypt\" smudge
    clean = \"/usr/bin/git-crypt\" clean
    required = true

This is baloney and needs to stop, at least on Unix. Well intention baloney maybe, but it takes over too much control from the host system. Resolving this path once on init makes the repository unportable. It turns out Unix system at least are really good at resolving paths and this is something that should happen at run time, not repo init time.

The offending function is our_exe_path(). I don't know about the Windows implementation, but on the Unix side of things this just makes life hard because the answer it comes up with only matches the system that initialized the repo, not the one that may be using it.

I have several repos that live on external disks or network drives and a large variety of systems that access them. The /usr/bin/git-crypt location is pretty common but not universal across them. Some are in /usr/local/bin/git-crypt, others such as CI runners often have $HOME/bin/git-crypt or similar user/project relative paths.

The way git-annex handles this makes repositories much more portable:

[filter "annex"]
    smudge = git-annex smudge -- %f
    clean = git-annex smudge --clean -- %f

Note the lack of path resoolution here leaving the system to resolve the path at run time.

I believe git-crypt would be better off doing the same thing.

AGWA commented 3 years ago

For the record, if you initialize git-crypt by running git-crypt init (which is how the documentation tells you to use git-crypt, as opposed to git crypt init) then your .git/config will look like this:

[filter "git-crypt"]
    smudge = \"git-crypt\" smudge
    clean = \"git-crypt\" clean
    required = true

git-crypt only puts an absolute path there if git-crypt was invoked with an absolute path, as that's an indication that git-crypt is not in $PATH and that the user needs an absolute path for it to work properly. It does appear that git crypt init causes git-crypt to be invoked with an absolute path, but git-crypt is not tested or documented to be used that way, and I don't know how else it might work differently when invoked from git.

I'm open to changing this behavior, but your rhetoric here is a degree too harsh for what is really going on.

alerque commented 3 years ago

Okay that's an interesting backstory for how this ended up this way. As noted I wasn't trying to say the intentions were bad, looking at our_exe_path() I was sure it was trying to come out on top of some problem. That doesn't change the outcome that my repos keep ending up choking across systems until I manually edit the config.

Invoking git-crypt vs. git crypt should cause next to no change. If anything the only change would be smudge = git crypt smudge vs. smudge = git-crypt-smudge. I should be entered into the config exactly as the user called it, without the quotes and without any path the user didn't enter.

If there isn't a way to derive that from git, what would be the harm in just defaulting to a hard coded git-crypt? Does the build system even support renamable builds? Does it ever need a path? Does it even work if it's not in the path somehow?

AGWA commented 3 years ago

Okay that's an interesting backstory for how this ended up this way. As noted I wasn't trying to say the intentions were bad, looking at our_exe_path() I was sure it was trying to come out on top of some problem. That doesn't change the outcome that my repos keep ending up choking across systems until I manually edit the config.

Does using git-crypt init instead of git crypt init fix the problem for you?

Invoking git-crypt vs. git crypt should cause next to no change.

The fact that running git crypt is even possible is an unintended side effect of git-crypt being prefixed with git-. It is not intended to be a Git sub-command. "Cause next to no change" is a nice idea, but the fact is that git is invoking git-crypt with different arguments, and likely other changes to the execution environment. It will never be the same as calling git-crypt directly, and I'm not sure why limited development time should be spent trying to make git-crypt work as a Git sub-command.

If there isn't a way to derive that from git, what would be the harm in just defaulting to a hard coded git-crypt? Does the build system even support renamable builds? Does it ever need a path? Does it even work if it's not in the path somehow?

Yes, git-crypt can be installed anywhere with any name and it works just fine when not in $PATH. If I change git-crypt to hard code a bare git-crypt command, there will surely be users filing issues complaining about how the git-crypt command can't be found. The current logic attempts to make all users happy. #71 suggests that the logic does work for users with similar use cases as yours. It just doesn't work when you try to use git-crypt as a Git sub-command.