geotheory
geotheory

Reputation: 23670

Applying a git patch - basic example

A few questions on this, but none I can find with an unambiguous minimal example. Let's say we want to apply a commit from a particular branch to multiple branches without the legacy commits that preceded the patch commit. E.g.

mkdir cherry_test
cd cherry_test
git init
printf "one\ntwo\nfour\n" > file.txt
git add file.txt; git commit -m 'master: 1'
git branch dev
echo five >> file.txt
git add file.txt; git commit -m 'master: 2'
git checkout dev
echo FIVE >> file.txt
git add file.txt; git commit -m 'dev: 3'
echo SIX >> file.txt
git add file.txt; git commit -m 'dev: 4'

Now lets do a patch to fill the gap (insert the missing line for 'three'):

perl -0777 -i -pe 's/two\nfour/two\nthree\nfour/igs' file.txt
git add file.txt; git commit -m 'dev patch'

At this point I'm unclear how to apply this patch to master without the additional uppercase number commits also patching. Say..

git log
commit d44425da786e161dd066b5db6db8b649b99ba575
author etc
    dev patch

Then this answer suggests we need to use git format-patch -1 d44425da. But then how to merge this with master and other branches? My efforts all seem to result in previous dev commits also merging across.

Upvotes: 1

Views: 6331

Answers (3)

shrishinde
shrishinde

Reputation: 3405

Use -x option if you want to preserve commit message. This way, you can still keep track of the origin of the commit and may avoid merge conflicts in the future.

git checkout <branch>
git cherry-pick -x <commit-id>

naive comment but you have to push your changes after this.

git push origin <branch>

Upvotes: 2

nishantjr
nishantjr

Reputation: 1820

The cherry-pick command creates a patch from a particular commit and it's parent, and applies that commit to the current branch. This should work for you:

git checkout master
git cherry-pick <commit-id>

Git user commands rarely modify the branch pointer of a branch that isn't checked out. So if a command modifies a branch, assume it is the checked-out branch.


So all that business with patch, apply and am is for patching all branches?

Looking at the man pages, these seem to be for sending patches over email, or applying patches from a 'patch' file.

git-format-patch - Prepare patches for e-mail submission
git-am - Apply a series of patches from a mailbox
git-apply - Apply a patch to files and/or to the index


The "man pages" for git are usually a very good resource for finding out how to use a git command. You can view them by running git help cherry-pick or man git cherry-pick or look it up online

Another great article for getting started on git is Git for computer scientists. It explains the (surprisingly simple) inner-workings of git, and once you understand that, working with git becomes quite intuitive.

Upvotes: 2

mkasberg
mkasberg

Reputation: 17332

As nishantjr suggested, you can certainly do it with a cherry-pick.

However, depending on how you do development, I might expect something like this:

Make the hotfix on master:

git checkout master
perl -0777 -i -pe 's/two\nfour/two\nthree\nfour/igs' file.txt 
git add file.txt; git commit -m 'master patch'

Now, merge changes from master into dev. I'll use git merge, but git rebase would work similarly:

git checkout dev
git merge master

For what you're trying to do, you probably shouldn't be using git format-patch, git apply, or git am. Those would only be required if you wanted, for example, to email a patch file to someone else. But that's a pretty rare use case these days since it's much easier to pull from something like github than apply a patch file.

Edit: After merging master, you will have a conflict because you added five in the master branch and FIVE\nSIX in the dev branch. Running git status will provide basic info about how to resolve the conflict. Your file.txt will look something like this:

one
two
three
four
<<<<<<< HEAD
FIVE 
SIX
=======
five
>>>>>>> master

You'll have to edit this file to tell git which changes you want. Since we're on the dev branch, let's keep the dev branch changes. Edit the file to look like this:

one
two
three
four
FIVE 
SIX

Save it, then git add file.txt, then git commit.

Upvotes: 0

Related Questions