git-branchless icon indicating copy to clipboard operation
git-branchless copied to clipboard

Support GPG-signing commits

Open arxanas opened this issue 3 years ago • 21 comments

Some resources:

  • Using git2's Repository::commit_signed: https://github.com/rust-lang/git2-rs/issues/507. It looks like you still need to sign the commit via GPG yourself.
    • Another example of signing the commit: https://blog.hackeriet.no/signing-git-commits-in-rust/
  • An implementation for git-revise: https://github.com/mystor/git-revise/pull/73

There's a few APIs in git-branchless which are capable of creating commits:

These commands are capable of creating commits:

  • git move.
    • Note that it can create commits in-memory or on-disk via git rebase, so both cases will have to be handled.
    • The calling code is in core::rewrite::execute. We'll probably want to add some configuration to to indicate that any commits created in this way should be signed. Also CherryPickFastOptions.
  • git amend.
  • git reword.
  • git sync and git restack: these should be handled fairly straightforwardly by whatever changes are made to support git move.
  • git record: experimental command, so not a priority at the moment.
  • git branchless snapshot create: these commits don't need to be signed since they're not supposed to be really committed/pushed.

These data structures will probably have to be updated to carry GPG information. You should be able to add a field and then follow the compiler errors to see where should be updated to use the new field:

In the long term, it would be best to contribute GPG-signing code to https://github.com/gitext-rs/git2-ext in some capacity. Either we can contribute it directly there, or contribute it to git-branchless first and extract it afterwards.

arxanas avatar Jul 18 '22 22:07 arxanas

Awesome, @arxanas. Thanks a lot for this carefully written issue.

This is probably more challenging than what I had anticipated, though I am not surprise. I will take the time to review the various links you have gathered here, and give it a try at some point.

lthms avatar Jul 23 '22 21:07 lthms

FYI I just released git2-ext v0.2 which has some of the basics of signing support implemented

  • A Sign trait
  • A commit that takes Sign
  • Updated reword and amend to take Sign

The only thing I didn't touch is the cherry_pick implementation as that uses git2's rebase mechanism and I don't see a way do to sign those.

epage avatar Jan 05 '23 15:01 epage

Also, for full git compatibility, we should try to support what is documented at https://github.com/git/git/blob/4f6db706e6ad145a9bf6b26a1ca0970bed27bb72/Documentation/config/gpg.txt

epage avatar Jan 05 '23 15:01 epage

I've done another release of git2-ext that re-implements git's gpg, x509, and ssh signing behavior.

The one problem with it is when the key is in a file, we do not yet correctly handle ~/. Knew that is complex enough that I didn't want to implement it myself and didn't find a crate to do it for me that was cross-platform.

epage avatar Jan 05 '23 18:01 epage

Yeah, I have just noticed that my signed commits are missing and just found that issue. It is not super urgent for me, but I wanted to know if there is timeline for this feature?

hauleth avatar May 09 '23 10:05 hauleth

@hauleth there are no plans to work on this. You might want to try jj instead, which has a draft PR; see the issue at https://github.com/martinvonz/jj/issues/58

arxanas avatar May 12 '23 19:05 arxanas

@arxanas I got used to git-branchless and I do not know if I want to test another implementation. If anything I would probably look how to implement it there. I was just curious if anyone is working on that yet. It is minor issue, but I just wondered if there are any plans for adding support for signing.

hauleth avatar May 15 '23 21:05 hauleth

there are no plans to work on this

@arxanas is that a "won't fix" or just no one have time to work on it? I can try to help out if it is the second case.

tommyip avatar Jun 01 '23 14:06 tommyip

@tommyip I guess you can call it a "not enough intererst to put explicit effort in" i.e. other things outweigh this for main dev(s) and they don't use gpg-signing themselves so there's little motivation.

I made the draft PR for jj - and haven't touched it since as I'm kind of busy lately :shrug: But people are happy to accept such PRs if they are well-formed :)

necauqua avatar Jun 06 '23 21:06 necauqua

@tommyip I simply have no plans to work on it for now, but I would accept a PR implementing it.

arxanas avatar Jun 07 '23 02:06 arxanas

Cool my work uses GPG-signing so I have a bit more incentive to see this implemented. No promises though 🫣.

tommyip avatar Jun 07 '23 07:06 tommyip

Hello, this happens to be a feature I'm also really interested in since we also require signed commits.

I see that @tommyip has some work already done here. First of all, thank you for looking into it! I just wanted to check the status of your WIP, and offer my help if there is anything that is still outstanding.

lbjarre avatar Nov 13 '23 09:11 lbjarre

Hi @lbjarre. The WIP PR supports all the git-branchless subcommands (at least at the time of my last push), I have been using it daily without any issue. The PR just need some integration tests, which is a bit difficult since the existing test suite assumes the output from git is deterministic but that is not the case for cryptographic signatures.

You can pull and compile my branch before this get upstreamed.

tommyip avatar Nov 13 '23 14:11 tommyip

Signatures should be deterministic as well. You just need to provide some signing key as a part of test suite. @tommyip have you tested it with SSH signing as well?

hauleth avatar Nov 13 '23 14:11 hauleth

I don't quite remember if this is the actual problem - openpgp uses the current time as part of the signature generation, but there is no easy way to mock the timestamp.

And yes, SSH signing works.

tommyip avatar Nov 13 '23 14:11 tommyip

but there is no easy way to mock the timestamp

There is a hidden gpg option --faked-system-time :) If you append an ! to the argument the clock also would stay frozen (and not tick up from the set time)

edit: and signatures are stable with it set, so that's great in fact, would help me with implementing similar tests once I finish doing something similar for jj

necauqua avatar Nov 13 '23 20:11 necauqua

there is no easy way to mock the timestamp.

I don't know the first thing about signing commits, but the test harness for this project includes a way to mock the timestamp used by git, so that commits are created w/ deterministic ids. Does the gpg signing use the same timestamp at git?

Here's the options struct: https://github.com/arxanas/git-branchless/blob/master/git-branchless-lib/src/testing.rs#L71-L74

And here's a usage example: https://github.com/arxanas/git-branchless/blob/master/git-branchless-smartlog/tests/test_smartlog.rs#L119C11-L125

claytonrcarter avatar Nov 14 '23 01:11 claytonrcarter