git encrypt/decrypt remote repository files while push/pull
Yes and no.
You could try to depend on hook but that supposes they are installed at the remote locations, and that is not always reliable.
Another way to achieve almost the same effect would be by using a smudge/clean attribute filter driver, but not for a full repo.
(Source: Pro Git book: Customizing Git - Git Attributes)
That way the smudge script is able decode the files, while the clean script would encode them.
Again, that could work for a few sensitive files, not for a full repo.
Off course, those scripts would not be in the repository itself, and would be managed/communicated by another way.
As Alkaline points out in the comments, that idea does not scale for a repo, as the main git maintainer Junio C. Hamano comments back in 2009:
As the sole raison d'etre of
diff.textconv
is to allow potentially lossy conversion (e.g. msword-to-text) applied to the preimage and postimage pair of contents (that are supposed to be "clean") before giving a textual diff to human consumption.The above config may appear to work, but if you really want an encrypted repository, you should be using an encrypting filesystem.
That would give an added benefit that the work tree associated with your repository would also be encrypted.
Even though it does not scale to a full repo, the idea was implemented (3 years later in 2013) with git-crypt
, as detailed in Dominic Cerisano's answer.git-crypt
uses a content filter driver (implemented in cpp, with commands.cpp
setting up your .gitattributes
with the relevant smudge
and clean
filter commands).
As any content filter driver, you can then limit the application of git-crypt
to the set of files you want, in the same .gitattributes
file:
secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
As mentioned in the README
:
git-crypt
relies on git filters, which were not designed with encryption in mind.As such,
git-crypt
is not the best tool for encrypting most or all of the files in a repository.
Wheregit-crypt
really shines is where most of your repository is public, but you have a few files (perhaps private keys named*.key
, or a file with API credentials) which you need to encrypt.For encrypting an entire repository, consider using a system like
git-remote-gcrypt
instead.
(see more at spwhitton/ tech/ code/ git-remote-gcrypt, from Sean Whitton)
You can take a look at this project: https://github.com/shadowhand/git-encrypt
UPDATE: This above project is deprecated and recommends using https://github.com/AGWA/git-crypt
How to secure public and private remote assets using git-crypt.
- Transparent to all git clients and services (eg. GitHub, BitBucket, etc).
- Linux, OSX and Windows support.
- Asset level encryption (see VonC's answer).
- AES-256 cipher.
Create your 256 bit private key (RETAIN AND PROTECT THIS KEY)
sudo apt install git-crypt
mkdir key; cd key;
git init; git-crypt init
git-crypt export-key ~/crypt.key
Push a file called .gitattributes
to each repo's root directory.
It should contain one asset pattern per file, directory or type you wish to encrypt:
docs/doc.txt filter=git-crypt diff=git-crypt
js/** filter=git-crypt diff=git-crypt
*.java filter=git-crypt diff=git-crypt
src/cpp/*.h filter=git-crypt diff=git-crypt
Encrypt assets in each repo:
cd repo-root-directory
git-crypt unlock ~/crypt.key
git-crypt status -f
Push (from command line or git client)
Continue your git workflow as usual.
- Run
git-crypt unlock ~/crypt.key
once on any new clones of these secured repos. - You may wish to purge old unencrypted commit histories on all branches and tags.
- If you use a git client, it must fully support git filters and diffs.