git 版本必须 2.45 以上,旧版本缺少所需 flag;首次使用需创建带 repo 和 read:org 权限的 GitHub Token 并运行 revup config forge_oauth;拉取上游请用 git pull --rebase,否则产生 merge commit 导致 revup 默认不上传
revup
SkydioMIT活跃维护基于 Python 的 Git 工作流工具,一次提交即可生成多个相互关联的 PR,并支持补丁版本追踪和 rebase 检测,让代码评审更高效。
Upload once to create multiple, relative PRs. Productivity-focused git tools with patch revision tracking, rebase detection and more. Uses python and git plumbing commands.
python3 -m pip install revup
revup -hREADME 未说明,仅要求 Python 3.8+ 与 git 2.45+,支持 Linux、OSX、Windows(测试有限)
用提交信息里的 Topic 标签自动生成并维护多条独立或相对依赖的 GitHub PR 链
基于 Python 的 Git 工作流工具,一次提交即可生成多个相互关联的 PR,并支持补丁版本追踪和 rebase 检测,让代码评审更高效。
核心能力
- 按 Topic 标签在后台创建独立分支链,不触碰工作区
- 用 Relative 标签建立相对 PR,自动指向正确的 base 分支
- 检测 rebase 后补丁未变则跳过重新推送,省 CI 成本
- 从提交信息自动添加 reviewer、assignee、label 和 draft
- 自动维护 review graph 与 patchsets 评论便于导航
容易踩的坑
- v0.4.0最新正式版2025-04-28 · 2025-04-28 20:50 UTC
Major improvements:
- Fixed the github issues when reordering PRs in a stack
- Patchsets now uses git merge-tree, and will be much more accurate within a single file
Minor improvements:
- QOL improvements for "config"
- Various other qol fixes
What's Changed
- git: Bump git supported version to 2.43 by @jerry-skydio in https://github.com/Skydio/revup/pull/189
- Fix warning formatting by @aaron-skydio in https://github.com/Skydio/revup/pull/190
- pylint: Disable too-many-positional-argument by @jerry-skydio in https://github.com/Skydio/revup/pull/192
- amend: Allow amending with pure renames by @brian-kubisiak-skydio in https://github.com/Skydio/revup/pull/191
- docs: improve GitHub token setup instructions for better accessibility and clarity by @f440 in https://github.com/Skydio/revup/pull/194
- git: Correctly match repository names containing '.' by @brian-kubisiak-skydio in https://github.com/Skydio/revup/pull/193
- lint: Fix misc pylint file warnings by @jerry-skydio in https://github.com/Skydio/revup/pull/195
- git: Add option for no_config in git shell by @jerry-skydio in https://github.com/Skydio/revup/pull/188
- git: Use merge-tree in patchsets by @jerry-skydio in https://github.com/Skydio/revup/pull/187
- upload: Allow relative between different uploaders by @jerry-skydio in https://github.com/Skydio/revup/pull/205
- git: Don't swallow all push output by @jerry-skydio in https://github.com/Skydio/revup/pull/204
- upload: Check PRs merge into base branch rather than base ref by @jerry-skydio in https://github.com/Skydio/revup/pull/207
- config: Improve input checking in config command by @jerry-skydio in https://github.com/Skydio/revup/pull/209
- config: Remove -nx negation shortform by @jerry-skydio in https://github.com/Skydio/revup/pull/210
- upload: Push a dummy commit to work around reordering issues by @jerry-skydio in https://github.com/Skydio/revup/pull/208
- upload: Query head oid of a PR via commits by @jerry-skydio in https://github.com/Skydio/revup/pull/206
New Contributors
- @f440 made their first contribution in https://github.com/Skydio/revup/pull/194
Full Changelog: https://github.com/Skydio/revup/compare/v0.3.0...v0.4.0
- v0.3.02024-07-02 · 2024-07-02 19:46 UTC
查看更新说明
This release is long overdue and adds a bunch of nifty features, qol improvements, and minor bugfixes
- ability to share credentials with gh auth so you don't need to write a token to a text file, just run gh auth login and you're free to remove github_oauth from your ~/.revupconfig
- ability to use cleanup=scissors with amend (try git config commit.cleanup scissors if you haven't already it's way better)
- ability to give relative topics in any order, both upload and restack will topologically sort relative chains for you
- ability to configure base branch inclusion in branch name, so you can retarget prs between branches. revup config upload.branch_format user will set this
- other small fixes and improvements
What's Changed
- Revup cherry-pick attempts to fetch by @aaron-skydio in https://github.com/Skydio/revup/pull/117
- git: Add ^commit to rev parse --verify by @jerry-skydio in https://github.com/Skydio/revup/pull/119
- amend: Fix double negative in no-edit by @jerry-skydio in https://github.com/Skydio/revup/pull/118
- setup: Add missing transitive dependencies by @jerry-skydio in https://github.com/Skydio/revup/pull/124
- readme: Update min git version by @jerry-skydio in https://github.com/Skydio/revup/pull/123
- amend: Force editing if inserting instead of throwing error by @jerry-skydio in https://github.com/Skydio/revup/pull/120
- Add support for git editor paths containing spaces by @mpearson in https://github.com/Skydio/revup/pull/126
- makefile: Fix mypy invocation by @jerry-skydio in https://github.com/Skydio/revup/pull/132
- Fix "Event loop is closed" error on windows by @mpearson in https://github.com/Skydio/revup/pull/127
- shell: Fix broken mypy linting on asyncio.gather() by @jerry-skydio in https://github.com/Skydio/revup/pull/134
- lint: Rerun black with latest version by @jerry-skydio in https://github.com/Skydio/revup/pull/135
- lint: Fix max line length by @jerry-skydio in https://github.com/Skydio/revup/pull/136
- github: Update python minor versions by @jerry-skydio in https://github.com/Skydio/revup/pull/133
- Read github credentials from git credential helper by @anguslees in https://github.com/Skydio/revup/pull/131
- lint: Fix linting in Credential class by @jerry-skydio in https://github.com/Skydio/revup/pull/137
- makefile: Fix newlines in revup man headers by @jerry-skydio in https://github.com/Skydio/revup/pull/138
- auth: Minor message and debug on auth source by @jerry-skydio in https://github.com/Skydio/revup/pull/139
- git: Run diff with --no-ext-diff by @jerry-skydio in https://github.com/Skydio/revup/pull/142
- lint: Update formatting yet again by @jerry-skydio in https://github.com/Skydio/revup/pull/143
- makefile: Pin black version by @jerry-skydio in https://github.com/Skydio/revup/pull/144
- toolkit: Add list-topics command by @brian-kubisiak-skydio in https://github.com/Skydio/revup/pull/141
- github: Also catch ContentTypeError by @jerry-skydio in https://github.com/Skydio/revup/pull/145
- scripts: Add shebang and executable to analyze_prs.py by @jerry-skydio in https://github.com/Skydio/revup/pull/146
- github: Don't match a user unless the prefix is correct by @jerry-skydio in https://github.com/Skydio/revup/pull/147
- Small analyze_prs improvements by @jerry-skydio in https://github.com/Skydio/revup/pull/149
- amend: Add more detail to the reflog action by @jerry-skydio in https://github.com/Skydio/revup/pull/150
- amend: respect git config commit.cleanup by @jerry-skydio in https://github.com/Skydio/revup/pull/151
- amend: respect core.commentChar by @jerry-skydio in https://github.com/Skydio/revup/pull/152
- amend: Update docs by @jerry-skydio in https://github.com/Skydio/revup/pull/154
- topic_stack: Simplify num_reviews a bit by @jerry-skydio in https://github.com/Skydio/revup/pull/166
- upload: Split populate reviews into 2 phases by @jerry-skydio in https://github.com/Skydio/revup/pull/157
- upload: Add topological_topics as a g
- v0.2.12023-04-27 · 2023-04-27 21:22 UTC
查看更新说明
What's Changed
- amend: Fix amending HEAD by @jerry-skydio in https://github.com/Skydio/revup/pull/116
Full Changelog: https://github.com/Skydio/revup/compare/v0.2.0...v0.2.1
- v0.2.02023-04-25 · 2023-04-25 19:11 UTC
查看更新说明
This release bumps the required git version to 2.39, which is one release older than the latest 2.40. We rely on a few flags / commands that were added in this version.
This release adds the following improvements / bugfixes:
- Added ability to specify which topics to upload on command line
- upload and amend now show you the contents of conflicts w/ conflict markers
- amend is about 16x faster. the cherry-pick step of upload is also that much faster, but upload is mostly bound by github api times.
- fixed the long standing issue where upload is skipped if only whitespace was changed
- added new revup config command to automatically edit config file for you. this is now the default way to set oauth and other config variables.
- cleaned up error message for github timeout during update
- sanitize topic names so we can give a better error
What's Changed
- lint: Fix lint failures by @jerry-skydio in https://github.com/Skydio/revup/pull/93
- lint: Run format to account for black upgrade by @jerry-skydio in https://github.com/Skydio/revup/pull/96
- git: Don't update index if file list is empty by @jerry-skydio in https://github.com/Skydio/revup/pull/92
- toolkit: Fix await statements by @jerry-skydio in https://github.com/Skydio/revup/pull/91
- Bump required git version to 2.39 by @jerry-skydio in https://github.com/Skydio/revup/pull/97
- Pass --verbatim to git patch-id by @jerry-skydio in https://github.com/Skydio/revup/pull/98
- Skip querying on an empty upload by @jerry-skydio in https://github.com/Skydio/revup/pull/100
- Avoid main branch not found error. by @jerry-skydio in https://github.com/Skydio/revup/pull/101
- Allow specifying topics to upload by @jerry-skydio in https://github.com/Skydio/revup/pull/95
- Use asyncio.gather to run patch-ids in parallel by @jerry-skydio in https://github.com/Skydio/revup/pull/104
- upload: Allow any head to be specified by @jerry-skydio in https://github.com/Skydio/revup/pull/99
- config: Reorganize config code and add config command by @jerry-skydio in https://github.com/Skydio/revup/pull/83
- Validate topic names by @jerry-skydio in https://github.com/Skydio/revup/pull/103
- upload: Improve is_on_correct_base logic by @jerry-skydio in https://github.com/Skydio/revup/pull/105
- Makefile uses python3 by @aaron-skydio in https://github.com/Skydio/revup/pull/85
- Only raise in parse_topics when uploading by @jerry-skydio in https://github.com/Skydio/revup/pull/107
- Add a simple LRU cache to common git cmds by @jerry-skydio in https://github.com/Skydio/revup/pull/108
- git: Switch cherry-pick backend to git merge-tree by @jerry-skydio in https://github.com/Skydio/revup/pull/109
- Remove remote prefix from upload printout by @jerry-skydio in https://github.com/Skydio/revup/pull/111
- Switch to async_lru for lru_cache() by @jerry-skydio in https://github.com/Skydio/revup/pull/112
- Delete topic from list if skipping by @jerry-skydio in https://github.com/Skydio/revup/pull/113
- git: Don't show clean error if failing to translate commit hash by @jerry-skydio in https://github.com/Skydio/revup/pull/115
- Catch and warn on github timeouts by @jerry-skydio in https://github.com/Skydio/revup/pull/114
Full Changelog: https://github.com/Skydio/revup/compare/v0.1.5...v0.2.0
- v0.1.52023-01-11 · 2023-01-11 23:20 UTC
查看更新说明
What's Changed
- github: Allow any ssh user in remote url by @jerry-skydio in https://github.com/Skydio/revup/pull/74
- github: Don't crash if a team is a reviewer by @jerry-skydio in https://github.com/Skydio/revup/pull/75
- github: Don't query teams yet by @jerry-skydio in https://github.com/Skydio/revup/pull/77
- amend: Don't attempt to lookup topics if no github remote by @jerry-skydio in https://github.com/Skydio/revup/pull/80
- patchsets: Make virtual diff target with shared history by @jerry-skydio in https://github.com/Skydio/revup/pull/81
- Fail on bad response status by @aaron-skydio in https://github.com/Skydio/revup/pull/82
- Fix error messages for unknown error types by @aaron-skydio in https://github.com/Skydio/revup/pull/84
- fix: small error by @0xflotus in https://github.com/Skydio/revup/pull/86
New Contributors
- @aaron-skydio made their first contribution in https://github.com/Skydio/revup/pull/82
- @0xflotus made their first contribution in https://github.com/Skydio/revup/pull/86
Full Changelog: https://github.com/Skydio/revup/compare/v0.1.4...v0.1.5
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Revup provides command-line tools that allow developers to iterate faster on parallel changes and reduce the overhead of creating and maintaining code reviews.
Features
- Revup creates multiple independent chains of branches for you in the background and without touching your working tree. It then creates and manages github pull requests for all those branches.
- Pull requests target the actual base branch and can be merged manually or by continuous integration
- Rebase detection saves time and continuous integration cost by not re-pushing if the patch hasn't changed
- Adds reviewers, labels, and creates drafts all from the commit text
- Adds auto-updating "review graph" and "patchsets" elements to make pull requests easier to navigate
revup amendandrevup restacksave time by replacing slow rebases
Compatibility
Revup requires python 3.8 or higher and git 2.45 or higher. Revup works with Linux, OSX, and Windows (limited testing).
Follow instructions here to get the latest git version for your OS. Revup uses flags only present in newer git versions.
Installing
Install with pip or your favorite package manager.
python3 -m pip install revup
Verify that installation was successful by showing the help page.
revup -h
You can also build from source to get the latest updates.
git clone https://github.com/Skydio/revup.git && cd revup
make deps && make package && make install
Tutorial
This tutorial will guide you through using basic revup features.
First time setup
Clone a sandbox repo by forking revup, creating a new repo, or using some other repo you own. Creating test PRs can be spammy so don't do the tutorial on other people's repos.
git clone https://github.com/<your-name>/revup.git && cd revup
On first run, you will need to configure github credentials. Create a GitHub Personal Access Token with the "repo" and "read:org" scopes, which revup needs in order to create and modify pull requests. Then run
revup config forge_oauth
and copy and paste the oauth into the prompt.
Create independent pull requests
Make your first two commits that will become two separate pull requests. Note the "Topic:" tag in the commit message - this is what causes revup to recognize and act on a commit. Each separately named topic will become a new pull request.
echo meh > foo; git add foo
git commit -m "My first revup foo" -m "Topic: foo"
echo peh > bar; git add bar
git commit -m "My first revup bar" -m "Topic: bar"
revup upload

