GitHub Standard Fork And Pull Request From Inside Emacs

1 Executive Summary

Collaborating via GitHub (and similar platforms) requires understanding and following a somewhat standardized fork, create, push workflow. Most of the gory details of this workflow typically get hidden by instructions of the form

Sign in to GitHub in your browser and /push/ the button on the  top-left

or something similar. I live exclusively in Emacs and use Chrome as the weapon of last-resort, this article details how to perform the afore-mentioned GitHub collaboration workflow from within Emacs. Caveat — you may still need to resort to Chrome or Firefox to set up GitHub tokens etc.

2 The Standard GitHub Workflow

The GitHub collaboration workflow is documented (if somewhat sparsely) on GitHub, and it's augmented by many excellent tutorials on the Web. I will avoid repeating that information, other than to link to them below and point out that reading those is essential to build a clear mental picture of how things work. The remainder of this article will focus on how to achieve the equivalent without having to push buttons on the GitHub web site.

3 Collecting The Needed Tools

Here are the tools I needed to achieve the goal of achieving the above workflow from within Emacs and without resorting to a Web browser.

  1. Package Magit from Melpa.
  2. Package Magit/Forge from Melpa.
  3. Command-Line tool hub from GitHub
  4. Newer Command-Line tool gh from GitHub.

Command-line tools gh and hub are written in go and implement the GitHub API. At the time of writing, hub appears more complete, but gh is catching up fast.

4 Implementing The GitHub Workflow

I'll use a concrete example to avoid introducing additional confusing terminology. In my own learning journey, I often got confused by terminology such as name, remote, etc. each of which were being used in a specialized sense.

4.1 Task:

Create a Pull-Request to project speech-rule-engine from user zorkow/ — the project repository is Speech Rule Engine from user zorkow.

Fork the project you wish to contribute to. I found multiple ways of doing this (eventually).
  1. magit/forge inside emacs:

This invokes command M-x forge-fork which prompts for two name arguments. The meaning of those arguments are somewhat non-obvious which is why I failed initially. To use it successfully, set Forge Custom option forge-owned-accounts to your GitHub user-id — in my case tvraman. Note that this variable can hold a list of GitHub user-ids that you use.

(setq forge-owned-accounts '(("tvraman")))

With the above in place, go to where you have the source repository checked out, in my case:

cd ~/sources/zorkow/speech-rule-engine

and open the magit status buffer by executing

M-x magit-status

and execute Emacs command forge-fork — by default magit/forge binds this to 'cf. The minibuffer shows the user-id you set up in forge-owned-accounts/ earlier as the default, press RET to accept the user-id value for both the fork and remote arguments.

  • The above flow works once it's all set-up — note however that if you are happier to just do this at the shell, you can use either hub or gh — read the documentation for those commands. Either way, you now have a copy of the speech-rule-engine project under your list of GitHub repositories — in my case at
Next, git clone the fork you just created. This is just a regular clone operation, in my case I did:
mkdir -p ~/sources/tvraman; cd ~/sources/tvraman; git clone
Create Your Changes
Follow the steps from the earlier tutorials to do your work, i.e., creating a feature-branch to hold your changes,etc. Note that all this work is being done in your fork, i.e., in this example, within ~/sources/tvraman/speech-rule-engine.
Create Pull Request
When ready, open the magit-status buffer for your fork, and create the pull-request using magit/forge — in the magit status buffer, type 'cp.
Uploading The Pull Request
Now, you need to send the pull-request to the author of the project you are contributing to — this is again one of those steps that all the docs talk about pushing a button on The easiest means I found to do this was via command-line tool hub:
cd ~/sources/tvraman/speech-rule-engine; hub pull-request 

Assuming you have emacsclient configured as your EDITOR, this opens a standard commit-like message buffer that lets you complete the action. Result: a new, shiny pull-request shows up in the target project — in this case in zorkow/speech-rule-engine.

Date: 2020-05-28 Thu 00:00

Author: T.V Raman

Created: 2020-05-28 Thu 09:54