Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ jobs:
cargo \
debhelper-compat \
dh-cargo \
git \
dpkg-dev \
librust-thiserror-dev \
python3:native \
Expand Down Expand Up @@ -152,6 +153,7 @@ jobs:
dnf install -y \
cargo \
gcc \
git \
make \
redhat-rpm-config \
rpm-build \
Expand Down
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ and splits it into one patch file per commit.
## Usage

```sh
patchsplit <owner/repo> <pr-number> [--out <dir>] [--force]
patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force]
patchsplit <owner/repo> <pr-number> [--out <dir>] [--force] [--squash]
patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force] [--squash]
```

Examples:
Expand All @@ -31,10 +31,27 @@ patches/
Existing output files are not overwritten by default. Pass `--force` to replace
them.

### Aggregate all commits

```sh
patchsplit openai/codex 42 --squash -o pr-42-patches
git apply pr-42-patches/pr-42.patch
```

`-s, --squash` downloads GitHub's aggregate PR `.diff` and writes a single
`pr-<pr-number>.patch`. This represents the net change from the PR's merge base
to its head: repeated edits are combined and reverted changes disappear.
It does not concatenate per-commit patches. The output is a raw diff for
`git apply` on the corresponding base, without individual commit messages or
authorship (it is not a `git am` mailbox). An empty net diff is reported as an
empty patch and no file is written. Binary changes are limited to the data
GitHub includes in its diff; binary file contents may not be included.

## Options

- `-o, --out <dir>`: Output directory for split patch files.
- `-o, --out <dir>`: Output directory for patch files.
- `-f, --force`: Overwrite existing patch files.
- `-s, --squash`: Write the PR's net diff as one patch.
- `-h, --help`: Show help.
- `-V, --version`: Show version.

Expand Down Expand Up @@ -63,6 +80,9 @@ extraction are listed in `po/POTFILES.in`.

## Build

Tests (`cargo test`) also require Git on Unix to verify that aggregate patches
apply to the expected file tree.

```sh
cargo build --release
```
Expand Down
23 changes: 20 additions & 3 deletions README_zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
## 用法

```sh
patchsplit <owner/repo> <pr-number> [--out <dir>] [--force]
patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force]
patchsplit <owner/repo> <pr-number> [--out <dir>] [--force] [--squash]
patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force] [--squash]
```

示例:
Expand All @@ -29,10 +29,25 @@ patches/

如果输出文件已存在,命令默认拒绝覆盖。需要覆盖时传入 `--force`。

### 聚合所有 commit

```sh
patchsplit openai/codex 42 --squash -o pr-42-patches
git apply pr-42-patches/pr-42.patch
```

`-s, --squash` 下载 GitHub 提供的 PR 整体 `.diff`,输出一个
`pr-<pr-number>.patch`。它表示 PR 从共同祖先(merge base)到最终 head 的净变化:
同一文件的多次修改会合并,已撤销的修改会消失,不是把各 commit 的补丁拼接起来。
输出为可在对应基线上用 `git apply` 应用的原始 diff,不包含各 commit 的提交说明和
作者信息,不能作为 `git am` 邮件补丁使用。净变化为空时会报补丁为空,不生成文件。
二进制变更受 GitHub diff 返回内容限制,可能不包含二进制文件内容。

## 参数

- `-o, --out <dir>`:指定拆分后 patch 文件的输出目录。
- `-o, --out <dir>`:指定 patch 文件的输出目录。
- `-f, --force`:允许覆盖已存在的 patch 文件。
- `-s, --squash`:将 PR 的最终净变化输出为一个补丁。
- `-h, --help`:显示帮助。
- `-V, --version`:显示版本。

Expand All @@ -59,6 +74,8 @@ scripts/update-pot.sh

## 构建

在 Unix 上运行测试(`cargo test`)还需要 Git,用于验证聚合补丁应用后的文件树。

```sh
cargo build --release
```
Expand Down
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Build-Depends:
debhelper-compat (= 13),
dh-cargo,
cargo,
git,
rustc,
python3:native,
librust-thiserror-dev (>= 2.0.0)
Expand Down
14 changes: 13 additions & 1 deletion debian/patchsplit.1
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,25 @@ patchsplit \- download a GitHub pull request patch and split it by commit
downloads the patch for a GitHub pull request and splits it into
individual patch files, one for each commit.
.PP
With
.BR \-\-squash ,
download the aggregate PR diff and write one
.B pr-<pr-number>.patch
containing the net change from the merge base to the PR head.
Repeated edits are combined and reverted changes disappear.
The output is a raw diff for git apply, without commit metadata.
An empty net diff is an error. Binary contents may be omitted by GitHub.
.PP
The resulting patch files are written to the
.B patches
directory by default.
.SH OPTIONS
.TP
.BR \-s ", " \-\-squash
Write the PR's net diff as one patch instead of splitting by commit.
.TP
.BR \-o ", " \-\-out " " \fIdir\fR
Write split patch files to
Write patch files to
.IR dir .
The default is
.BR patches .
Expand Down
14 changes: 13 additions & 1 deletion packaging/patchsplit.1
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,25 @@ patchsplit \- download a GitHub pull request patch and split it by commit
downloads the patch for a GitHub pull request and splits it into
individual patch files, one for each commit.
.PP
With
.BR \-\-squash ,
download the aggregate PR diff and write one
.B pr-<pr-number>.patch
containing the net change from the merge base to the PR head.
Repeated edits are combined and reverted changes disappear.
The output is a raw diff for git apply, without commit metadata.
An empty net diff is an error. Binary contents may be omitted by GitHub.
.PP
The resulting patch files are written to the
.B patches
directory by default.
.SH OPTIONS
.TP
.BR \-s ", " \-\-squash
Write the PR's net diff as one patch instead of splitting by commit.
.TP
.BR \-o ", " \-\-out " " \fIdir\fR
Write split patch files to
Write patch files to
.IR dir .
The default is
.BR patches .
Expand Down
1 change: 1 addition & 0 deletions packaging/patchsplit.spec
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Source0: %{name}-%{version}.tar.gz
BuildRequires: rust
BuildRequires: cargo
BuildRequires: gcc
BuildRequires: git

