• Stars
    star
    647
  • Rank 69,579 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created about 6 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Submit stacked diffs to GitHub on the command line

ghstack

Conveniently submit stacks of diffs to GitHub as separate pull requests.

pip3 install ghstack

Python 3.8 and greater only.

How to setup

Go to github.com Settings→Developer Settings→Personal Access Tokens and generate a token with public_repo access only. Create a ~/.ghstackrc as shown below:

λ cat ~/.ghstackrc
[ghstack]
github_url = github.com
github_oauth = [your_own_token]
github_username = [your_username]
remote_name = upstream [if remote is called upstream and not origin]

How to use

Make sure you have write permission to the repo you're opening PR with.

Prepare a series of commits on top of master, then run ghstack. This tool will push and create pull requests for each commit on the stack.

How do I stack another PR on top of an existing one? Assuming you've checked out the latest commit from the existing PR, just git commit a new commit on top, and then run ghstack.

How do I modify a PR? Just edit the commit in question, and then run ghstack again. If the commit is at the top of your stack, you can edit it with git commit --amend; otherwise, you'll have to use git rebase -i to edit the commit directly.

How do I rebase? The obvious way: git rebase origin/master. Don't do a git merge; ghstack will throw a hissy fit if you do that. (There's also a more fundamental reason why this won't work: since each commit is a separate PR, you have to resolve conflicts in each PR, not just for the entire stack.)

How do I start a new feature? Just checkout master on a new branch, and start working on a fresh branch.

WARNING. You will NOT be able to merge these commits using the normal GitHub UI, as their branch bases won't be master. Use ghstack land $PR_URL to land a ghstack'ed pull request.

Structure of submitted pull requests

Every commit in your local commit stack gets submitted into a separate pull request and pushes commits onto three branches:

  • gh/username/1/base - think of this like "master": it's the base branch that your commit was based upon. It is never force pushed; whenever you rebase your local stack, we add merge commits on top of base from the true upstream master.

  • gh/username/1/head - this branch is your change, on top of the base branch. Like base, it is never force pushed. We open a pull request on this branch, requesting to merge into base.

  • gh/username/1/orig - this is the actual commit as per your local copy. GitHub pull requests never sees this commit, but if you want to get a "clean" commit all by itself, for example, because you want to work on the commits from another machine, this is the best way to get it.

Developer notes

This project uses Poetry, so after you've installed Poetry itself, run this command in your clone of this repo to install all the dependencies you need for working on ghstack:

poetry install

Note that this installs the dependencies (and ghstack itself) in an isolated Python virtual environment rather than globally. If your cwd is in your clone of this repo then you can run your locally-built ghstack using poetry run ghstack $ARGS, but if you want to run it from somewhere else, you probably want poetry shell instead:

poetry shell
cd $SOMEWHERE
ghstack $ARGS

Testing

We have tests, using a mock GitHub GraphQL server! How cool is that?

poetry run python test_ghstack.py

That runs most of the tests; you can run all tests (including lints) like this:

poetry run ./run_tests.sh

Publishing

You can also use Poetry to publish to a package repository. For instance, if you've configured your Poetry repositories like this:

poetry config repositories.testpypi https://test.pypi.org/legacy/

Then you can publish to TestPyPI like this:

poetry publish --build --repository testpypi

To publish to PyPI itself, just omit the --repository argument.

Design constraints

There are some weird aspects about GitHub's design which lead to unusual design decisions on this tool.

  1. When you create a PR on GitHub, it is ALWAYS created on the repository that the base branch exists on. Thus, we MUST push branches to the upstream repository that you want PRs to be created on. This can result in a lot of stale branches hanging around; you'll need to setup some other mechanism for pruning these branches.

  2. Branch name does not correspond to pull request number. While this would be excellent, we have no way of reserving a pull request number, so we have no idea what it's going to be until we open the pull request, but we can't open the pull request without a branch.

Ripley Cupboard

Channeling Conor McBride, this section documents mistakes worth mentioning.

Non-stack mode. ghstack processes your entire stack when it uploads updates, but it doesn't have to be that way; you could imagine that you could ask ghstack to only process the topmost commit and leave the rest alone. An easy and attractive looking way of doing this is to edit the stack selection algorithm to look a single commit, rather than all the commits from merge-base to head.

This sounds OK but you try it and you realize two things:

  1. This is wrong, if you exclude the commits before your commit you'll end up with a base commit based on the "literal" commit in your Git repository. But this has no relationship with the base commit that was previously uploaded, which was synthetically constructed.

  2. You also have do extra work to pull out an up to date stack to write into the pull request body.

So, this is not impossible to do, but it will need some work. You have to work out what the real base commit is, whether or not you need to advance it, and also rewrite the stack rendering code.

More Repositories

1

htmlpurifier

Standards compliant HTML filter written in PHP
PHP
2,837
star
2

git-ftp

A quick and efficient way of pushing changed files to a website via FTP
Python
494
star
3

convolution-visualizer

Convolution visualizations
JavaScript
354
star
4

logitext

Beautiful, interactive visualizations of logical inference
UrWeb
144
star
5

compact

Compact regions library for Haskell
Haskell
82
star
6

nvprof2json

Convert nvprof profiles into about:tracing compatible JSON files
Python
67
star
7

torchdbg

PyTorch centric eager mode debugger
TypeScript
43
star
8

csrf-magic

Automatic CSRF protection for PHP applications
PHP
41
star
9

thesis

Thesis
TeX
37
star
10

pl-class-public

Public slides and assignments for CSCI-UA.04900: Special Topics in Programming Languages
JavaScript
36
star
11

stride-visualizer

Stride visualizations
JavaScript
36
star
12

cusec2012-victor

