5

I have a text file committed and pushed to the master branch. My co-worker made a separate branch from the master branch and made some changes in the file - he made a revision of the text. The changes are made in a single commit and in a single file.

Now, I want to merge some of his changes to the original file in the master branch. But! I do not want to accept everything, just some of the changes.

The changes are made on various lines of the same file: some lines changed, some added, some removed in the revision. How can I achieve that?

If I understand the git correctly, simple merge of the revision branch to the master will not detect conflicts as I have made no changes in the master branch. Also, the merge would just apply all the changes made in the branch/commit. However, I want to apply only changes made on line (let's say) #20, 50, 69. I want to ignore the other changes as I do not agree with them.

How to make the git to arise conflicts on all changed files to enable me to select if I want to accept the change? I need some interactive way.

For instance, in MS Word, it is possible to track the changes. Then, each of the changes may be accepted (the new version is taken and the older removed) or rejected (the old version is kept and the change is thrown away). Then, the change is no longer highlighted.

I am using TortoiseGit application on MS Windows 10, running on git version 1.9.5.msysgit.1 . Therefore, if there is a way using the client I would prefer it.

Yue Lin Ho
  • 2,945
  • 26
  • 36
Sharg
  • 155
  • 3
  • 9
  • Possible duplicate of [How do you merge selective files with git-merge?](http://stackoverflow.com/questions/449541/how-do-you-merge-selective-files-with-git-merge) – Greg Burghardt Mar 29 '16 at 16:39

3 Answers3

4

Here is something that worked for me; assuming that the changes you want to import are on the testbranch branch (and assuming the file you want to operate on is README):

  • Start on the master branch:

    $ git checkout master
    
  • Use the --patch argument to git checkout to bring in the changes from the other branch:

    $ git checkout --patch testbranch README
    

    This will bring up the same interface as git add -p, which will let you selectively accept or skip chunks.

larsks
  • 277,717
  • 41
  • 399
  • 399
2

How to make git ... enable me to select if I want to accept the change?

git merge --no-commit

will do this - the docs say:

... perform the merge but pretend the merge failed and do not autocommit, to give the user a chance to inspect and further tweak the merge result before committing.

which will do what asked for.

It may not, however, be what you want. The result will be this state:

  B        <sharg
 / \
A---B'--C' <master
 \     /
  C --/    <coworker

where C' doesn't really contain all the changes in C, but you can't merge it again because you lied to git. Is that ok?

Useless
  • 64,155
  • 6
  • 88
  • 132
  • 1
    I am afraid this would mean a lot of manual corrections and editations after the merge. I would prefer a way to interactively decide about each change if I want to keep my version or the coworkers. Important is that the changes are made on lines of the same file, not on various files. – Sharg Mar 29 '16 at 16:48
  • Once you have the un-committed change, you can use `git add -p` to prompt you for which version of every hunk (and line if necessary) to keep, or use your preferred (maybe graphical) mergetool. – Useless Mar 29 '16 at 16:51
  • Actually, this approach really did exactly what I needed. I had merged the co-worker branch into mine without commit (`--no-commit`) and used _diff with previous version_. I got the changes with the possibility to edit the current working tree. I made the changes as I needed and then commited and pushed. Thank you very much for your suggestion. – Sharg Apr 02 '16 at 14:36
1

Assuming were talking about a single commit, you need to take the commit thats been submitted, uncommit it, and then do use interactive staging to selectively chose which changes to accept. So first go ahead and merge in their changes. Then...

git reset HEAD^
git add --interactive

This will kick you into a menu system. Type "5" then hit enter, this opens up the patching process. The the files that have been changed will show up on a numbered list. Type the numbers you want to consider for acceptance. So lets say there are 5 files and you want 1, 2, 3 and 5. You can type it comma separated or do 1-3,5. Once you've types the file numbers you want hit enter. The interface gives you a chance to double check if you want to add any other files. Type any additional numbers. When you're ready to start inspecting changes, leave the line blank and hit enter.

Now its going to walk you through each "hunk" of changes that git can find. Type "h" to see the list of commands. "y" means you accept a change, "n" means you don't accept a change. If a hunk of changes is too large, you can try to break it into smaller hunks with the "s" command - it can only do so much though.

Once you've gone through all the files, you'll be back at the menu system. Type "q" and hit enter to quite. Use git status to check what's been staged.

Now you can go ahead and commit the changes knowing that only the parts you accepted will be included.

eddiemoya
  • 6,713
  • 1
  • 24
  • 34