12

All commits that have been pushed to the develop branch indicate that they were verified.

To merge everything from develop to master, I decided to click a button Rebase and merge. (I didn't want to create another new commit for the master.)

Surprisingly after the merge succeeds, all the verified signatures were gone from the master.

  1. What am I missing here?
  2. How am I supposed to preserve the verified signature?
josemigallas
  • 3,761
  • 1
  • 29
  • 68
JeffMinsungKim
  • 1,940
  • 7
  • 27
  • 50
  • 3
    Rebasing creates new commits, the old signatures are invalid and can't be reused. You have to sign the new commits, so you have to instruct rebase to apply new signatures to the commits. – Lasse V. Karlsen Jul 17 '20 at 08:34
  • 1
    I'm not talking about interactive rebase squashing. I've already looked into the post you gave. Is this a normal behavior then? – JeffMinsungKim Jul 17 '20 at 08:35
  • 2
    Rebasing constructs new commits, the hash of the parent is included in the data that is signed if I'm not mistaken, so yes, this is expected. – Lasse V. Karlsen Jul 17 '20 at 08:37
  • 2
    While the answer of the linked 'duplicate' may be similar, the question is a different case. Voting to reopen. – jessehouwing Jul 17 '20 at 13:16
  • 2
    I believe this question should be reopened. The reason is I didn't do an interactive rebase through a CLI. All I want to figure it out why the problem actually happened when I clicked the `Rebase and merge` button from GH. – JeffMinsungKim Jul 20 '20 at 00:46
  • Can you clarify why you think that your question differs? Please do so by editing the question and providing more context – Nico Haase Jul 24 '20 at 08:42
  • I've already mentioned the reason above. – JeffMinsungKim Jul 28 '20 at 00:54
  • [This page on GitHub Docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges) explains what each pull request options do under the hood. – catwith Mar 25 '22 at 04:30

1 Answers1

18

When rebasing the changes are replayed on master. This causes them to be "rebased" on a new parent commit which will change the commit-id (which is partially based on the parent commit-id).

Rebasing may also require merging the changes as the commits are replayed. Even if the merge happens automatically, it may change the contents of the files. The file contents are another element that make up the commit-id.

The verification is done through a cryptographic signature of the contents and the commit-metadata. Hence, rebasing will break that signature.

To not break your signature you'll need to use a fast-forward merge (where no new merge commit is created). To achieve that you'll need to locally rebase your changes and sign them.

Or you can squash-rebase, where all your small commits are rolled up into a single new commit, which GitHub will sign on your behalf.

If verification is important to you, rebasing is generally a bad idea, fast-forward merges and merge commits will better reflect what actually happened and who had authored those changes.

Official docs:

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
  • 2
    Actually, the hash of the commit itself cannot be included, as that is based on the commit object, which contains the signature. Would be a chicken and the egg kind of problem. – Lasse V. Karlsen Jul 17 '20 at 08:44
  • 1
    Your answer is well written. Thank you and it helped me to understand a general concept. – JeffMinsungKim Jul 17 '20 at 08:50
  • 1
    My $0.02 1) Even if you are on top of the master, there is no conflict resolution, and your display name + email on github matches to the one on your .gitconfig: still there is one important thing happening: GitHub will alter CommitDate to match the date-time you pressed "Merge-Rebase" or "Squash-Rebase" button. This gives different commit hash and breaks signature 2) There is nothing special abou Squash-Rebase, in no way GitHub can sign a commit on you behalf, it just don't even have a private keys – Dmitry Gusarov Apr 03 '21 at 15:22
  • 2
    "When rebasing the changes are replayed on master. This causes them to be "rebased" on a new parent commit" -> wrong in many cases where the feature-branch is already based on the latest master (completely normal when using a rebase workflow). In this case it is the behavior of github (changing timestamps using git rebase --force-rebase) which is causing the change of commit hashes. This does not happen with other git servers like gitlab and is a really bad implementation. – Étienne Mar 15 '23 at 13:26
  • See https://stackoverflow.com/questions/60597400/how-to-do-a-fast-forward-merge-on-github/75738857#75738857 for details – Étienne Mar 15 '23 at 13:37
  • GitHub has a "Fast-forward merge" option in the dropdown. You don't *have* to select rebase. But if you do rebase, you get these issues. If your feature isn't based on the latest commit, you can't use fast-forward merges and when working with multiple developers on a single product, you'll likely have the same issues. – jessehouwing Mar 15 '23 at 15:27