Can git merge
mostly ignore some file deletions and file renames between two branches, while merging only subsequent changes to the files that were renamed (and ignoring changes to the files that were deleted in one branch), back and forth between the two branches?
Thus, I would like to be able to merge changes both ways between two branches. The development
branch is initially a copy of the master
branch, but with numerous deletions and file renames.
This last point is what breaks the method I tried:
master
, I did a merge -s ours development
(no file changed).development
, I did merge -s ours master
(no file changed).I was hoping that this would somehow define some starting point, so that any subsequent git merge
from any of the branches would only apply the changes made since the two merges above. Instead, the merge results in the branches becoming identical (as far as I can see), whereas I need to keep the development
branch lean and clean (fewer files, better file locations), and the master
branch complete (all the files, in locations appropriate for deployment)—while being able to import all changes (after the initial deletions and renames) both ways. Can this be done with git?
The most commonly used strategies are Fast Forward Merge and Recursive Merge. In this most commonly used merge strategy, history is just one straight line. When you create a branch, make some commits in that branch, the time you're ready to merge, there is no new merge on the master.
Recursive. This operates on two heads. Recursive is the default merge strategy when pulling or merging one branch. Additionally this can detect and handle merges involving renames, but currently cannot make use of detected copies.
After carefully reviewing the documentation at https://www.kernel.org/pub/software/scm/git/docs/git-merge.html:
The main idea of merge is, in a sense, to actually try to make the current branch identical to another branch or a specific commit in another branch, by incorporating changes that happened since they diverged
from one of them into the other, which is exactly the behavior you are getting. Keyword being "diverged". You can specify which commit to merge 'up to' but not a commit since when you want to merge, merge always goes back in history up to the moment the two threads where identical or to the beginning of them, then replays the changes that happened in the merge-source again on the merge-target. This part of the behavior (where it first tries to find a common ancestor for both points and replay the changes from that point) is not changeable by any option in the merge command, no merge-strategy can change that. ours
instructs it to ignore changes from other branches and always end up having the current branch's tree as the end result. recursive -Xours
makes it merge and favor the current branch's version in conflicts, but both first go back to the common point or to the beginning of history for the merge source.
What I understood is this: you have a project with say a large tree and lots of files. While developing features you want to concentrate on those files you will be modifying so you delete some files, rearrange them to be easier to handle, work on them, then want to integrate the changes into the master branch. This is simply not what merge is intended to do obviously. There's no option for the command that simply tells it to start the merge from a specific point forwards
However, you might, with a small change of strategy, achieve the desired effect with a combination of git format-patch
and git apply
/git am
First, when the branches are identical, in development
, remove all unnecessary files but keep the structure. Start working on the files you want.
When the changes are ready to go to master, let's say you have made 5 commits by then. Execute something like:
git format patch -5 --stdout > /some_folder/patchname.patch
Now you can checkout master and apply the patch you created in /some_folder/patchname.patch using something like
git am --signoff < /some_folder/patchname.patch
first you might wanna check if everything will be fine by running:
git apply --check /some_folder/patchname.patch
Another way is to use git cherry-pick
(see https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html) to manually choose what commits you want to transfer between both of branches.
Hope this helps in any way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With