Home > other >  Git format-patch and branch conflicts
Git format-patch and branch conflicts

Time:06-30

I need to create patches from one repo (repo-a) and merge them into another (repo-b). These patches needs to contain the commits themself, so I found that git format-patch and git am is a perfect fit.

We are using multiple branches in repo-a and from time to time, files are added from two different branches and merged into main.

git am doesn't like this.. Here is a full example of the problem;

mkdir repo-a; cd repo-a

git init

touch randomfile
git add randomfile
git commit -m "Adding an initial file"

git checkout -b anotherbranch
touch a-file
git add a-file
git commit -m "Adding a-file from anotherbranch"

git checkout main
touch a-file
git add a-file
git commit -m "Adding a-file from main"

git merge anotherbranch

git format-patch -o patches HEAD~2
# patches/0001-Adding-a-file-from-anotherbranch.patch
# patches/0002-Adding-a-file-from-main.patch

cd ..
mkdir repo-b; cd repo-b
git init
cp -r ../repo-a/patches ./

git am patches/*
# Applying: Adding a-file from anotherbranch
# applying to an empty history
# Applying: Adding a-file from main
# error: a-file: already exists in index
# Patch failed at 0002 Adding a-file from main
# hint: Use 'git am --show-current-patch=diff' to see the failed patch
# When you have resolved this problem, run "git am --continue".
# If you prefer to skip this patch, run "git am --skip" instead.
# To restore the original branch and stop patching, run "git am --abort".

The above fails because git already has the file. Normally, git is happy and adds the patches as it should..

Is there a way to do this, and keep the git commits? I don't want to create one big patch, I want the commits as well.

I have read https://git-scm.com/docs/git-format-patch and enter link description here. I have also tried some random options (like --find-copies-harder), but without any luck.

CodePudding user response:

git format-patch is well suited to extract a linear history of commits, but not for merges :

DESCRIPTION
Prepare each non-merge commit with its "patch" ...

[...]
CAVEATS
Note that format-patch will omit merge commits from the output, even if they are part of the requested range.

  • as you can see in your example :

a patch is created for each of your commits on anotherbranch and main, but none for the merge commit, and if you inspect the pacthes, they do not include information to state that they both have the same parent.

This is not enough information to automatically rebuild a history with merges.


There may be several strategies to port commits from repo-a to repo-b while preserving branching and merges, but we would need a bit more context to give you a more precise answer.

For example : one way could be to add repo-a as a remote in repo-b, and use git rebase -r (-r is short for --rebase-merges) or some subcommand of git filter-repo to port complete chunks of history.

CodePudding user response:

git merge anotherbranch

I would rather rebase the branch on top of the target branch (on top of main), before making a patch between that new branch HEAD and main (instead of HEAD~2)

git switch anotherbranch
git rebase main
git format-patch -o patches main
  • Related