sops
sops copied to clipboard
sops mergetool
This is a proposal for a subcommand to make merge conflicts easier to resolve.
Merge conflicts result in yaml files which have git conflict markers interspersed throughout:
<<<<<<< HEAD
hello: ENC[AES256_GCM,data:DwC3quV200ZxFMcA7u52e2aC,iv:JllZv1pXjMhxOEf73R+RH837bOw7tSCPS71d81FA/ig=,tag:5m504sVLe86QWEy7Z8FvOg==,type:str]
example_key: ENC[AES256_GCM,data:3pz9roKd3wkUCLp3qw==,iv:MhT4V6wvS8TcT/p5MiU03V9aKM5mIaoUhJ6a+APyZ74=,tag:63WRr3wGYRgm8ly544ziig==,type:str]
=======
hello: ENC[AES256_GCM,data:APSKlYA=,iv:Bqnt+wHabgrqRxF+qBtcldCOzFF9pvDyJeB0FzkMK0E=,tag:bQF0E2R1g2f4mV40gkHRiA==,type:str]
example_key: ENC[AES256_GCM,data:ofA1/U7nZ6ib,iv:PMVDHfuQvOCdba4j0yX4FhRvU0muNB7rsA1sQfWspwE=,tag:1ihSoIBU64SnYGjFSQ+O+g==,type:str]
#ENC[AES256_GCM,data:29yFDGk0NqSdVLhS3rtGyA==,iv:7OPc3YK4qdjd+WhTgQ0fUFMFFcq2B6CHCprVrccwJwE=,tag:lZRdY1Au36RpV/rOtd/Wkg==,type:comment]
example_array:
- ENC[AES256_GCM,data:Kc4Cep2Aop9UcfuYtJA=,iv:Lq3K8iULXtHHF93wnt+XEvQU658jpkEELNWLkcIKlow=,tag:kThmC9Tj0j+PVq9oX91a9w==,type:str]
- ENC[AES256_GCM,data:n3q+i4Qb/okAMD7KTpM=,iv:uQtHMC8gSiWKCLH3RajRlPLhLDk0b+aI1UmO85uAHkA=,tag:80Mxe37inATu7yh3Jb16Lw==,type:str]
- ENC[AES256_GCM,data:iTBqV9Q7YkJ+Z/nNKqo=,iv:gbxjebdYTuPEcd/u2Ob+yP/FI3hUn3WNZ5uMBzDjTO0=,tag:D2oqgJG28+mc1zInH0vbAQ==,type:str]
>>>>>>> conflict
example_number: ENC[AES256_GCM,data:0fDVSRYmzbgjcQ==,iv:hFAX3Ct8Urgrcy/bU0Cah7XRMVooaQhhBLV43TEDcDU=,tag:usjRGYZ7WF1VN5jimpW+xw==,type:float]
example_numbers:
- ENC[AES256_GCM,data:fOw=,iv:jDQcTx4EMybKxy1oeZVNnz/Q91d8s+IiA937xC33XWs=,tag:7bbs+ePG9yIMnUqnkf/gNg==,type:int]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
<<<<<<< HEAD
lastmodified: "2023-12-10T15:22:35Z"
mac: ENC[AES256_GCM,data:mS8QUUAJqNX8xgzW5ULrE6TNMLfbPCT2Hx7E3OVPfscqNUqtufkPK8V0RS2ZFgL00Nf6rsnPpxxpSWPDfCgtySR3IoD0yR0II5ANNe5/as8ZzBI0qT4YPwYeWZvNHDdCF78fYlc7oahvlDITe9CB6TKl7j+Q5ORb9/5tp3i5YPY=,iv:HiADr04Zqs+PcHx5bKpitIpqgKFKoQ/VzmliDg3xzPc=,tag:TXhsOk/IqBsZKIdiTjH39Q==,type:str]
=======
lastmodified: "2023-12-10T15:22:00Z"
mac: ENC[AES256_GCM,data:yodhyMzC2z8tmVAuojZx2S+arts0QYTwU+VKY7apqDcv8i9a+FMbQjiF0UJkmh2UmvjUGsbxWBZqVyFUU1eYS7DXrrJ17wmyWENMcKNCYXR1keYbMjYRBAiF1NCpUq8Quxy/IkxaOxBso8Im8xLWg15FhI3OKlQhb50z1XjEoNE=,iv:G1xMNDCyp0AE92CaC/F008rotHkrecxS3DMrKe+yjwM=,tag:/7BXZ2Q3KE3Xb3OGztwK9Q==,type:str]
>>>>>>> conflict
pgp:
- created_at: "2023-12-10T15:21:20Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQEMA/H3E2d4aIikAQf+OqYuFFEtr/SmuQdNn+gnkYz2jLopqU9R/LsJZjvfshrX
pnfuyLO0v5PrqbZda/HLw6cMM3MBVzW6BMUGkuzhG0A0xc/ePeuNLD67ebVwgHG4
oMGGLrrUsVhIVXIlRdOOuAwurFNdExMz8zgjaEIOG+wkrOXu2ea4O1lI1HGO3OcD
gC80RoQONBkj5LWiOJcDwCg51nKYIqKQsHlSJy5pRghD6sOPMKd/PhUc/frVeV5/
TMn3X71loG8KT/R3ZalxpiEhnClBQWO4P48PVk08P1ZmiWZ5azSydq8M97IrptGZ
KB4n+M3N2K9dpoFWOpGbipHjKs3NaRJQDcET4DyNWtJcARP6ZXsTKJCGtNJpkFvn
CSoKP03prUn8Q3ZmwIdTlN5azG6jUkXQ+X4Os8bQAJN8mZNzfBt5d+wcS1o/BZn6
4oltd2SQdjoSQ+bzMVepvGecL9/nGSmIPlRHoV8=
=Ldwt
-----END PGP MESSAGE-----
fp: 12C84F483BE5E15FEFEDBD594B342EA504A3ADC1
unencrypted_suffix: _unencrypted
version: 3.8.1
Attempting to edit this file without sops will result in mac mismatch errors for obvious reasons. Unfortunately, sops is unable to interpret these files:
$ sops example.yml
Error unmarshalling input yaml: yaml: line 2: mapping values are not allowed in this context
The current workflow I have for handling merge conflicts is to check out the file from both branches, decrypt it, diff it, make my changes, and then reencrypt it. This works but it's rather annoying.
Git has a very cool feature called git-mergetool which does the work of checking out the two branches and replacing the original file once the conflict is resolved for us. We can use git mergetool
to invoke sops, sops can decrypt the files and handle our merge, and then reencrypt it once we're done.
When git mergetool is invoked with this tool (either through the -t or --tool option or the merge.tool configuration variable), the configured command line will be invoked with $BASE set to the name of a temporary file containing the common base for the merge, if available; $LOCAL set to the name of a temporary file containing the contents of the file on the current branch; $REMOTE set to the name of a temporary file containing the contents of the file to be merged, and $MERGED set to the name of the file to which the merge tool should write the result of the merge resolution.
Right now I have this working as a proof of concept with vim, similar to how git config merge.tool vimdiff
works. By setting the following in your .git/config you can invoke git mergetool
which will give you a lovely vim window to resolve your changes
[mergetool "sops"]
cmd = sops mergetool --base $BASE --remote $REMOTE --local $LOCAL --merged $MERGED
[merge]
tool = sops
Anything in the pane at the bottom will be encrypted with sops before replacing the conflicted file. This allows for easy resolution of merge conflicts without requiring anything funky with --ignore-mac
.
I've included positional arguments in the mergetool
command which should allow other editors such as kdiff3 or meld but I haven't tested it. Invocation would be something like sops mergetool kdiff3 {base} {local} {remote} -o {merged}
I've got quite a bit of code cleanup and refactoring to do but I wanted to get some feedback on this proposed feature first.