Git-Repo The ultimate utility for managing services
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!
The problem
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 pip
from pypi
. Then
you’ve discovered a bug in that project, and want to fix it. So you do pip
show foobar
(or the same with npm
, gems
…) to see its repository:
https://github.com/ford_prefect/foobar.git
.
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
https://github.com/ford_prefect
page, and - click on the little
fork
button:
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?
The solution
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
where the X
s matches the gist to get rid of. And you have git hub gist ls
that lists
all your gists!
Choices made
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 (gitlab
, github
…).
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 upstream
remote.
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-repo
as git lab
or git hub
…
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! 📎
I’d be happy to have some feedback either on twitter or on the Github issues.