Creating and Applying Git Patch Files
I was recently reviewing code on a project where I didn’t have write access, and wanted to suggest a small code change to the team. As I couldn’t send a pull request to make the change, I had to look into how to create a patch that I could then email.
Creating a patch
In this example, we will add a line to a Rails project’s Gemfile
.
When we add a gem 'rspec-rails'
line, git diff
looks like this:
diff --git a/Gemfile b/Gemfile
index c661619..989efe8 100644
--- a/Gemfile
+++ b/Gemfile
@@ -24,6 +24,7 @@ group :development do
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
+ gem 'rspec-rails'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
We can save this as a patch file, without committing the code.
git diff > add-rspec.patch
Now let’s look at what happens when you add a new file to the working directory.
Create a notes.txt
, add a couple of lines there, and run git diff
.
You will notice that the new file is not present in the diff.
To get it, you will need to stage all the files and then run git diff --cached
.
git add .
git diff --cached > add-rspec.patch
Now the patch looks like:
diff --git a/Gemfile b/Gemfile
index c661619..989efe8 100644
--- a/Gemfile
+++ b/Gemfile
@@ -24,6 +24,7 @@ group :development do
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
+ gem 'rspec-rails'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..3a5e395
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,2 @@
+We are using rspec for testing.
+Rspec is the best.
Binary patches
What if the new file we added was a binary file?
This time we will add a logo.jpeg
file and stage it.
We can use the --binary
option.
git add .
git diff --staged --binary > mypatch.patch
The patch file will look like this:
diff --git a/Gemfile b/Gemfile
index c661619..989efe8 100644
--- a/Gemfile
+++ b/Gemfile
@@ -24,6 +24,7 @@ group :development do
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
+ gem 'rspec-rails'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
diff --git a/app/assets/images/logo.jpeg b/app/assets/images/logo.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..064fa38be3ecd426a3c8977ed43df627c6f6f229
GIT binary patch
literal 50966
zcmbT6RZtv2x1a}i2o6CLAUMHc&=7(LcbCE49fAa#;4l!}9R?j7La@Qz-3jh4+5Goz
z?N;s6?w*#Hmg=v%T8{i(_`3mkBQGr{4M0Eu01*Bqz~5JZu%w!lgod)35UrItyREZ@
...a few hundred lines like this...
z_i{8b#lS>d00-gE<y-oK1ih6&zzl1$iJXXs289`1p0s}urC+&SB#PYPr9*_xMg=~A
v97b_p1peNmKNs|WZ3Z9xD7de_7qxsD`+5QY01Jai0{XNQKl(o6fIt7)0U9~_
literal 0
HcmV?d00001
Creating patches from commits
Suppose you have created a new branch and made two commits -
one for adding rspec to Gemfile, and another for the notes file.
You can create a patch file for the commits by using git format-patch
.
$ git format-patch master
0001-Add-rspec-to-gemfile.patch
0002-Add-notes-file.patch
This will create a patch file for each commit. Let’s take a look at what one of the files looks like:
From 57c9101b014623049a6bb75ee43505058d494077 Mon Sep 17 00:00:00 2001
From: Nithin Bekal <nithin@example.com>
Date: Sun, 12 Feb 2017 13:31:03 +0530
Subject: [PATCH 1/2] Add rspec to gemfile
---
Gemfile | 1 +
1 file changed, 1 insertion(+)
diff --git a/Gemfile b/Gemfile
index c661619..989efe8 100644
--- a/Gemfile
+++ b/Gemfile
@@ -24,6 +24,7 @@ group :development do
gem 'listen', '~> 3.0.5'
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
+ gem 'rspec-rails'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
--
2.11.1
If you don’t want to create multiple patch files, you can do this:
git format-patch master --stdout > rspec-changes.patch
Applying a patch
Now that we have looked at the different ways to create patches,
let’s see how we can apply a patch file to the working directory.
Let’s checkout a review-rspec-patch
branch from master first.
Now let’s apply one of the patch files we created earlier:
git apply 0001-Add-rspec-to-gemfile.patch
Using git apply
provides the patch as unstaged changes in your branch.
If you want to apply the patches as commits, you can use git am
.
$ git am rspec-changes.patch
Applying: Add rspec to gemfile
Applying: Add notes file
$ git log --oneline
ac9caff Add notes file
f784b22 Add rspec to gemfile
8619310 ...older commits...