Matthew
Matthew

Reputation: 29256

In git, how do I create a single patch for the last 2+ revisions?

I would like to create a patch for the last 2 revisions.

git format-patch -2

gives me 2 patch files, one for each revision

git format-patch HEAD~2..HEAD

gives the same thing.

git format-patch -1 HEAD~2..HEAD

gives a single file, but only contains changes for the last revision.

Is there any way to do this in git?

Upvotes: 74

Views: 55377

Answers (4)

VonC
VonC

Reputation: 1328312

With Git 2.20 (Q4 2018) and more, you now have:

  • git format-patch --interdiff.
  • git format-patch --rangediff.

Both are helping to explain the difference between this version and the previous attempt in the cover letter (or after the tree-dashes as a comment).

format-patch: allow --interdiff / --rangediff to apply to a lone-patch

When submitting a revised version of a patch or series, it can be helpful (to reviewers) to include a summary of changes since the previous attempt in the form of an interdiff, typically in the cover letter.
However, it is occasionally useful, despite making for a noisy read, to insert an interdiff or a rangediff into the commentary section of the lone patch of a 1-patch series.

See commit ee6cbf7, commit 3fcc7a2, commit 3b02641, commit 5ac290f, commit 126facf, commit fa5b7ea (22 Jul 2018) by Eric Sunshine (sunshineco).
(Merged by Junio C Hamano -- gitster -- in commit 688cb1c, 17 Sep 2018)

Therefore, extend "git format-patch --interdiff=<prev>" to insert an interdiff into the commentary section of a lone patch rather than requiring a cover letter.
The interdiff is indented to avoid confusing git-am and human readers into considering it part of the patch proper.

See commit 40ce416, commit 8631bf1, commit 4ee9968, commit 2e6fd71, commit 31e2617, commit 73a834e, commit 2566865, commit 87f1b2d (22 Jul 2018) by Eric Sunshine (sunshineco).
(Merged by Junio C Hamano -- gitster -- in commit 881c019, 17 Sep 2018)

Therefore, extend "git format-patch --range-diff=<refspec>" to insert a range-diff into the commentary section of a lone patch rather than requiring a cover letter.


With Git 2.46 (Q3 2024), batch 15, "git format-patch --interdiff"(man) for multi-patch series learned to turn on cover letters automatically (unless told never to enable cover letter with "--no-cover-letter" and such).

See commit f96c385, commit bc665cd (07 Jun 2024) by Rubén Justo (rjusto).
(Merged by Junio C Hamano -- gitster -- in commit 9071453, 20 Jun 2024)

format-patch: assume --cover-letter for diff in multi-patch series

Signed-off-by: Rubén Justo

When we deal with a multi-patch series in git-format-patch(1), if we see --interdiff or --range-diff but no --cover-letter, we return with an error, saying:

fatal: --range-diff requires --cover-letter or single patch

or:

fatal: --interdiff requires --cover-letter or single patch

This makes sense because the cover-letter is where we place the diff from the previous version.

However, considering that format-patch generates a multi-patch as needed, let's adopt a similar "cover as necessary" approach when using --interdiff or --range-diff.

Therefore, relax the requirement for an explicit --cover-letter in a multi-patch series when the user says --iterdiff or --range-diff.

Still, if only to return the error, respect "format.coverLetter=no" and --no-cover-letter.

Upvotes: 5

JC Brand
JC Brand

Reputation: 2692

Use the --stdout option and then cat it to a file.

Like so:

git format-patch HEAD~2..HEAD --stdout > changes.patch

This will keep the per-commit metadata.

Upvotes: 73

William Pursell
William Pursell

Reputation: 212544

You could do something like:

$ git checkout -b tmp
$ git reset HEAD~2
$ git commit -a

The commit to branch tmp will be the same as the 2 individual commits.

Upvotes: -2

Tobu
Tobu

Reputation: 25436

git diff HEAD~2..HEAD > my-patch.diff

It won't have any of format-patch's per-commit metadata, though.

Upvotes: 73

Related Questions