AGWA / git-crypt

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

`git worktree add` in repo with encrypted commited file made encrypted fails. #105

Open ghost opened 7 years ago

ghost commented 7 years ago

I've tested this on debian jessie, with git/testing (2.11.0-1) from http://ftp.us.debian.org/debian/ testing/main amd64 Packages.

What I observe is, git worktree add's failure behavior falls into, what I get the impression to be, a large range of compatibility problems that stem from having a previously committed file with the same path as a current encrypted file. I'm curios if a .gitcryptignore and .git/info/gitcryptignore type file to list files for which the error condition triggered for "an older version of this file may be unencrypted in the repository's history." does not interrupt git plumbing commands.

Its a bit annoying that all worktree's have to independently be decrypted; maybe a feature to apply lock/unlocks across all work trees would be a nice configuration option to add. git config --global gitcrypt.globalworktreelockstate true kinda thing.

# Init
$ git init example
$ cd example/
$ git crypt init
$ git crypt exampleport-key ../example.gitcrypt
$ cat .gitattributes
secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt

# Encrypted file Works
$ touch secretfile
$ git add secretfile 
$ git commit secretfile -m "add secret file, encrypted"

$ git crypt lock
$ git worktree add ../example1  # Success

$ git crypt unlock ../example.gitcrypt 
$ git worktree add ../example2  # Success

# Unencrypted file turned encrypted fails unless repo is locked
$ touch file
$ git add file 
$ git commit file -m "unencrypted file"
$ cat .gitattributes
secretfile filter=git-crypt diff=git-crypt
file filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt

$ git rm --cached file
$ git add file .gitattributes 
$ git commit file .gitattributes -m "encrypt file"

$ git worktree add ../example3  # Fails (128)
Preparing ../example3 (identifier example3)
git-crypt: Error: Unable to open key file - have you unlocked/initialized this repository yet?
error: external filter '"/usr/local/bin/git-crypt" smudge' failed 1
error: external filter '"/usr/local/bin/git-crypt" smudge' failed
fatal: file: smudge filter git-crypt failed

$ echo $?
128

$ git crypt lock
$ git worktree add ../example4  # Works
$ git crypt unlock ../example.gitcrypt 

$ cd ../example4/
$ git crypt unlock ../example.gitcrypt  # Must also decrypt the work tree
stefan-improbable commented 7 years ago

I'm also experiencing this behaviour. It seems that there can be only one decrypted worktree:

#!/bin/bash

GPG_USER=stefan

mkdir repo
cd repo
git init .

cat << EOF > .gitattributes
*.key filter=git-crypt diff=git-crypt
EOF
git crypt init
git crypt add-gpg-user "$GPG_USER"

cat << EOF > test.key
testdata
EOF

git add -A
git commit -m 'commit1'
git crypt lock

git worktree add ../wt
git crypt unlock

cd ../wt
# These fail
echo "********* Failing lock ***********"
git crypt lock
echo "********* Failing lock --force ***********"
git crypt lock --force
echo "********* Failing unlock ***********"
git crypt unlock

It would be nice if git crypt supported multiple workspaces or at least show some better error message.

ckyoog commented 5 years ago

@stefan-improbable the reason git-crypt doesn't work with multiple worktree is because it writes its git config, both[filter git-crypt] and [diff git-crypt], into .git/config which is shared by all worktrees. git-crypt has already supported to add/remove the key file for different worktree to/from different dir. So the issue you demonstrated is only because the git-crypt config now is still being read/written to/from one place, which is .git/config.

I made a simple patch to fix your issue (my issue too), which works for me. I can freely git crypt unlock/lock in different worktree. This patch is based on extensions.worktreeConfig = true, so to use my patch, you have to run the following command first

git config extensions.worktreeConfig true

git-crypt-support-worktree-simple-version-patch.txt

icy commented 5 years ago

@ckyoog I've tried your patch, but then the command git status always failed, then I couldn't lock/unlock and/or do anything. I had to disable the extension, use lock -force and the unlock the things.

stefan-improbable commented 4 years ago

@ckyoog thanks, your patch seems to work for me!

@icy you may be using and old git client that doesn't support --worktree, i.e. if git config --worktree fails, the patched git-crypt will be failing as well. Also try git crypt locking everything with non-patched git-crypt before using the patched one.

bqv commented 4 years ago

@ckyoog would you please submit that patch as a PR?

icy commented 4 years ago

@icy you may be using and old git client that doesn't support --worktree, i.e. if git config --worktree fails, the patched git-crypt will be failing as well. Also try git crypt locking everything with non-patched git-crypt before using the patched one.

I will try again. If the patch requires new git, it would have some checks or warning that would be very helpful. Thx

icy commented 4 years ago

@ckyoog I have the issue with (hopefully) new git as below

$ git worktree add -b testing w/test
Preparing worktree (new branch 'testing')
git-crypt: Error: Unable to open key file - have you unlocked/initialized this repository yet?
error: external filter '"git-crypt" smudge' failed 1
error: external filter '"git-crypt" smudge' failed
fatal: DISCOVERY/details.secret.md: smudge filter git-crypt failed

$ git version
git version 2.26.0
bqv commented 4 years ago

could you try moving the filters from .git/config to .git/config.worktree

icy commented 4 years ago

could you try moving the filters from .git/config to .git/config.worktree

Thanks a lot. My mistake, I should have executed git lock before executing git worktree.

I confirm @ckyoog's patch is working . Thanks a ton.

baguilarq commented 2 years ago

It could be great if we can have this feature, I'm having the same issue

asmigala commented 10 months ago

This seems to work around the issue (even without the patch):

cp -r .git/git-crypt .git/worktrees/YOUR_WORKTREE_NAME/
starsep commented 10 months ago

Copying configuration doesn't seem great as keeping it in sync will be problematic. I haven't tested whether it works but would try to symlink instead:

ln -sr .git/git-crypt .git/worktrees/YOUR_WORKTREE_NAME/git-crypt
asmigala commented 10 months ago

@starsep yep, that works as well.

WizardUli commented 4 months ago

Any news on a proper fix? worktrees are absolutely integral part of git.