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.
Some additional info:
cp -r
, rm -rf .git and-some-other-files
and a new git init
.
I found a way to do this in the way I wanted.
git remote add otherrepo ../otherrepo
git fetch otherrepo
# If you want to fetch lfs objects as well
git lfs fetch --all otherrepo
# -X subtree: Or you will get a lot of merge-conflicts, some of them with empty lines.
# --signoff: To add signoff on the merge-commit (not the merged commits)
# --allow-unrelated-histories: This is the main trick!
git merge -X subtree --signoff --allow-unrelated-histories otherrepo/main
The whole history and everything works as it should. The merge-commit contains what is merged, and history, graph, authors and everything looks good.