Search code examples
gitpushgit-submodulesgit-remote

Stop Git from pushing secret (but tracked) files


Using git I track a top secret file called top-secret.txt. How can I ensure that this file never leaves my local system when pushing to a remote (but stays under version control locally)?

Example

  • Let's say I have a commit which changes the secret file called top-secret.txt and another file called not-secret.txt.
  • When pushing this commit only the change made to not-secret.txt shall be transferred to the remote.
  • The change made to top-secret.txt shall stay on my local system.

Extra info: Pushing is performed by a Continuous Integration System so I have the chance to execute scripts locally before pushing to the remote.

Do I need to setup a git submodule for this or is there a simpler solution?


Solution

  • You can't. Git's underlying object model (that everything is an object of one of four types: commit, tree, annotated-tag, or "blob"—i.e., file) prohibits distinguishing between "file I can see but you can't" and "file everyone can see". Anyone with a copy of the repository can see every object in the repository.

    There are therefore only two ways to keep a file secret:

    • don't include it in the repository in the first place, or
    • encrypt it.

    The submodule method amounts to doing the first of these while also giving a hint that there's something missing (not the same as "there but encrypted").