Example: You have a branch `refactor` that is quite different from `master`. You can't merge all of the commits, or even every hunk in any single commit or master will break, but you have made a lot of improvements there that you would like to bring over to master. _Note: This will not preserve the original change authors. Only use if necessary, or if you don't mind losing that information, or if you are only merging your own work._ On master: > git co -b temp On temp: > git merge --no-commit --no-ff refactor … which stages everything, so: > git reset head Then begin adding the pieces you want: > git add --interactive *The following is from an actual merge.* staged unstaged path 1: unchanged +1/-1 deploy_settings.py 2: unchanged +4/-3 requirements.txt 3: unchanged +2/-1 settings/defaults.py 4: unchanged +1/-1 settings/production.py.example *** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now> Choose `p` for patch. staged unstaged path 1: unchanged +1/-1 deploy_settings.py 2: unchanged +4/-3 requirements.txt 3: unchanged +2/-1 settings/defaults.py 4: unchanged +1/-1 settings/production.py.example Patch update>> Enter the number next to the file you want to process first. You can keep entering numbers until you've selected all the files, or you can do them one at a time. An asterisk will appear next to the files you select. When you are finished selecting files, press 'enter' without entering a number (or anything) to continue to the next step. You will see a single diff hunk and it will ask you whether to stage it or not. diff --git a/deploy_settings.py b/deploy_settings.py index 9b110f4..c5b228e 100644 --- a/deploy_settings.py +++ b/deploy_settings.py @@ -4,7 +4,7 @@ This file holds the Fabric deployment settings for this project from fabric.state import env #env.project = 'my_project' #The name of this project -#env.repo_base = 'git@git.oldsite.com:%s.git' % env.project +#env.repo_base = 'git@git.newsite.com:%s.git' % env.project Stage this hunk [y,n,q,a,d,/,e,?]? Enter `y` to stage or `n` to skip. This will go on for every diff hunk in the selected files until you get back to: *** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now> You can enter `s` to see what you changed staged unstaged path 1: unchanged +1/-1 deploy_settings.py 2: +4/-3 nothing requirements.txt 3: +2/-1 nothing settings/defaults.py 4: unchanged +1/-1 settings/production.py.example *** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help What now> You can quit now, so enter `q`, Then do some status and diff commands to explore the staged vs unstaged changes and make sure it looks like you expected. Don't forget to `git add` any untracked files as appropriate. Commit the staged changes: > git commit -m "merged selected patches from refactor branch" # don't do commit -a here… you only want to commit the staged changes Revert the unstaged changes > git checkout . And finally, merge to master: > git checkout master > git merge temp > git branch -D temp