Over the last decade, we’ve seen many online platforms offering repository hosting, like SourceForge, Savannah, Gitorious, Google Code, Github, Launchpad, Gitlab… And a bunch of others I fail to remember. They offer a great service to help developers and the FLOSS community to make it easy to find and share code on a project.
Though, they all always sucked at one thing, it’s to integrate nicely in the flow of coding. Some have a GUI tool, others integrate more or less in your editor (or IDE), and that’s rarely the ones you’re using for your work.
The git utility has a rather well designed interface to make it easy to remember, extend, and/or customize. So, out of frustration of having to swing between my code and a web-page to issue some actions on a repository. I figured I could write a tool to exploit those services APIs and make their features available where they belong, in your shell!
Let’s say you’ve discovered a super neat python project you’ve installed and
love, that’s called
foobar. You’ve installed it using
you’ve discovered a bug in that project, and want to fix it. So you do
show foobar (or the same with
gems…) to see its repository:
Then, you check it out, with:
git clone https://github.com/ford_prefect/foobar.git
then you watch the code, create a branch:
git checkout -b bugfix/nasty_one
fix it, update the tests, and install it locally, and then you’ve got an updated version of the code on your machine. Nothing out of ordinary here, that’s how life works…
…At least as long as you’re not the sharing type. Otherwise, you know you’ve got to contribute your patch back to the community, by sending a patch on the repository.
But it’s not as simple as doing a
git format-patch and mailing it, why would it?
Nah, you need to:
- open your browser on github, at the
- click on the little
Then once the repository added, you have to change the remotes, so yours is the origin and the other one the upstream:
% git remote origin set-url https://github.com/your_name/foobar.git % git remote add upstream https://github.com/ford_prefect/foobar.git
(which nobody does, because who remembers the
git remote syntax?
That being done, you then got to push your branch onto your remote, as a new branch. Then, you have to open your browser and click on the create pull request button.
And then, only then, the original author will get notified of your change and will be able to review your patch, and eventually integrate it.
So basically, you’ve got to switch between your editor, the browser and the command-line, and do like five operations across those, where you really meant to do three actions. And then, what about pushing that code to gitlab? Or bitbucket?
Over the last ten years, I always found each time I was doing those actions, I was being frustrated by having to do those useless operations, and wanted to do something to get rid of those.
I eventually did:
Now, what I’m doing for the same thing as above is:
% git hub clone ford_prefect/foobar % # hack, hack, hack! % git co -b 'bugfix/nasty_one' % git hub fork % git push github bugfix/nasty_one % git hub request create 'Fixed a nasty bug' --message 'Fixing issue with the thing'
And voilà! 🙌
If you want to create a repository on Gitlab, and push the code base over there? Well, easy:
% git lab create foobar % git push gitlab master
As an extra, if while you’re debbuging you’re running into an unreadable stacktrace or compilation error:
% git hub gist create 'Awful compilation error… Help me out' compilation.log
And of course, once your output is made irrelevant, you can simply delete it by doing a:
% git hub gist delete https://gist.github.com/XXXXXXXXXXX
Xs matches the gist to get rid of. And you have
git hub gist ls that lists
all your gists!
Because everybody can manage their Git repository the way they prefer,
I decided that git-repo would never ever mingle with the
origin remote. The
origin remote is a special git convention that can change the behaviour of
other tools, so it’s better left in the hand of the user!
Another reason for
git-repo to not decide what
origin is, is that the tool
is made so it does not favour a service over another one, thus it makes a lot
more sense to have each service have a custom label (
Then one could consider using
origin as the base remote for the fork. But I believe
that would be wrong as well, because in git convention, the
origin is the remote
you’re working with, and the upstream is most of the time read only. Which is why
the upstream is kept as the
Finally, git-repo comes with a nice hack: the
all remote. When you have several
services configured as a remote for your current repository, they are as well configured
as a single remote target: the
all remote. So when you do:
% git push all master
You’re pushing the branch master on all your remotes at once! So of course it’s no
magic and you’ll need to synchronize your local remote indexes (using
git fetch --all)
so they’re kept up to date with the different remotes, but it’s easier than doing as
many pushes as you have remotes!
Status of the project
For your first time run, I have written a wizard, that you can launch using:
% git-repo config
and will update your
~/.gitconfig with the relevant configuration details, and
define the aliases so you can call
git lab or
As a final word, this is the first published version, and the second prototype
I wrote (thus the
1.x version scheme). I consider it being still in a beta
phase as I still believe the CLI API ergonomy for all the commands is still
perfectible so they feel natural to type and remember. That’s the reason why
I did not split the project into submodules, and we have this huge help screen
that has it all.
To know more about the tool, you might want to check a series of screencasts I wrote:
- New project
- Delete project
- Fork a project! 🍴
- Got PR? 👋
- Wanna gist with me? 📎
- ⑥ There’s more to gist! 📎