I have an interesting problem (at least to me.)
I have a master
branch and a feature
branch, which has been parted its way from master
a while ago. Another team keeps updating the master
branch and my team is only working on feature
branch.
The master
branch includes some changes that my team is not interested in. We only care about their app
folder, that's it. Even in the app
folder, we are not interested in everything, only the changes that we think we need. We are not merging our feature
branch into their master
because there is tech-stack changes that we are implementing and only thing we need from them is their JavaScript code.
Meanwhile, we are also making changes in the feature
branch's app
folder. So in the app
folder, they have some changes that we don't have, we have some changes that they don't have. We want to keep all our changes, but only pick some of their changes.
How can I go about merging their master
branch's app
folder into our feature
branch's app
folder? I have been researching for hours, tried some VS Code extensions to preview the difference between the two folders. What I am looking for is an interface where I can Accept or Decline everything that comes from master
branch's `app folder. Although this is my preference, I am open to any suggestions that would solve this problem.
This may sound like a messed up situation but my team lost some members over the past couple of months and the difference between branches grew bigger and bigger every week. Now we want to solve this once and for all.
Thanks for your help.
CodePudding user response:
What I am looking for is an interface where I can Accept or Decline everything that comes from master branch's
app
folder
git checkout -p master app
is crude but stands a decent chance of serving here.
If that's not showing you enough to decide what you want, the next step up is a selective merge with
git diff --merge-base @ master -- app | git apply -3
which will use Git's automerge machinery and leave any overlapping or abutting changes for you to sort out as usual, or you can save the diff to a file and edit it to taste before applying it if you're careful.
CodePudding user response:
There are two ways to do this. The simpler one will keep the changes, but discard any commits they made. The more complex one will preserve commits.
Recommendation
Both of the two methods discussed below have the potential to cause merge conflicts and other headaches down the line, especially as people continue to make changes on the master branch. Furthermore, if you have changes to the app/ folder in the feature branch, directly using git apply may result in your changes being overwritten.
I would strongly recommend merging the master branch into the feature branch via git merge
with no squashing. Given the divergence you mentioned, there may be merge conflicts, but this is OK. Merge conflicts do what you want: they let you choose which changes to accept, and which to reject.
That being said, here are two approaches that are analogous to cherry-picking only a single folder.
Option 1: Discard commits, keep changes
This approach is pretty straight-forward, and it uses a combination of git diff
and git apply
:
git switch feature
git diff feature..master -- app | git apply --index
This will:
- Switch to the feature branch (this is where you'll apply the changes)
- Get all the changes made to the master branch, that aren't on the feature branch.
- Filter only the changes in the
app
directory - Apply the changes via
git apply
- Stage the changes by adding them to the index (this is what the
--index
option does)
The only downside of this approach is that it won't preserve history, or commit messages.
From there, you can commit the changes yourself:
git commit -m "Apply changes made to master branch"
Option 2: Get both commits and changes
This one is a bit more complicated, and it relies on git format-patch
.
git switch feature
git format-patch --stdout feature..master -- app | git am
This will:
- Switch to the feature branch (where you'll apply the changes)
- Get all the changes made to the master branch, that aren't on the feature branch
- Filter by only the changes made in the
app
directory - Format these as a series of patches (containing commit messages, authors, etc)
- Apply all of these patches using git am
Note that depending on the contents of changes, this may result in a failure that you'll have to resolve manually. (It'll alert you to this)