Reputation: 249552
I have a git repo with a second repo as a submodule. Both repos have corresponding branches for various features which usually correspond pretty directly, e.g. if the parent repo is on branch A, the submodule will also be on branch A.
In both the parent and the submodule repos, as time goes on more branches are added, and sometimes I merge older branches into later ones, e.g. merge branch A into branch B periodically in both repos, while branch B is also getting new commits which are not in A.
The problem comes when I merge branch A into B for the parent repo after the A submodule was updated. I want to ignore those updates (i.e. I always want to discard submodule updates during merges, otherwise the parent branch B might end up with submodule branch A which is wrong).
I found some instructions for how to always use "ours" when merging files, but it seems ineffective for submodules. Here's how to reproduce the problem with a submodule:
# first command will update your ~/.gitconfig, you may want to undo it later
git config --global merge.ours.driver true
mkdir -p tmp/sub
cd tmp
git init
git commit --allow-empty -m "chore: Initial commit"
echo 'sub merge=ours' >> .gitattributes
git add .gitattributes
git commit -m 'chore: Preserve sub during merges'
mkdir sub
pushd sub
git init
git commit --allow-empty -m "sub: init"
popd
git submodule add ./sub
git commit -m 'add submodule'
git checkout -b demo-prod
pushd sub
echo prod > readme
git add readme
git commit -m 'add prod readme'
popd
git commit sub -m 'sub: add prod readme'
git checkout -
git submodule update
pushd sub
echo master > log
git add log
git commit -m 'add master log'
popd
git commit sub -m 'sub: add master log'
git checkout demo-prod
git merge -
The expected result is an automatic merge, but the actual result is a merge conflict because "sub" has new commits in both branches of the parent repo.
How can I achieve easy merging in such a situation?
Upvotes: 5
Views: 1487
Reputation: 60497
The problem comes when I merge branch A into B for the parent repo after the A submodule was updated. I want to ignore [any branch-A submodule] updates (i.e. I always want to discard submodule updates during merges, otherwise the parent branch B might end up with submodule branch A which is wrong).
When you merge, if a path was changed in the other branch and not touched at all in the local branch Git sees no chance of conflict so it "trivially" takes the other-branch version. This is so far under the radar Git doesn't even see it as an automerge, it runs no merge driver at all for it, so far as I can tell there's nothing to shut off, you can't stop it, …
… which might seem like a flat "can't be done", but this is Git. Anything Git does automatically you can easily fix up afterwards if you like. Either run the merge --no-commit
and git checkout @ path/to/submodule
before committing, or if you forget do git checkout @~ path/to/submodule
and git commit --amend
. Lots of custom workflows can be automated through config settings or hooks, but I think this one is oddball enough you're going to have to script it if you want automation.
Upvotes: 0
Reputation: 1328262
Merging with submodules is tested in t7405-submodule-merge.sh
, and it has always included a merge -s ours
which should do what you want.
(test added in commit f37ae35, Apr. 2009, Git v1.6.2.4)
An actual merge for submodule was discussed in Nov. 2017, for this patch, in commit 6c8647d, Jan. 2018, v2.17.0-rc0, but you should not need it here.
Using the merge strategy "-s ours
" can be too much (in that it ignores all commits from the other branch), but the merge recursive strategy option could help: git merge -X ours
.
Upvotes: 0