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.

  • Git format-patch vs git log -p
  • Reapply Git commits from copied fork repository to original repository
  • Git auto patch submodule
  • How do I make a git patch from multiple commits at different points in history?
  • Ignore space difference in context line when applying git patch
  • Create a git patch from the changes in the current working directory
  • Is it possible to set committer to same person who is defined in patch as author when using git am?
  • What does “1 line adds whitespace errors” mean when applying a patch?
  • 2 Solutions collect form web for “How can I generate/apply git patches only for commits that alter specific files”

    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)

    if the two repositories have common history (they are both forked from the same repository, but have evolved differently), you could use cherry-picking to import commits selectively from one branch to another.

    create a local repository with two remotes (your two diverging repositories)

    find the commits in repositoryA that touch certain files

     $ git checkout repoA/master
     $ git log sub/dir/ectory
     a34256f ...
    

    cherry-pick those commits into the branch of repositoryB

     git checkout repoB/master
     git cherry-pick a34256f
    
    Git Baby is a git and github fan, let's start git clone.