Phantom007
Phantom007

Reputation: 2249

how to merge specific files in git

Suppose I have a project on MASTER branch with 100s of php files. To do a bug fixing in the project, i create a separate branch

git checkout -b bugfix

Then after fixing the bug in 3 files (for eg index.php, register.php and login.php), i merge it in the master branch

git checkout master
git merge bugfix

The above code will merge all the 3 files i made changes, but is there anyway that i can force GIT to merge only 2 files, say login.php and register.php only?

Upvotes: 13

Views: 11144

Answers (4)

Mehrad
Mehrad

Reputation: 3839

There are two approaches:


Approach 01

The following solution is adopted from a blog post

It turned out that checkout can also be helpful in this matter. You can simply callout (checkout) those specific files from another branch:

# switch to the branch you want to be your merge destination
git checkout master

# checkout specific files from specific branch (e.g bugfix)
# format: git checkout <source branch> <file.1> <file.2> ... <file.N>
git checkout bugfix login.php register.php

# check the status
git status

# merge them in
git commit -m "your merge comment"

Approach 02

This is an easy alternative approach, but it only works if you have one commit per file (meaning every time you have changed a file, you have made one commit and then have moved to the next file). In this case you can simply bring those specific commits to the other branch (in your case the master branch):

# get which commit you want to take to the other branch (first 7 characters will do)
git log

# switch to the branch you want to be your merge destination
git checkout master

# bring specific commit to this branch (replace the 63344f2 with your own 7 character commit ID)
git cherry-pick 63344f2

Upvotes: 15

axiac
axiac

Reputation: 72425

You can simulate the behaviour you want but what happens with the changes you did on the third file?

The changes on the third file remain in the commits on the branch but they will not be present in the merged commit, it's like the file was not modified on the branch at all.

This is how you can do it:

git checkout master
git merge bugfix --no-commit

The --no-commit option tells git to merge the files but stop before committing them. You can now inspect the files, change them, do whatever you want. In order to cancel the changes you did on index.php you can run:

git checkout master -- index.php

Running git status you can see that index.php does not appear as modified any more (neither in the index or in the working tree). You can now git commit and that's all.

Upvotes: 1

hjpotter92
hjpotter92

Reputation: 80653

No, there doesn't exist a direct way. Though; you can select the files from branch you want to merge and overwrite them over existing ones in master branch. The commands in order shall be:

git checkout master
git show bugfix:login.php > login.php
git show bugfix:register.php > register.php
git add .
git commit -m "Select login and register from branch/bugfix"

Ok, the above method will "destroy" file history. There is an old discussion about the same in this mailing list.

From a technical standpoint, the thing that makes history matter (and why "set of commits in date order" is useless) is because it gives us a COMMON ANCESTOR! And that is the only thing that matters.

Now, what is fundamentally wrong with doing per-file history?

Now, if you've followed this argument, you should go "Aaahh! Obvious!".

Ignoring a whole lot of paragraphs; you'll find the workaround:

git diff commit..othercommit filename | git-apply --index && git commit

In your case, commit = hash of you HEAD/master branch; and othercommit = hash of bugfix branch.

Upvotes: 0

CB Bailey
CB Bailey

Reputation: 793369

There is no way to record a partial merge in Git, all merges must merge the entire root trees of all the commits being merged.

You can of course choose to resolve that merge by choosing the unchanged copy of one the files from one of the parents, but this is still a "full" merge and the changes in that file will be considered to have been merged when it comes to subsequent rebases or merges between the branches involved.

Upvotes: 2

Related Questions