Transcript of "Inventing on Principle", CUSEC 2012 given by Bret Victor
34
star
13

ghc-shake

ghc --make reimplemented with Shake
Haskell
31
star
14

metromaps

Metro Maps as envisioned by Dafna Shahaf
HTML
28
star
15

lr-agda

Logical relations proof in Agda
Agda
23
star
16

onnx-pytorch

PyTorch development for onnx
Python
21
star
17

pytorch-unattached

Tensors and Dynamic neural networks in Python with strong GPU acceleration
C++
20
star
18

tlparse

TORCH_LOGS parser for PT2
Rust
19
star
19

SMT-LIB-benchmarks-pytorch-shapes

SMT-LIB benchmarks for shape computations from deep learning models in PyTorch
SMT
18
star
20

hpd3js

Haskell heap profiling with D3.js
JavaScript
17
star
21

backpack-examples

Backpack examples repository
15
star
22

eff

Inefficient and syntactically unwieldy implementation of algebraic effects in Python using generators
Python
14
star
23

ghc-rts-rust

A reimplementation of GHC's runtime system in Rust
Rust
14
star
24

deepseq-magic

Deep evaluation of data structures without NFData
Haskell
11
star
25

HoTT-coqex

Coq solutions to exercises in HoTT book
Coq
11
star
26

hamt

Hash Array Mapped Tries in Haskell
Haskell
11
star
27

ocaml-cminsketch

Count-min sketch implementation in OCaml
OCaml
10
star
28

hsleak

A collection of space leaks in GHC Haskell
Haskell
10
star
29

ghc-plugin-template

Sample project for GHC core transformation plugins
Haskell
9
star
30

stenomatic

The Stenomatic 9000: a Steno drilling tool
HTML
8
star
31

reflex-backpack

Reflex with Backpack
Haskell
8
star
32

backpack-regex-example

Regex example with Backpack
8
star
33

scheme-hamt

Hash-array mapped trie in mit-scheme
Scheme
8
star
34

jfp-ghc-rts

JFP article on the GHC RTS
8
star
35

ghc-usage

Frontend plugin to print locally used module info
Haskell
8
star
36

stg-spec

Specification of GHC's spineless tagless G-machine and its cost semantics
Makefile
7
star
37

tmr-issue24

Mini-issue of The Monad Reader!
Haskell
6
star
38

tmr-issue20

The Monad Reader: Issue 20
Haskell
6
star
39

nf

NF data type to statically enforce normal form
Haskell
6
star
40

mutsleuth

Mutation detection in Python
Python
5
star
41

hello-plugin

Hello World plugin using GHC API, intended for use with cabal/stack repl
Haskell
5
star
42

groom

Pretty-print Show instances from Haskell
Haskell
5
star
43

SensorSimulator

Sensor Simulator for simulating sensor data in real time.
Java
5
star
44

sake-bot

Bot for transmitting Travis build information upstream
Ruby
5
star
45

triemap

Matching and unification on TrieMaps
Haskell
4
star
46

tmr-issue22

Issue 22 of the Monad Reader
Haskell
3
star
47

hackage-query

Query Hackage for interesting information
Haskell
3
star
48

hoopl

Higher-order optimization library
Haskell
3
star
49

stenowiki

Wiki for steno dictionary entries
Python
3
star
50

breaking-barriers

Research repository for "breaking barriers"
TeX
3
star
51

sigc

Compare implementations with signatures, generate "implements" tables
Haskell
3
star
52

tmr-issue21

Issue 21 of The Monad Reader
Haskell
2
star
53

cpython-metaclass

metaclass in cpython extension
C++
2
star
54

automation

Shell
2
star
55

jpeg-raw-sync

Sync jpeg deletions to raw folder
Rust
2
star
56

rlimits

Support code for Haskell resource limits.
Haskell
2
star
57

ezyang.com

HTML files for my personal website
HTML
2
star
58

bake

Experimental GHC API driver for Backpack
Haskell
2
star
59

haskell-mit6005

Haskell to MIT 6.005 FP pseudocode pretty-printer
Haskell
2
star
60

labeler-github-action

Labeling GitHub action for PyTorch issues/pull requests
JavaScript
2
star
61

ghceye

Haskell
2
star
62

data-dependent-shape-puzzles

Puzzlers regarding data-dependent shapes in PT2
Jupyter Notebook
2
star
63

ghc-cafeteria

Eagerly evaluated all CAFs in your application
Haskell
2
star
64

pdfs

1
star
65

github-delete-old-branches

Delete old branches from GitHub
Ruby
1
star
66

flavr

Mobile website for flavor matching lookups (data not included)
Haskell
1
star
67

cachegrind-labs

some experiments using cachegrind to measure performance
C++
1
star
68

s3-bouncer

Gatekeeper for presigned S3 urls
Python
1
star
69

ci-experiments

CI experiments
1
star
70

hiw16-slides

Slides for Haskell Implementor's Workshop 2016
1
star
71

gh-magic-keywords

magic keyword experiment
1
star
72

stratify

Stratifies the lambda cube into multiple levels
Haskell
1
star
73

pldi14-rlimits-aec

Artifact evaluation for PLDI'14
Haskell
1
star
74

tmr-issue23

Issue 23 of The Monad Reader
TeX
1
star
75

model-tests

Model tests for PyTorch
Python
1
star
76

latency

Some latency benchmarks
Haskell
1
star
77

dividing-the-land

Answer Set Programming solution to Dividing the Land metapuzzle
JavaScript
1
star
78

vimrc

My vimrc
Vim Script
1
star
79

crepe

experimenting with puppeteer
JavaScript
1
star
80

circleci-experiment

testing for circleci
1
star