First, consider why you want to mandate signed commits. They are not a best practice for most open-source projects because they represent a significant barrier to entry – you need to set up GPG, manage a key-ring, and exchange public keys so that they can be verified. Signed commits have most value when
- the software is security-sensitive, so you want to be able to tie all contributions to a committer, or
- the project is likely to be under legal threat, so you want to be able to trace every contribution to an author that has understood and agreed to the licensing and to the Developer Certificate of Origin. The project can then demonstrate through all signatures that they have exercised due diligence.
E.g. for the Linux Kernel project, both of these considerations apply.
If you are only interested in the potential legal benefits and manage development through GitHub, there are less cumbersome third-party solutions that verify only that the user account of a pull request has signed a DCO. This is a weaker guarantee than signed commits and represents some platform lock-in, but is much more contributor-friendly.
If you have decided that commit signatures are desirable, then you should only sign the most recent commit, and then sign all new commits afterwards. This is because of the Git data model:
- All data of a commit is hashed to produce an identifier for the commit.
- A commit includes the IDs of parent commits.
- When a commit is signed, the signature is part of the commit.
So if you were to sign an existing commit, its ID would change and you would have to re-write your complete history. But signing old commits is not necessary since the commit references parent commits – so you're not really signing an individual change, but the complete Git history up to and including that change.