<p align="center">
<img alt="Revup" src="https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/revup_light.svg"/>
</p>
<p align="center">
<a href="https://github.com/Skydio/revup"><img alt="Source Code" src="https://img.shields.io/badge/source-code-blue"/></a>
<a href="https://github.com/Skydio/revup/issues"><img alt="Issues" src="https://img.shields.io/badge/issue-tracker-blue"/></a>
<img alt="Python 3.8 | 3.9 | 3.10" src="https://img.shields.io/pypi/pyversions/revup"/>
<a href="https://pypi.org/project/revup/"><img alt="PyPI" src="https://img.shields.io/pypi/v/revup"/></a>
<a href="https://github.com/Skydio/revup/tree/main/LICENSE"><img alt="MIT License" src="https://img.shields.io/pypi/l/revup"/></a>
</p>
Revup provides command-line tools that allow developers to iterate faster on parallel changes and reduce the overhead of creating and maintaining code reviews.
<p align="center">
<img alt="intro_gif" src="https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_1.gif"/>
</p>
# 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 amend` and `revup restack` save time by replacing slow rebases
# Compatibility
Revup requires python 3.8 or higher and git 2.40 or higher. Revup works with Linux, OSX, and Windows (limited testing).
Follow instructions [here](https://git-scm.com/downloads) 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.
```sh
python3.8 -m pip install revup
```
Verify that installation was successful by showing the help page.
```sh
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](https://github.com/Skydio/revup/fork) revup, creating a [new](https://github.com/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.
```sh
git clone https://github.com/<your-name>/revup.git && cd revup
```
On first run, you will need to configure github credentials. Create a personal access token [here](https://github.com/settings/tokens/new)
and check the box for "full repo permissions". Revup needs this in order to create and modify pull requests. Then run
```sh
revup config github_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.
```sh
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
```
![tutorial_1](https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_1.gif)
You've uploaded your first revup changes! Notice how in github, both branches target 'main'. This allows them to be merged independently.
<img src="https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/foo_github.png" width="50%"><img src="https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/bar_github.png" width="50%">
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.
```sh
echo deh >> foo; git add foo
git commit -m "My second revup foo" -m "Topic: foo2" -m "Relative: foo"
revup upload
```
![tutorial_2](https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_2.gif)
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.
```sh
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
```
![tutorial_3](https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_3.gif)
`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 --interactive` along with `git 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](https://github.com/Skydio/revup/tree/main/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
Assignees: eve
Labels: bug, feature, draft
```
Github usernames can be abbreviated and will match the shortest name with the given prefix.
Labels must match exactly. The `draft` label is special and will make a pull request a draft if present and unmake draft if removed.
## 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.
<img src="https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/review_graph.png" width="40%">
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.
<img src="https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/patchsets.png" width="80%">
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 config in `~/.revupconfig`, followed by `.revupconfig` in the current repo.
## 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
```
# 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.
- [Stacked Diffs vs Pull Request](https://jg.gg/2018/09/29/stacked-diffs-versus-pull-requests/)
- [In Praise of Stacked PRs](https://benjamincongdon.me/blog/2022/07/17/In-Praise-of-Stacked-PRs/)
## Peer projects
Revup is inspired in part by this non-exhaustive list of open source projects that also support a patch based workflow:
- [ghstack](https://github.com/ezyang/ghstack): also a patched based tool integrated with github. revup builds on code from this project, especially graphql usage.
- [git-branchstack](https://github.com/krobelus/git-branchstack): creates branches similar to `revup upload` but doesn't push or create reviews.
- [git-revise](https://github.com/mystor/git-revise): similar to `revup amend` and 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](https://github.com/Skydio/revup/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 -v` to provide verbose logs.
## Disclaimer
Revup is published by Skydio but is not an officially supported Skydio product.
Raw data
{
"_id": null,
"home_page": "https://github.com/skydio/revup",
"name": "revup",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "github python git workflow version-control python3 developer-tools code-review pull-requests developers developer-productivity stacked-diffs",
"author": "Jerry Zhang",
"author_email": "jerry@skydio.com",
"download_url": "https://files.pythonhosted.org/packages/b6/2b/d352356c14c2ee65bf9817fc4ba304325d15c247a34bc8d0f609c502fac4/revup-0.3.0.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n\n <img alt=\"Revup\" src=\"https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/revup_light.svg\"/>\n\n</p>\n\n<p align=\"center\">\n<a href=\"https://github.com/Skydio/revup\"><img alt=\"Source Code\" src=\"https://img.shields.io/badge/source-code-blue\"/></a>\n<a href=\"https://github.com/Skydio/revup/issues\"><img alt=\"Issues\" src=\"https://img.shields.io/badge/issue-tracker-blue\"/></a>\n<img alt=\"Python 3.8 | 3.9 | 3.10\" src=\"https://img.shields.io/pypi/pyversions/revup\"/>\n<a href=\"https://pypi.org/project/revup/\"><img alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/revup\"/></a>\n<a href=\"https://github.com/Skydio/revup/tree/main/LICENSE\"><img alt=\"MIT License\" src=\"https://img.shields.io/pypi/l/revup\"/></a>\n</p>\n\nRevup provides command-line tools that allow developers to iterate faster on parallel changes and reduce the overhead of creating and maintaining code reviews.\n\n<p align=\"center\">\n<img alt=\"intro_gif\" src=\"https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_1.gif\"/>\n</p>\n\n# Features\n\n- 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.\n- Pull requests target the actual base branch and can be merged manually or by continuous integration\n- Rebase detection saves time and continuous integration cost by not re-pushing if the patch hasn't changed\n- Adds reviewers, labels, and creates drafts all from the commit text\n- Adds auto-updating \"review graph\" and \"patchsets\" elements to make pull requests easier to navigate\n- `revup amend` and `revup restack` save time by replacing slow rebases\n\n# Compatibility\n\nRevup requires python 3.8 or higher and git 2.40 or higher. Revup works with Linux, OSX, and Windows (limited testing).\n\nFollow instructions [here](https://git-scm.com/downloads) to get the latest git version for your OS. Revup uses flags only present in newer git versions.\n\n# Installing\n\nInstall with `pip` or your favorite package manager.\n\n```sh\npython3.8 -m pip install revup\n```\n\nVerify that installation was successful by showing the help page.\n\n```sh\nrevup -h\n```\n\nYou can also build from source to get the latest updates.\n\n```\ngit clone https://github.com/Skydio/revup.git && cd revup\nmake deps && make package && make install\n```\n\n# Tutorial\n\nThis tutorial will guide you through using basic revup features.\n\n## First time setup\n\nClone a sandbox repo by [forking](https://github.com/Skydio/revup/fork) revup, creating a [new](https://github.com/new) repo, or using some other repo you own.\nCreating test PRs can be spammy so don't do the tutorial on other people's repos.\n\n```sh\ngit clone https://github.com/<your-name>/revup.git && cd revup\n```\n\nOn first run, you will need to configure github credentials. Create a personal access token [here](https://github.com/settings/tokens/new)\nand check the box for \"full repo permissions\". Revup needs this in order to create and modify pull requests. Then run\n```sh\nrevup config github_oauth\n```\nand copy and paste the oauth into the prompt.\n\n## Create independent pull requests\n\nMake your first two commits that will become two separate pull requests.\nNote the \"Topic:\" tag in the commit message - this is what causes revup to recognize and act on a commit.\nEach separately named topic will become a new pull request.\n\n```sh\necho meh > foo; git add foo\ngit commit -m \"My first revup foo\" -m \"Topic: foo\"\necho peh > bar; git add bar\ngit commit -m \"My first revup bar\" -m \"Topic: bar\"\n\nrevup upload\n```\n\n![tutorial_1](https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_1.gif)\n\nYou've uploaded your first revup changes! Notice how in github, both branches target 'main'. This allows them to be merged independently.\n\n<img src=\"https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/foo_github.png\" width=\"50%\"><img src=\"https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/bar_github.png\" width=\"50%\">\n\nUnder the hood, revup creates and pushes these branches for you, tracking and managing the dependencies as needed.\n\n## Create relative pull requests\n\nNow we'll make a new review that's relative to \"foo\". The \"Relative\" tag will ensure the new review targets the correct branch.\n\n```sh\necho deh >> foo; git add foo\ngit commit -m \"My second revup foo\" -m \"Topic: foo2\" -m \"Relative: foo\"\n\nrevup upload\n```\n\n![tutorial_2](https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_2.gif)\n\nWith this simple but powerful model, you can upload independent and dependent changes all at once.\n\n- Multiple commits can be in one topic, in which case they will all be in a single pull request.\n- Commits in the same topic do not need to be adjacent in history.\n- Topics relative to each other do not need to be adjacent in history, but the second topic must come after the first.\n\n## Modify pull requests\n\nNow let's update a pull request.\n\n```sh\necho heh >> bar; git add bar\n# Either\nrevup amend HEAD~ --no-edit # Specify a commit to amend\n# or\nrevup amend bar --no-edit # Specify a topic name to amend\n\nrevup upload\n```\n\n![tutorial_3](https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/tutorial_3.gif)\n\n`revup amend` makes it easy to modify commits in your history. You also have other options for modifying reviews:\n\n- Adding new commits with the same topic\n- Using `git rebase --interactive` along with `git commit --amend`\n\n## Pulling in upstream changes\n\nUse `git pull --rebase` to pull in changes. Don't use `git merge` or `git pull` without rebase as this creates a merge commit.\n\nBy 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`.\n\n```\n[pull]\n rebase = true\n[rebase]\n autoStash = true\n```\nWe recommend adding the above to `.gitconfig` to make pulling and rebasing easier.\n\n# More features\n\nThis is a non-exhaustive intro to some more handy revup features.\n\nFor a full description of features, see the [docs](https://github.com/Skydio/revup/tree/main/docs) or run `revup -h` or `revup upload -h` to view docs in `man` format.\n\n## Work with forks\n\nFor 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.\n\nAdd git remotes for both the original and fork.\n```\n$ git remote -v\norigin https://github.com/ORIGINAL_OWNER/REPO_NAME.git (fetch)\norigin https://github.com/ORIGINAL_OWNER/REPO_NAME.git (push)\nmyfork https://github.com/YOUR_USERNAME/REPO_NAME.git (fetch)\nmyfork https://github.com/YOUR_USERNAME/REPO_NAME.git (push)\n```\n\nWhen uploading, pass the remote to create the pull request in as `--remote-name` and the forked remote as `--fork-name`.\n```\nrevup --remote-name origin --fork-name myfork upload\n```\n\n## Add reviewers / labels\n\nRevup can also add reviewers, assignees, and labels to pull requests. Add the appropriate tags to any commit in a topic.\n\n```\nReviewers: alice, bob\nAssignees: eve\nLabels: bug, feature, draft\n```\n\nGithub usernames can be abbreviated and will match the shortest name with the given prefix.\n\nLabels must match exactly. The `draft` label is special and will make a pull request a draft if present and unmake draft if removed.\n\n## Working on other branches\n\nRevup normally auto-detects your local base branch and uses that to list commits and target reviews.\nYou 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).\n\n```\nA fix for multiple branches\n\nTopic: fix\nBranches: main, rel1.1\n```\n\nYou 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).\n\n```\nrevup upload --base-branch custom-branch-name\n```\n\n## Review graph and patchsets\n\nRevup 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.\n\n<img src=\"https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/review_graph.png\" width=\"40%\">\n\nThe 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.\n\n<img src=\"https://raw.githubusercontent.com/skydio/revup/740c5cd/docs/images/patchsets.png\" width=\"80%\">\n\nThe 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\nthe case where you rebase then upload and will show you a diff with upstream files excluded.\n\n# Configuring revup\n\nRevup 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.\n\nFlags specified on the command line take precedence, followed by config in `~/.revupconfig`, followed by `.revupconfig` in the current repo.\n\n## Repo config\n\nThe primary usecase for the in-repo config file is setting up the naming of the main branch and release branches.\n\nFor example if your main branch is `master` and release branches are named like `rel1.1`, commit the following to `.revupconfig` in the repo root.\n\n```\n[revup]\nmain_branch = master\nbase_branch_globs =\n rel[1-9].[0-9]\n rel[1-9].[0-9][0-9]\n```\n\n## User config\n\nThe user config at `~/.revupconfig` saves time by defaulting the most commonly used flags.\n\nFor 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`.\n\n```\n[upload]\nskip_confirm = True\n```\n\n# Appendix\n\n## Commit based development\n\n(aka \"stacked diffs\", \"patch based\", etc)\n\nIf 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.\n\n- [Stacked Diffs vs Pull Request](https://jg.gg/2018/09/29/stacked-diffs-versus-pull-requests/)\n- [In Praise of Stacked PRs](https://benjamincongdon.me/blog/2022/07/17/In-Praise-of-Stacked-PRs/)\n\n## Peer projects\n\nRevup is inspired in part by this non-exhaustive list of open source projects that also support a patch based workflow:\n\n- [ghstack](https://github.com/ezyang/ghstack): also a patched based tool integrated with github. revup builds on code from this project, especially graphql usage.\n- [git-branchstack](https://github.com/krobelus/git-branchstack): creates branches similar to `revup upload` but doesn't push or create reviews.\n- [git-revise](https://github.com/mystor/git-revise): similar to `revup amend` and the backend for the above with a merge system that handles conflicts\n\n## Contributing & support\n\nThanks for contributing to revup! You can get started with your own idea, or see the [issues](https://github.com/Skydio/revup/issues) page for ideas that other people are excited about.\n\nWhen reporting issues:\n- Check the issue tracker to see if it has already been reported.\n- Provide a description of repro steps.\n- If possible, run the same command with `revup -v` to provide verbose logs.\n\n## Disclaimer\n\nRevup is published by Skydio but is not an officially supported Skydio product.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Revolutionary github tools. Effortlessly create multiple branches and pull requests.",
"version": "0.3.0",
"project_urls": {
"Bug Tracker": "https://github.com/skydio/revup/issues",
"Homepage": "https://github.com/skydio/revup",
"Source": "https://github.com/skydio/revup"
},
"split_keywords": [
"github",
"python",
"git",
"workflow",
"version-control",
"python3",
"developer-tools",
"code-review",
"pull-requests",
"developers",
"developer-productivity",
"stacked-diffs"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b62bd352356c14c2ee65bf9817fc4ba304325d15c247a34bc8d0f609c502fac4",
"md5": "6c3d2751b7cbe7c1324d289549e4d6fe",
"sha256": "2eb49172759ce00bd66e94ab38ba6bb3ead5334b11d63a0b6adde0f6883a0701"
},
"downloads": -1,
"filename": "revup-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "6c3d2751b7cbe7c1324d289549e4d6fe",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 70903,
"upload_time": "2024-07-02T19:47:53",
"upload_time_iso_8601": "2024-07-02T19:47:53.892615Z",
"url": "https://files.pythonhosted.org/packages/b6/2b/d352356c14c2ee65bf9817fc4ba304325d15c247a34bc8d0f609c502fac4/revup-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-02 19:47:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "skydio",
"github_project": "revup",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "revup"
}