Patching with "git format-patch" and "git am"

Posted on by Michael Orr

Why Patch?

Sometimes you just have to do it live! Sometimes a fix is so crucial that you head directly to the production server, edit the code, save the file, and restart the server. It's not an ideal situation but it happens. Most of the time, the fix is pretty small and you can just go to your local repository after things are fixed on the live server and remake the changes to your code base and commit them. When the fix is more complex, you may want to commit the code on your production server and create a patch to apply your changes to the code in the repository. If your repository is in git, here are some instructions on how to use 'git format-patch' and 'git am' to bring everything back in sync.

Patching can be useful for more than just hot fixes.  Sometimes you don't need to work on a live server, you just want to and by "live" I mean on an actual server just like the production box instead of your local machine. This can be very useful for anything from starting a new project to working on v2 of an enormous live system. Rather than mess with a local copy of the code (and trying to get some advanced technology working on your mac) or trying to configure a virtual machine (or several) to let you interact with a duplicate environment of what your production server will be, you can just build the server, deploy to it once and edit in place. You don't have to worry about differences between when your development and production environments when you are working on an exact copy of the production system. You can just make changes to the code and restart the application to see them. Of course you'll want to commit your work regularly and make sure to get it into the repository. You can do this by creating patches with git as well.

Can you follow these instructions?

Go to your local repository, make sure you are on your master branch, 'git pull' to make sure you have all recent changes and view 'git log' to find the ID of your latest commit. Save this value for later. Hopefully all of these commits have already been deployed to production, let's check. Go to the production server and go into your project's current folder and view 'git log'. If your production server has all of the same commits then you are good to go. It is okay if the production server has more commits because you've already committed the new code on the production server, as long as they are all after the commits that are in your local repository. If you have extra commits on the master branch of your local repository these instructions will not work exactly as printed, take some time to read up on git am and git format-patch though and you can figure it out. (Try keeping your work off the master branch and only merge your working branches back into the master when you are ready to deploy.)

Patching Instructions

Step 1) Commit Code on Production Box First, go ahead and commit the changes you made to the code on the deploy branch on the production server if you haven't already. You can commit it all at once, or split it into multiple commits if that makes more sense for the changes you have made. For the sake of this demo we'll say that you put everything into one commit with the commit message "my fix" which is a horrible commit message but works great for example purposes.

git commit -m "my fix"

Step 2) Create Patches On the production server go into your application's current directory. Using the ID of the last commit you have in your local repository run the command to create the patches.

git format-patch LAST_LOCAL_COMMIT_ID
(*replacing the LAST_LOCAL_COMMIT_ID with the value saved before
 -- should look like 48aa02be08fd5f2ed641b50f5611b968ff2699a7)

This tells git to create a patch file for each commit that happened since the specified commit. With our one commit, this would create one file named '0001-my-fix.patch'

Step 3) Get Patches Now download the patches to your local computer with your protocol of choice (scp, sftp, etc) and put them in the root directory of your local repository.

Step 4) Run Patches Go into your local repository and run the patches

git am -s 0001-my-fix.patch
(*replacing 0001-my-fix.patch with the correct file name)

Path files tend to be named starting with ordered numbers (0001, 0002, etc) so if you made multiple commits on the production server, you may need to run multiple patch files. You can run them each individually or you can run them all at once like so

git am -s 0*
(*assuming no other files in the directory start with a 0 [zero])

Step 5) Push Patched Commits to Remote Branch

Now the commits have been applied to your local repository and you need to push them to the remote.

git push origin master

Ta-da! Now the repository is back in sync with the code actually running on the server.

Enhanced by Zemanta
comments powered by Disqus