gitgit-diffgit-patch

How can I generate/apply git patches only for commits that alter specific files


I have two git repos that are forks of each other and I need to occasionally import commits from one to the other.

For example:

git-repo1 has this directory structure:

repo1/project1/src

repo1/project2/src

while git-repo2 has the following directory structure:

repo2/src/

What I'd like to do is take a series of commits and generate patches only for commits that altered files within a particular subdirectory (say repo1/project1/src) and ignore all commits that only alter files anywhere else.

Or alternatively, generate patches for all the commits, but only apply the patch IF it alters files within a particular directory.

I need to preserve the metadata about the commits so playing with git diff doesn't seem like a viable option.

The directory structure between the forked git repos differs.

Is there a straight forward way to do this?

UPDATE1

I see this question (How to apply a git patch from one repository to another?) in terms of coping with differing directory structures.

But what if the patch speaks of modifying files that simply do not exist? I would like to ignore such changes.


Solution

  • git rev-list --reverseseries-- repo1/project1/src/ \
    | xargs -I@ git format-patch --stdout @^! >mystuff.patch

    will spit the commits in series that affect that subdirectory into mystuff.patch

    Then,

    cat >mystuff.sed <<\EOD
    /^(From [0-9a-f]{40}|diff --git )/!{H;$!d}
    x
    /^From /b
    ${h;s,.*--,--,;x}
    \,^diff[^\n]* [ab]/repo1/project1/src/,!{$!d;x;b}
    ${p;x}
    EOD
    

    and

    sed -Ef mystuff.sed mystuff.patch >justmystuff.patch
    

    will strip out all the hunks outside that directory. You can apply with

    git am justmystuff.patch
    

    with -pn and --directory=new/path/to as desired.

    (edit: EOD --> \EOD so the cat above doesn't try to substitute)