%description
Patchsplit is a command-line tool for splitting patch files into
Expand Down
14 changes: 10 additions & 4 deletions po/patchsplit.pot
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ msgstr ""
msgid "downloaded patch is empty"
msgstr ""

#: src/main.rs
msgid "downloaded content is not a Git diff"
msgstr ""

#: src/main.rs
msgid "failed to create output directory {path}: {source}"
msgstr ""
Expand All @@ -113,17 +117,19 @@ msgstr ""
#: src/main.rs
msgid ""
"Usage:\n"
" patchsplit <owner/repo> <pr-number> [--out <dir>] [--force]\n"
" patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force]\n"
" patchsplit <owner/repo> <pr-number> [--out <dir>] [--force] [--squash]\n"
" patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force] [--squash]\n"
"\n"
"Options:\n"
" -o, --out <dir> Output directory for split patch files [default: "
" -o, --out <dir> Output directory for patch files [default: "
"patches]\n"
" -f, --force Overwrite existing patch files\n"
" -s, --squash Write the PR's net diff as one patch\n"
" -h, --help Show this help\n"
" -V, --version Show version\n"
"\n"
"Examples:\n"
" patchsplit rust-lang/rust 12345\n"
" patchsplit openai codex 42 -o pr-42-patches"
" patchsplit openai codex 42 -o pr-42-patches\n"
" patchsplit openai/codex 42 --squash"
msgstr ""
24 changes: 16 additions & 8 deletions po/zh_CN.po
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ msgstr "下载的 patch 不是有效的 UTF-8 文本:{source}"
msgid "downloaded patch is empty"
msgstr "下载的 patch 为空"

#: src/main.rs
msgid "downloaded content is not a Git diff"
msgstr "下载的内容不是 Git diff"

#: src/main.rs
msgid "failed to create output directory {path}: {source}"
msgstr "创建输出目录 {path} 失败:{source}"
Expand All @@ -112,30 +116,34 @@ msgstr "仓库"
#: src/main.rs
msgid ""
"Usage:\n"
" patchsplit <owner/repo> <pr-number> [--out <dir>] [--force]\n"
" patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force]\n"
" patchsplit <owner/repo> <pr-number> [--out <dir>] [--force] [--squash]\n"
" patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force] [--squash]\n"
"\n"
"Options:\n"
" -o, --out <dir> Output directory for split patch files [default: "
" -o, --out <dir> Output directory for patch files [default: "
"patches]\n"
" -f, --force Overwrite existing patch files\n"
" -s, --squash Write the PR's net diff as one patch\n"
" -h, --help Show this help\n"
" -V, --version Show version\n"
"\n"
"Examples:\n"
" patchsplit rust-lang/rust 12345\n"
" patchsplit openai codex 42 -o pr-42-patches"
" patchsplit openai codex 42 -o pr-42-patches\n"
" patchsplit openai/codex 42 --squash"
msgstr ""
"用法:\n"
" patchsplit <owner/repo> <pr-number> [--out <dir>] [--force]\n"
" patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force]\n"
" patchsplit <owner/repo> <pr-number> [--out <dir>] [--force] [--squash]\n"
" patchsplit <owner> <repo> <pr-number> [--out <dir>] [--force] [--squash]\n"
"\n"
"选项:\n"
" -o, --out <dir> 拆分后的 patch 文件输出目录 [默认:patches]\n"
" -o, --out <dir> patch 文件输出目录 [默认:patches]\n"
" -f, --force 覆盖已有 patch 文件\n"
" -s, --squash 将 PR 的最终净变化输出为一个补丁\n"
" -h, --help 显示帮助信息\n"
" -V, --version 显示版本\n"
"\n"
"示例:\n"
" patchsplit rust-lang/rust 12345\n"
" patchsplit openai codex 42 -o pr-42-patches"
" patchsplit openai codex 42 -o pr-42-patches\n"
" patchsplit openai/codex 42 --squash"
Loading
Loading