example scenario in README
This commit is contained in:
parent
cd564736f3
commit
9997c97cb8
143
README.md
143
README.md
|
@ -1,6 +1,7 @@
|
|||
# gh-stack [![Check if compilation works; no tests yet!](https://api.travis-ci.org/timothyandrew/gh-stack.svg?branch=master&status=passed)](https://travis-ci.org/timothyandrew/gh-stack)
|
||||
|
||||
- [Usage](#usage)
|
||||
- [Examples](#examples)
|
||||
- [Strategy](#strategy)
|
||||
- [Disclaimer](#disclaimer)
|
||||
|
||||
|
@ -63,6 +64,148 @@ $ gh-stack autorebase 'stack-identifier' -C /path/to/repo
|
|||
$ gh-stack rebase 'stack-identifier'
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
*This is a quick overview of the ways this tool could be used in practice.*
|
||||
|
||||
1. Write some code, create local commits/branches:
|
||||
```bash
|
||||
$ git checkout -b first
|
||||
# Write code
|
||||
$ git add -A; git commit -m 'first'
|
||||
|
||||
$ git checkout -b second
|
||||
# Write code
|
||||
$ git add -A; git commit -m 'second #1'
|
||||
# Write code
|
||||
$ git add -A; git commit -m 'second #2'
|
||||
|
||||
$ git checkout -b third
|
||||
# Write code
|
||||
$ git add -A; git commit -m 'third'
|
||||
```
|
||||
|
||||
2. Your Git tree now looks like:
|
||||
```bash
|
||||
* 42315c4 U - (third) third
|
||||
|
|
||||
* 6db2c28 U - (second) second #2
|
||||
|
|
||||
* 5746a83 U - second #1
|
||||
|
|
||||
* e845ded U - (first) first
|
||||
|
|
||||
* 8031011 U - initial commit
|
||||
```
|
||||
|
||||
3. Push each branch:
|
||||
```bash
|
||||
$ git push origin first:first second:second third:third
|
||||
* [new branch] first -> first
|
||||
* [new branch] second -> second
|
||||
* [new branch] third -> third
|
||||
```
|
||||
|
||||
4. Create a PR for each new branch (starting at `first`), and:
|
||||
- Ensure that all the PRs have a common identifier in their title (I'll use `[EXAMPLE-17399]` here). This identifier (currently) is required to be unique across all GitHub repositories accessible to you (including _all_ public repositories).
|
||||
- Set the `base` for each PR to the branch preceding it. Here, `first`'s PR is set to merge into `master`, `second`'s PR is set to merge into `first`, and `third`'s PR is set to merge into `second`.
|
||||
|
||||
5. Log all PRs in the stack:
|
||||
```bash
|
||||
$ gh-stack log 'EXAMPLE-13799'
|
||||
#1: [EXAMPLE-13799] PR for branch `first` (Base)
|
||||
#2: [EXAMPLE-13799] PR for branch `second` (Merges into #1)
|
||||
#3: [EXAMPLE-13799] PR for branch `third` (Merges into #2)
|
||||
```
|
||||
|
||||
6. Annotate all PRs with information about the stack:
|
||||
```bash
|
||||
$ gh-stack annotate 'EXAMPLE-13799'
|
||||
1: [EXAMPLE-13799] PR for branch `first`
|
||||
2: [EXAMPLE-13799] PR for branch `second`
|
||||
3: [EXAMPLE-13799] PR for branch `third`
|
||||
Going to update these PRs ☝️ Type 'yes' to continue: yes
|
||||
Done!
|
||||
```
|
||||
|
||||
This (idempotently) adds a table like this to the description of every PR in the stack:
|
||||
<img src="img/annotate.png" width="700" />
|
||||
|
||||
7. Make changes to a branch that rewrites commits in some way (amend, remove a commit, combine commits):
|
||||
```bash
|
||||
$ git checkout first
|
||||
# Do some work
|
||||
$ git add -A; git commit --amend -m 'amended first'
|
||||
```
|
||||
|
||||
History has now diverged, and this will cause conflicts with dependent PRs when `first` is (force-)pushed.
|
||||
```bash
|
||||
* e7cb9c6 U - (HEAD -> first) amended first
|
||||
|
|
||||
| * 42315c4 N - (origin/third, third) third
|
||||
| |
|
||||
| * 6db2c28 N - (origin/second, second) second #2
|
||||
| |
|
||||
| * 5746a83 N - second #1
|
||||
| |
|
||||
| * e845ded N - (origin/first) amended first
|
||||
|/
|
||||
|
|
||||
* 8031011 U - (origin/master, master) initial commit
|
||||
```
|
||||
|
||||
8. Use the `autorebase` subcommand to fix this inconsistency (it requires a path to a local checkout of the repository):
|
||||
```bash
|
||||
$ gh-stack autorebase --repo /tmp/test EXAMPLE-13799
|
||||
Checking out Commit { id: 803101159653bf4bf92bf098e577abc436458b17, summary: "initial commit" }
|
||||
|
||||
Working on PR: "first"
|
||||
Cherry-picking: Commit { id: e7cb9c6cdb03374a6c533cbf1fc23a7d611a73c7, summary: "amended first" }
|
||||
|
||||
Working on PR: "second"
|
||||
Cherry-picking: Commit { id: 5746a83aed004d0867d52d40efc9bd800b5b7499, summary: "second #1" }
|
||||
Cherry-picking: Commit { id: 6db2c2817dfed244d5fbd8cbb9b8095965ac9a05, summary: "second #2" }
|
||||
|
||||
Working on PR: "third"
|
||||
Cherry-picking: Commit { id: 42315c46b42044ebc4b57a995a75b97699f4855a, summary: "third" }
|
||||
|
||||
["b45e5838a93b33411a5f0c9f726bc1987bc71ff5:refs/heads/first", "93170d2199ed9c2ae30d1e7492947acf477fb035:refs/heads/second", "a85a1931c44c3138d993128591af2cad2ef6c68d:refs/heads/third"]
|
||||
Going to push these refspecs ☝️ Type 'yes' to continue: yes
|
||||
Enumerating objects: 12, done.
|
||||
Counting objects: 100% (12/12), done.
|
||||
Delta compression using up to 8 threads
|
||||
Compressing objects: 100% (8/8), done.
|
||||
Writing objects: 100% (11/11), 907 bytes | 453.00 KiB/s, done.
|
||||
Total 11 (delta 3), reused 0 (delta 0)
|
||||
remote: Resolving deltas: 100% (3/3), done.
|
||||
To github.com:timothyandrew/test.git
|
||||
+ e845ded...b45e583 b45e5838a93b33411a5f0c9f726bc1987bc71ff5 -> first (forced update)
|
||||
+ 6db2c28...93170d2 93170d2199ed9c2ae30d1e7492947acf477fb035 -> second (forced update)
|
||||
+ 42315c4...a85a193 a85a1931c44c3138d993128591af2cad2ef6c68d -> third (forced update)
|
||||
|
||||
Updating local branches so they point to the new stack.
|
||||
|
||||
+ Branch first now points to b45e5838a93b33411a5f0c9f726bc1987bc71ff5
|
||||
+ Branch second now points to 93170d2199ed9c2ae30d1e7492947acf477fb035
|
||||
+ Branch third now points to a85a1931c44c3138d993128591af2cad2ef6c68d
|
||||
All done!
|
||||
```
|
||||
|
||||
- This restores local history to a flat list and pushes the tip of each branch up to update the PRs themselves.
|
||||
```bash
|
||||
* a85a193 N - (HEAD, origin/third, third) third
|
||||
|
|
||||
* 93170d2 N - (origin/second, second) second #2
|
||||
|
|
||||
* 61f64b6 N - second #1
|
||||
|
|
||||
* b45e583 N - (origin/first, first) amended first
|
||||
|
|
||||
* 8031011 U - (origin/master, master) initial commit
|
||||
```
|
||||
|
||||
- If conflicts are encountered, `autorebase` will pause and allow you to fix the conflicts before resuming.
|
||||
|
||||
## Strategy
|
||||
|
||||
This is a quick summary of the strategy the `autorebase` subcommand uses:
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
After Width: | Height: | Size: 206 KiB |
Binary file not shown.
After Width: | Height: | Size: 156 KiB |
Binary file not shown.
After Width: | Height: | Size: 131 KiB |
|
@ -109,6 +109,8 @@ pub async fn fetch_pull_requests_matching(
|
|||
.into_iter()
|
||||
.map(|item| item.unwrap());
|
||||
|
||||
println!("{:?}", items);
|
||||
|
||||
let responses: Vec<_> = join_all(items.map(|item| item.json::<PullRequest>()))
|
||||
.await
|
||||
.into_iter()
|
||||
|
|
|
@ -135,7 +135,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
let identifier = m.value_of("identifier").unwrap();
|
||||
let stack = build_pr_stack(identifier, &credentials).await?;
|
||||
|
||||
let repo = m.value_of("repo").unwrap();
|
||||
let repo = m.value_of("repo").expect("The --repo argument is required.");
|
||||
let repo = Repository::open(repo)?;
|
||||
|
||||
let remote = m.value_of("remote").unwrap_or("origin");
|
||||
|
|
Loading…
Reference in New Issue