patchy
makes it easy to maintain personal forks in which you merge some pull requests of your liking to have more features than other people.
- Merge multiple pull requests and commits into a single repo effortlessly
- Sync those pull requests and the main branch with a single command
- Add new pull requests and update existing ones easily
Go to a git repo, and initialize the config file:
patchy init
Invoke patchy
by running the following command:
patchy run
I'm using the Helix Editor but there are some pull requests which add awesome features.
I found myself very frequently doing the same tasks in order to sync the 4 pull requests I like to use and keep them up to date. With patchy, I just run one command and it handles the rest.
Here's my config:
# main repository to fetch from
repo = "helix-editor/helix"
# the repository's branch
remote-branch = "master"
# This is the branch where you will see all result from patchy's work. Set it to any branch you want.
# WARNING: Make sure you do not store any important work on this branch. It will be erased.
local-branch = "patchy"
# List of pull requests which you would like to merge
# TIP: Add comments above pull requests to help yourself understand which PRs do what
pull-requests = [
# syntax highlighting for nginx files
"12309",
# adds file explorer
"11285",
# global status line
"8908",
# command expansions
"11164",
]
# An optional list of patches to apply, more on them later
patches = ["remove-tab"]
Running patchy run
outputs:
With this, all I will need to do is run patchy run
and it will automatically update all of the pull requests and sync the master branch to the latest changes.
You might want to apply some changes to your repo, but it's not a pull request. No worries! patchy
is built for this.
Create a patch from a commit:
# obtain commit hashes e.g. from `git log`
patchy gen-patch <hash-of-commit>
For example, I'm running:
patchy gen-patch 7bb8ec5a77769d88855d41dd5fecfaece54cf471
It generated a file, .patchy/feat-swap-light-and-dark-colors.patch
:
diff --git a/README.md m/README.md
index 11a909b2..4eae6a8d 100644
--- a/README.md
+++ m/README.md
@@ -2,8 +2,8 @@
<h1>
<picture>
- <source media="(prefers-color-scheme: dark)" srcset="logo_dark.svg">
<source media="(prefers-color-scheme: light)" srcset="logo_light.svg">
+ <source media="(prefers-color-scheme: dark)" srcset="logo_dark.svg">
<img alt="Helix" height="128" src="logo_light.svg">
</picture>
</h1>
To use your new .patch
, edit your .patchy/config.toml
like so:
--- patches = []
+++ patches = [ "feat-swap-light-and-dark-colors" ]
Each pull request's branch contains commits. By default, we will always use the latest commit. However you can pin a commit to a specific version with the following syntax:
remote-branch = "main @ cfd225baedbb5fb9cbc9742f91244fa50882b580"
pull-requests = [
"145 @ fccc58957eece10d0818dfa000bf5123e26ee32f",
"88 @ a556aeef3736a3b6b79bb9507d26224f5c0c3449"
]
Where the hashes represent each sha1
hash of every commit.
This is handy if you don't want things to randomly break when some of the pull requests push a new change.
Patchy can be installed on Linux, Windows and macOS.
Install the binary directly into your system, available for macOS and Linux.
Recommended for Linux users.
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/nik-rev/patchy/releases/latest/download/patchy-installer.sh | sh
Recommended for macOS users.
brew install nik-rev/tap/patchy-bin
cargo install patchy-bin
Recommended for Windows users.
powershell -ExecutionPolicy ByPass -c "irm https://github.com/nik-rev/patchy/releases/latest/download/patchy-installer.ps1 | iex"
nix profile install github:nik-rev/patchy/main
Example usage with flakes
If the software you are using has a flake.nix
which automatically builds this software, then using patchy with it is straightforward.
-
Use patchy to create your own remote fork.
Let's say you fork the
helix-editor/helix
and your fork is located atyour-username/helix
, the patchy branch is calledpatchy
-
Add your fork's input in your
flake.nix
as follows:inputs.helix.url = "github:your-username/helix/patchy";
-
Use the input in your home-manager:
programs.helix.package = inputs.helix.packages.${pkgs.system}.helix;
This is easier when the target repository has a flake.nix
which fully builds the software. Which, the helix-editor/helix
does have for example.
If you merge a lot of PRs, it's likely some of them will clash with eachother and there will be conflicts.
Say you merge 10 pull requests, 3 of which couldn't be merged due to merge conflicts. The other 7 will be merged, while branches for those 3 will exist and you will be able to merge them yourself.
✗ Could not merge branch 11164/command-expansion into the current branch for pull request #11164 Command expansion v2 since the merge is non-trivial.
You will need to merge it yourself:
git merge --squash 11164/command-expansion
Note: To learn how to merge only once and re-use for subsequent invocations of patchy, see Merge conflicts (github)
Fixing merge conflicts and retaining the fixes, declaratively
Okay, now merge the branch:
git merge --squash 11164/command-expansion
We need --squash
since patchy gen-patch
does not work on Merge commits. But using --squash
makes it into a non-merge commit.
Now fix the merge conflicts.
Then, commit your changes:
git commit -m "merge branch 11164/command-expansion"
This creates the following commit:
2fb6c3c7 (HEAD -> patchy) Merge branch '11164/command-expansion' into patchy
Now that you have this commit, let's generate a .patch
file for it:
> patchy gen-patch 2fb6c3c7 --patch-filename=merge-11164
✓ Created patch file at .patchy/merge-11164.patch
Now, you can go ahead and add the patch to your config:
- pull-requests = [ "1234", "1111", "11164" ]
+ pull-requests = [ "1234", "1111" ]
- patches = [ ]
+ patches = [ "merge-11164" ]
When you do this, you won't need to solve this merge conflict anymore as the merge-11164
patch includes both the entire pull request as well as how it was merged.
Note that if you change the order of your pull requests in pull-requests
you may see merge conflicts again. It is recommended to keep the order the same once you fix the conflicts.