If I git checkout develop -- A, won't that also cause a nasty merge conflict in the future?
No, not by itself it won't. Merge works by comparing each tip against the merge base and then comparing the two sets of changes. If both branches make the same changes, there's no conflict.
Other changes, on either branch, to or too near to lines changed in common on both branches, can appear as conflicts. The way to forestall those is to give git an accurate merge base by recording a merge from the common content.
# merging master and develop, but there are common changes and
# also changes that conflict only with those common changes.
# supply git's merge with the common changes as part of the base,
# so it will see that it needs to resolve only those other changes
# check out the current merge base
git checkout $(git merge-base master develop)
# make the changes you're merging
git checkout develop -- file_A
git commit -m "cherrypicking file_A as of develop @ $(git rev-parse develop)"
# (for ensuite)
base=$(git rev-parse HEAD)
# record that both branches have those changes
git checkout develop
git merge -s ours $base -m "recording common content from previous cherry-picks"
git checkout master
git merge -s ours $base -m "recording common content from previous cherry-picks"
# and now this merge will get an accurate base:
git merge develop
Now: the only effect of those $base
merges is to record the common content as ancestral to both branch tips, giving the merge from develop
to master
an accurate base from which to resolve the other changes.
The new commit gets history back in line with the practice given in a widely-used successful git branching model.
If, in terms of how your team interprets commits, leaving the origins of that common content recorded only in the text of commit messages is preferable, git's got that covered too. Instead of recording the ancestry permanently, via the checkouts and merges after the base
assignment above, you can also
echo $(git rev-parse master master~) $base > .git/info/grafts
echo $(git rev-parse develop develop~) $base >>.git/info/grafts
git checkout master
git merge develop
# later, whenever you want -- the ancestry above is strictly repo-local
rm .git/info/grafts
Ancestry recorded in .git/info/grafts
is repo-local. Your merge commands will see it, and the result will be correct. The only downside to this is since the base isn't actually recorded others will have the same trouble repeating it -- very unlikely unless you're doing criss-cross merges or also cherrypicking to other branches.