If you are new to Git or to Unix systems, you might have come across Git patch files or git patch commands.
Git patch files are very beneficial : they are used in order to store differences that need to be applied to a file or a group of files on your system.
Git patch is historically linked to the Unix “patch” command that was used in early Unix versions to store differences between files or binaries.
In today’s tutorial, we are going to see how you can create Git patch files.
We are also taking a look at applying Git patch files in order for the changes to be effective.
Create Git Patch Files
To create a Git patch file, you have to use the “git format-patch” command, specify the branch and the target directory where you want your patches to be stored.
$ git format-patch <branch> <options>
So will the format-patch command do when executed?
The “git format-patch” command will check for commits that are in the branch specified but not in the current checked-out branch.
As a consequence, running a “git format-patch” command on your current checkout branch won’t output anything at all.
If you want to see commits differences between the target branch and the current checked out branch, use the “git diff” command and specify the target and the destination branch.
$ git diff --oneline --graph <branch>..<current_branch>
* 391172d (HEAD -> <current_branch>) Commit 2
* 87c800f Commit 1
If you create patches for the destination branch, you will be provided with two separate patch files, one for the first commit and one for the second commit.
For example, let’s say that you have your “master” branch and a “feature” branch that is two commits ahead of your master branch.
When running the “git diff” command, you will be presented with the two commits added in your feature branch.
$ git diff --oneline --graph master..feature
* 391172d (HEAD -> feature) My feature commit 2
* 87c800f My feature commit 1
Now, let’s try creating patch files from commits coming from the master branch.
$ git format-patch master
0001-My-feature-commit-1.patch
0002-My-feature-commit-2.patch
Awesome!
You successfully created two patch files using the “git format-patch” command.
Creating Git Patch Files in a Directory
As you probably noticed from the previous section, patch files were created directory in the directory where the command was run.
This might not be the best thing because the patch files will be seen as untracked files by Git.
$ git status
Untracked files:
(use "git add <file>..." to include in what will be committed)
0001-My-feature-commit-1.patch
0002-My-feature-commit-2.patch
In order to create Git patch files in a given directory, use the “git format-patch” command and provide the “-o” option and the target directory.
$ git format-patch <branch> -o <directory>
Back to our previous example, let’s create Git patch files in a directory named “patches”.
This would give us the following command
$ git format-patch master -o patches
patches/0001-My-feature-commit-1.patch
patches/0002-My-feature-commit-2.patch
In this case, we provided the “git format-patch” will a local directory but you can provide any directory on the filesystem out of your Git repository.
Create Git Patch for Specific Commit
In some cases, you are not interested in all the existing differences between two branches.
You are interested in one or two commits maximum.
You could obviously cherry-pick your Git commits, but we are going to perform the same action using Git patches.
In order to create Git patch file for a specific commit, use the “git format-patch” command with the “-1” option and the commit SHA.
$ git format-patch -1 <commit_sha>
In order to get the commit SHA, you have to use the “git log” command and look for the corresponding commit SHA.
For example, given the example we just used, let’s inspect the differences between master and feature using the “git log” command.
$ git log master..feature
commit 391172da58dbfa27bc995eda538012ae1fbc5383 (HEAD -> feature)
Author: Bob <[email protected]>
Date: Wed Dec 11 16:24:46 2019 -0500
My feature commit 2
commit 87c800f87c09c395237afdb45c98c20259c20152
Author: Bob <[email protected]>
Date: Wed Dec 11 16:03:15 2019 -0500
My feature commit 1
In this case, we are not interested in the second commit (with SHA 391172..) but in the first commit (with SHA 87c800..)
Copy the commit SHA and run the “git format-patch” command again.
You can optionally provide the output directory similarly to the example we provided in the previous section.
$ git format-patch -1 87c800f87c09c395237afdb45c98c20259c20152 -o patches
patches/0001-My-feature-commit-1.patch
Awesome! You successfully created a Git patch file for one single commit on your repository.
Apply Git Patch Files
Now that you have created a patch file from your branch, it is time for you to apply your patch file.
In order to apply a Git patch file, use the “git am” command and specify the Git patch file to be used.
$ git am <patch_file>
Referring to our previous example, make sure to check out to the branch where you want your patch file to be applied.
$ git checkout feature
Switched to branch 'feature'
Your branch is up to date with 'origin/feature'.
Now that you are on your branch, apply your Git patch file with the “git am” command.
$ git am patches/0001-My-feature-commit-1.patch
Applying: My feature commit 1
Now, taking a look at your Git log history, you should see a brand new commit created for your patch operation.
$ git log --oneline --graph
* b1c4c91 (HEAD -> feature) My feature commit 1
When applying a Git patch, Git creates a new commit and starts recording changes from this new commit.
Awesome! You have successfully applied your Git patch file using “git am”.
Git Patch Troubleshooting
In some cases, you might run into errors when trying to apply Git patch files.
Let’s say for example that you have checked out a new branch on your Git repository and tried to apply a Git patch file to this branch.
When applying the Git patch, you are running into those errors.
Git Apply Patch failed : file already exists in index
This case is easy to solve : you tried to apply a Git patch file that contained file creations (say you created two new files in this patch) but the files are already added into your new branch.
In order to see files already stored into your index, use the “git ls-files” command with the “–stage” option.
$ git ls-files --stage <directory>
100644 eaa5fa8755fc20f08d0b3da347a5d1868404e462 0 file.txt
100644 61780798228d17af2d34fce4cfbdf35556832472 0 file2.txt
If your patch was trying to add the “file” and “file2” files into your index, then it will result in the “file already exists in index” error.
To solve this issue, you can simply ignore the error and skip the patch operation.
To skip a Git patch apply operation and ignore conflicts, use “git am” with the “–skip” option.
$ git am --skip
Git Apply Patch failed : error in file
In some cases, you might run into some “merging” errors that may happen when applying a patch.
This is exactly the same error than when trying to merge one branch with another, Git will essentially failed to automatically merge the two branches.
To solve Git apply merging errors, identify the files that are causing problems, edit them, and run the “git am” command with the “–continue” option.
$ git am --continue
Conclusion
In this tutorial, you learnt how you can create Git patch files using the “git format-patch” command.
You learnt that it is possible to create Git patch files for single commits and to apply them to the target branch easily using the “git am” command.
If you are interested in Git or in software engineering, make sure to check our dedicated sections on the website for more information.
3 comments
[…] How To Create and Apply Git Patch Files […]
–online and –graph are non existent options in git, at least on the latest version (2.27.0)
“The ‘git format-patch’ command will check for commits that are in the branch specified but not in the current checked-out branch.”
No. That’s backwards