You've uploaded your first revup changes! Notice how in github, both branches target 'main'. This allows them to be merged independently.
Under the hood, revup creates and pushes these branches for you, tracking and managing the dependencies as needed.
Create relative pull requests
Now we'll make a new review that's relative to "foo". The "Relative" tag will ensure the new review targets the correct branch.
echo deh >> foo; git add foo
git commit -m "My second revup foo" -m "Topic: foo2" -m "Relative: foo"
revup upload

With this simple but powerful model, you can upload independent and dependent changes all at once.
- Multiple commits can be in one topic, in which case they will all be in a single pull request.
- Commits in the same topic do not need to be adjacent in history.
- Topics relative to each other do not need to be adjacent in history, but the second topic must come after the first.
Modify pull requests
Now let's update a pull request.
echo heh >> bar; git add bar
# Either
revup amend HEAD~ --no-edit # Specify a commit to amend
# or
revup amend bar --no-edit # Specify a topic name to amend
revup upload

revup amend makes it easy to modify commits in your history. You also have other options for modifying reviews:
- Adding new commits with the same topic
- Using
git rebase --interactivealong withgit commit --amend
Pulling in upstream changes
Use git pull --rebase to pull in changes. Don't use git merge or git pull without rebase as this creates a merge commit.
By default revup will not upload if you pull but haven't made changes to a commit. To override this and upload always, run revup upload --rebase.
[pull]
rebase = true
[rebase]
autoStash = true
We recommend adding the above to .gitconfig to make pulling and rebasing easier.
More features
This is a non-exhaustive intro to some more handy revup features.
For a full description of features, see the docs or run revup -h or revup upload -h to view docs in man format.
Work with forks
For contributing to projects that you may not have push access to, revup can be configured to push to a fork while creating a pull request in the main project.
Add git remotes for both the original and fork.
$ git remote -v
origin https://github.com/ORIGINAL_OWNER/REPO_NAME.git (fetch)
origin https://github.com/ORIGINAL_OWNER/REPO_NAME.git (push)
myfork https://github.com/YOUR_USERNAME/REPO_NAME.git (fetch)
myfork https://github.com/YOUR_USERNAME/REPO_NAME.git (push)
When uploading, pass the remote to create the pull request in as --remote-name and the forked remote as --fork-name.
revup --remote-name origin --fork-name myfork upload
Add reviewers / labels
Revup can also add reviewers, assignees, and labels to pull requests. Add the appropriate tags to any commit in a topic.
Reviewers: alice, bob, myorg/backend-team
Assignees: eve
Labels: bug, feature
Draft: true
Github usernames can be abbreviated and will match the shortest name with the given prefix.
Teams are specified as org/team-slug and can be used as reviewers (Github does not support teams as assignees).
Labels must match exactly. Draft: true makes a pull request a draft, and Draft: false or removing the tag unmakes it.
Working on other branches
Revup normally auto-detects your local base branch and uses that to list commits and target reviews. You can choose to target any particular topic to another branch or even multiple branches, in which case revup will use those as the base branch instead (and create multiple pull requests in the latter case).
A fix for multiple branches
Topic: fix
Branches: main, rel1.1
You can specify base branch on the command line as well, although this is usually not necessary unless you're working on a branch that the autodetector doesn't know about (see Repo config below).
revup upload --base-branch custom-branch-name
Review graph and patchsets
Revup will add 2 comments in every pull request to provide helpful features for users and reviewers. These are enabled by default and automatically updated as the pull request changes.
The review graph provides links and titles to all local pull requests that have a relative relationship with the current pull request, including any that it depends on, or that depend on it. This allows you to quickly browse between pull requests in a chain.
The patchsets table provides a history of uploads for a given pull request as well as links and summaries of the diff between each upload. Notably, revup specially handles the case where you rebase then upload and will show you a diff with upstream files excluded.
Configuring revup
Revup is highly configurable using a standard config file format. Every flag is also a config option, so users can get the exact behavior they need.
Flags specified on the command line take precedence, followed by .revupconfig in the current repo's .git directory, followed by .revupconfig at the repo root, followed by ~/.revupconfig.
Repo config
The primary usecase for the in-repo config file is setting up the naming of the main branch and release branches.
For example if your main branch is master and release branches are named like rel1.1, commit the following to .revupconfig in the repo root.
[revup]
main_branch = master
base_branch_globs =
rel[1-9].[0-9]
rel[1-9].[0-9][0-9]
User config
The user config at ~/.revupconfig saves time by defaulting the most commonly used flags.
For example, after getting used to the workflow, a user might not need the confirmation check. Adding the following lines will be the same as running with --skip-confirm.
[upload]
skip_confirm = True
Git-dir config
A .revupconfig placed inside the current repo's .git directory has the highest config-file precedence and is not tracked by git. This is useful for per-checkout overrides that should not be shared with other contributors.
Appendix
Commit based development
(aka "stacked diffs", "patch based", etc)
If you've used tools such as Gerrit, Phabricator, or git mailing lists, you may already be familiar with this style of development. If you'd like to read more, here are some well written discussions on the subject.
Peer projects
Revup is inspired in part by this non-exhaustive list of open source projects that also support a patch based workflow:
- ghstack: also a patched based tool integrated with github. revup builds on code from this project, especially graphql usage.
- git-branchstack: creates branches similar to
revup uploadbut doesn't push or create reviews. - git-revise: similar to
revup amendand the backend for the above with a merge system that handles conflicts
Contributing & support
Thanks for contributing to revup! You can get started with your own idea, or see the issues page for ideas that other people are excited about.
When reporting issues:
- Check the issue tracker to see if it has already been reported.
- Provide a description of repro steps.
- If possible, run the same command with
revup -vto provide verbose logs.
Disclaimer
Revup is published by Skydio but is not an officially supported Skydio product.