Click here to Skip to main content
15,889,200 members
Articles / DevOps / Git
Tip/Trick

Git - Merge Against a Directory from Feature Branch

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
4 Jan 2021GPL33 min read 6.3K   1  
One of the possible ways to merge a folder from feature branch into master
This will give you insight into the merge conflicts that will appear on a large scale troublesome merge against only a selection of the files you chose. It is not intended as THE solution to partially merge a feature branch into master. There is no straightforward way.

Introduction

There are other ways, this is why I choose to do it this way:

I was on a huge SugarCRM project that had been versioned by SVN for years and then ported to Git. It had two major branches (master and feature) developed by lots of people, it all started on SVN.

Recently, they decided to merge the branches and they wanted it done right away. There was time pressure. I asked to cherry-pick all the commits from feature into master, but nobody had heard/used it, so I was denied.

The only way they wanted it done was to pull origin feature on the master branch or the other way around.

I tried both, rebase the feature branch with origin/master and merge feature into master. Git would gobble up for 5 minutes and then break with 140+ unstaged conflicted files. Normal scenario, but 90% of those were unmarked.

A properly marked merge conflict.

<<<<<<< HEAD
        productSave($record_line['id'],$record_line['items']);
    }
}

function productSave($itg_record_line_id, $items) {
=======
        productSave($record_line['id'],$record_line['items'], $parent_type, $entity_id);
    }
}

function productSave($itg_record_line_id, $items, $parent_type, $parent_id) {
>>>>>>> xfeature

There was not enough time to look for WHY the conflicts were unmarked, knowing how even the simplest searches about Git end up. You ask for a banana but what you get is a gorilla holding the banana and the entire jungle. The primary resason that I chose to use this method was those unmarked conflicts.

Unrelated Histories

These Git commands are meant to be executed top down, no matter what I comment in between.

The xmaster branch, a working copy of master:

git checkout master

git pull origin master

git branch xmaster 

The xfeature branch, selected files from the feature branch:

git checkout feature

git pull origin feature

git checkout --orphan xfeature

git reset 

You end up on the new xfeature branch. All the files from feature branch are present. They were staged (added), but I issued the git reset command to unstage them. I don't want any trace of those files, much less of them being deleted.

Now you delete all the files that you don't want to merge with xmaster. That is, you leave only one directory from the gazillion others.

Zip-up xfeature, then merge it on xmaster:

git add .

git commit -m "initial commit"

git checkout xmaster

git merge xfeature --allow-unrelated-histories 

At this point, I got what I wanted, since most of those 140 conflicting files were in the directories that merged, git marked the conflicting areas of those files. For brevity, the examples are shown with only one folder.

After resolving those conflicts, finalize the merge:

git add .

git commit -m "merge xfeature on xmaster" 

Go back to master and overwrite its files/folders from the ones you like on xmaster.

git checkout master

git checkout xmaster modules/Opportunities/*

git commit -m "merge module Opportunities from feature branch onto master" 

Points of Interest

If you use an intelligent IDE that has Git support which tracks all the changes you make to files and offers you colored diff in its editor, you can directly overwrite the files on master from feature branch and work out from there by hand. Then add and commit the changes.

git checkout master

git checkout feature modules/Opportunities/*

git restore --staged . 

Edit the marked changes in the IDE the way you wish.

git add .

git commit -m "changes from feature branch module Opportunities added to master" 

Since I'm more accustomed to working in an text editor and want a black&white textual representation of the conflicts, I used the aforementioned method. As you can see, all of this is based around the --orphan and --allow-unrelated-histories switches.

Another way to merge if you delete a portion of the feature branch would be with ignoring deleted files. As a bonus, you get the history of the branches if everything goes right, but that is another story.

History

  • 4th January, 2021: Initial version

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Macedonia, the Republic of Macedonia, the Republic of
heretic

Comments and Discussions

 
-- There are no messages in this forum --