skip to content

In Git, what does the -s flag on git commit add, and why do projects require it?

level: juniorimportance: should knowfreq 42%

answer

  1. a statement, not proof
  2. one line at the end of the message
  3. comes from user.name and user.email
  4. kernel-style contribution agreement
  5. Developer Certificate of Origin trailer

basics

~20 s

The -s flag appends a Signed-off-by trailer carrying your configured name and email. Projects governed by the Developer Certificate of Origin read that line as your certification that you have the right to submit the code under the project's licence.

solid answer

~50 s

`git commit -s` (long form `--signoff`) appends a trailer line to the end of the commit message, built from `user.name` and `user.email` — for example `Signed-off-by: Ada Lovelace <[email protected]>`. It exists to satisfy the Developer Certificate of Origin (DCO), the lightweight contribution agreement popularised by the Linux kernel: by adding the line you assert that you wrote the change, or otherwise have the right to submit it under the project's licence. It is plain text, not cryptography — anyone can type it — and it is unrelated to `git commit -S`, which makes a GPG or SSH signature. Projects enforce it during review or with a server-side hook that rejects a push whose commits lack the trailer. You can add it afterwards with `git commit --amend -s`, or across a series with `git rebase --signoff <base>`.

code

bash · 8 lines
bash
git commit -s -m "parser: reject empty header names"
git log -1 --format='%B'
# parser: reject empty header names
#
# Signed-off-by: Ada Lovelace <[email protected]>

git commit --amend -s          # add it to the commit you just made
git rebase --signoff origin/main   # add it to the whole series (rewrites hashes)

go deeper

for a junior

Recall the exact effect: -s appends a Signed-off-by line built from your configured name and email. Know the phrase Developer Certificate of Origin and that the line is a claim about rights, not a signature.

for a middle

Explain that the trailer is plain text inside the commit message, that -S is the unrelated cryptographic signing flag, and how to repair a series with git commit --amend -s or git rebase --signoff.

for a senior

Show how a project actually enforces the policy — reviewers, and a server-side hook that inspects trailers on pushed commits — and why a mismatch between the sign-off address and the author address matters.

for a principal

Be ready to argue DCO versus a contributor licence agreement for a project you own: friction on contributors, what each actually protects, and how much provenance you need before adding cryptographic signing on top.

## What the flag actually does `git commit -s` (or `--signoff`) does exactly one mechanical thing: it appends a line of the form `Signed-off-by: <name> <email>` to the end of the commit message, using the identity Git would use as the committer — `user.name` and `user.email` from your configuration. Nothing is validated. Git does not check that the address is yours, does not contact anyone, and does not attach any cryptographic material. The trailer is ordinary text inside the commit object, so it is hashed along with the rest of the message and travels with the commit forever. ## The Developer Certificate of Origin The trailer means something only because of a policy the project adopts. The Developer Certificate of Origin (DCO) is a short document, originally written for Linux kernel development, that a project publishes and asks contributors to agree to. By adding the sign-off line you certify roughly this: that you wrote the contribution yourself and have the right to submit it under the project's licence; or that it is based on work covered by a compatible licence and you have the right to submit it under that licence; or that someone else who made one of those certifications gave it to you and you are passing it on unmodified. You also agree that the contribution and the record of it — including the name and email in the trailer — are public and may be redistributed. The DCO is deliberately cheaper than a contributor licence agreement: there is no form to sign, no company to countersign, and the record lives in the commit history itself. ## Sign-off is not a signature This is the single most common confusion. `-s` writes a text line; `-S` (`--gpg-sign`) attaches a cryptographic signature to the commit object using GPG or an SSH key. `-s` proves nothing about identity — it is a *statement*, like initialling a form. `-S` gives verifiable provenance. Some projects want both, but they answer different questions: the first is a legal assertion, the second is authenticity. Similarly, `git tag -s` signs a tag; it has nothing to do with the sign-off trailer. ## Where the line lives in the message Sign-off belongs in the trailer block: the final paragraph of the message, made up of `Key: value` lines, separated from the body by a blank line. Other common trailers share that block — `Co-authored-by:`, `Reviewed-by:`, `Acked-by:`, `Reported-by:`. Because it is a well-formed trailer, tooling can read it: `git log --format='%(trailers:key=Signed-off-by,valueonly)'` extracts the values, and `git interpret-trailers` can add or normalise them programmatically. ## Adding it after the fact If you forget on the last commit, `git commit --amend -s` fixes it. For a whole branch of commits, `git rebase --signoff <upstream>` replays each commit adding the trailer — remember this rewrites every commit, producing new hashes, so only do it on a branch you have not shared, or expect to force-push it. A maintainer applying an emailed patch can add their own sign-off with `git am -s`, which is how a chain of custody through several people ends up with several Signed-off-by lines in order. There is also a `format.signOff` configuration boolean that makes `git format-patch` add the trailer by default. Git's own documentation cautions against enabling it blindly: adding the line is meant to be a conscious act, because it is a statement about rights, not a formatting preference. ## How projects enforce it Enforcement is a policy layer on top of Git. Reviewers may simply refuse a contribution without it. On a server you control, an `update` or `pre-receive` hook can walk the pushed commits, read the trailers, and reject the push when one is missing — that is the Git-native mechanism. Many projects additionally require that the email in the sign-off match the commit's author email, which catches copy-pasted trailers from someone else's patch. ## Practical mistakes The usual failures are: signing off only the tip commit of a multi-commit series when the policy applies to every commit; a mismatch between the sign-off address and the author address after changing `user.email`; and putting the line in the middle of the body, where trailer parsers will not see it.

  • Does the Signed-off-by trailer prove who wrote the commit?
    No. It is unverified text produced from your local `user.name` and `user.email`; anyone can type any name into it. It is a certification of rights, not authentication. Cryptographic provenance requires signing the commit itself with `git commit -S`, which is a separate mechanism.
  • How do you add sign-off to every commit on a branch you already made?
    `git rebase --signoff <upstream>` replays each commit in the range and appends the trailer. Because every commit is rewritten, all hashes change, so do it before sharing the branch, or be ready to force-push and warn anyone who has fetched it.
  • Why do multiple Signed-off-by lines sometimes appear on one commit?
    They record a chain of custody. The author signs off, and each person who forwards or applies the patch can add their own with `git am -s`. In DCO terms each signer certifies that they had the right to pass the change along, in the order the lines appear.

saying these in an interview costs you the question

  • Says Signed-off-by cryptographically verifies who wrote the commit
  • Confuses git commit -s with git commit -S GPG signing
  • Thinks -s makes all future commits signed off automatically
  • Claims the hosting platform adds the trailer, not Git
  • Treats the trailer as a formatting habit with no licensing meaning

context