8

I want to get patches for all commits that are made to a file/folder.

I can get the list of commit-id through git log --format="%H"-- path/to/folder

Is there a way i can get generate patches from this list.

[edit]:

below code partly solves my problem

for c in `git log --format="%H" -- path/to/file`;do git format-patch "$c^1".."$c" -o patches ; done

since format-patch is called individually, i will get patches all numbered 0001-commit-text.patch where i will lose the order of patches. Is there any better solutions

prahlad venkata
  • 351
  • 2
  • 6

4 Answers4

6

You can try git diff initial_commit_id..latest_commit_id > changes.patch

This is based on this article: https://www.lullabot.com/articles/git-best-practices-upgrading-the-patch-process

For example:

git diff ab0b3a55de5..6f5dbbc4187b97

Update: if you provide the path to the specific file as an argument to format-patch it'll only create patches for the commits with changes to that file. So no need for the loop and one-by-one invocation of format-patch. See example in format-patch for a single file

So try this:

get format-patch from..to -o patches /path/to/file 
kofman
  • 108
  • 6
  • This will give a single patch. I would like to have patches seperate. – prahlad venkata Jan 23 '18 at 11:24
  • Then I guess that's been answered here: https://stackoverflow.com/questions/6658313/generate-a-git-patch-for-a-specific-commit – kofman Jan 23 '18 at 11:32
  • All the answer will be applicable only if i want a range of commits. not if my commits are at random points in the log. – prahlad venkata Jan 23 '18 at 11:38
  • if you provide the path to the specific file as an argument to format-patch it'll only create patches for the commits with changes to that file. So no need for the loop and one-by-one invocation of format-patch. See example in https://stackoverflow.com/questions/7885075/format-patch-for-a-single-file – kofman Jan 23 '18 at 11:52
6

Come up with the below shell script to achieve this. any other answers are welcome.

#!/bin/bash
COUNTER=1;
for c in `git log --format="%H" --reverse -- path/to/file`;do
    git format-patch --start-number=$COUNTER "$c^1".."$c" -o patches
    let COUNTER=COUNTER+1
done
prahlad venkata
  • 351
  • 2
  • 6
4

My slight improvization (just composed) by using only git:

git format-patch $(git rev-list --max-parents=0 HEAD)..HEAD -- path/to/file

Might not work if the rev-list --max-parents returns more than one commit. Used idea from that post:

How to show first commit by 'git log'?

saulius2
  • 249
  • 4
  • 8
  • 1
    I tested on a Linux kernel git repo cloned on a Debian 10 host. Works as advertised. +1. – Jonathan Ben-Avraham Mar 30 '22 at 15:04
  • 1
    Caveat, will "fail", not get the first commit, if the file you want was in the _very first_ commit in the repo. – sastorsl May 30 '23 at 07:14
  • 1
    Can use `git format-patch --root` (without any SHA) for cases where the file is in the initial / very first commit. Ref https://stackoverflow.com/questions/11197812/how-to-use-git-format-patch-on-initial-commit – sastorsl May 30 '23 at 07:22
  • @sastorsl, nice observation! Replacing the range with this switch in my command generates the complete patch set (even if the file belongs to the initial commit in repository). Just check that. You should post this as an answer, I think :) – saulius2 May 30 '23 at 08:47
0

Building on the rest of the answers.

If you want all the commits for a file which is in the initial / very first commit you must omit the SHA. Even <SHA>^1 will not "work" in this case.

git format-patch --root

Refering to How to use git format-patch on initial commit

sastorsl
  • 2,015
  • 1
  • 16
  • 17