How do I wrap git file merge with pre- and post-processing?
Asked Answered
L

1

7

I'd like to be able to invoke some pre-processing on files before Git tries to merge them, and the post-process the merged result. The general idea here is that some files are difficult to automatically merge as-is, but can be converted to an easier form for processing. Here's my concrete use case:

I have a repository of mostly not-very-sensitive data. Within that repository, I have a little bit of encrypted sensitive data, in a file called sensitive.pgp. I like this arrangement because I don't have to trust that my repository is being managed securely, I just have to trust the encryption and the password. The catch of course it that Git can't possibly merge encrypted text, so if sensitive.pgp is modified in two checkouts at once, there's no merging available -- even if the changes to the clear text are easily separated. The manual work-flow is like this:

  1. Merge conflict for sensitive.pgp detected.
  2. Start git-mergetool. Tool fails to merge PGP files, too.
  3. Now I have temporary files for my version, the base version, and the remote version.
  4. Decrypt all three files.
  5. Invoke my merge tool on the decrypted versions.
  6. Encrypt the result.
  7. git-add the new sensitive.pgp.

I'd like to tell Git to apply my pre- and post-processing before it even tries to merge, so it can handle this automatically. I can imagine lots of other scenarios with the same general pattern: Pretty much any time you have a compressed file format with a text-like underlying structure (e.g. PDF, OpenOffice, Word), for example.

Any suggestions?

Longmire answered 21/10, 2011 at 19:12 Comment(1)
Bonus points: Is there any way to configure this operation to only be done on specific files or file types, other than to put that logic into the pre- and post- processing itself?Longmire
I
6

You have a few options:

  1. define a checkout/checkin filter in .gitattributes (see git help attributes) that decrypts the files at checkout (leaving them unencrypted in your working tree) and encrypts them before checking in
  2. define a custom merge driver (see git help attributes and the merge.<driver>.* options in git help config)
  3. define a custom merge tool (see git help mergetool and the mergetool.<tool>.* options in git help config) that decrypts before invoking the real merge tool and encrypts when the real merge tool returns

You can configure git to only apply custom filters and merge drivers to specific files, but the merge tool applies to the whole repository unless you limit it by passing file names to the git mergetool command. You can design your custom merge tool to change its behavior depending on the name of the file being merged.

Ingroup answered 21/10, 2011 at 19:59 Comment(1)
Thanks a lot. I've started tinkering with a custom merge driver, and that looks like a good solution.Longmire

© 2022 - 2024 — McMap. All rights reserved.