Git Hosting (GitLab and GitHub)
In the previous chapter we covered local usage of Git. We learned how to keep our code versioned using it, how to go back in time, how to undo changes, how to keep separate branches of our code to work in more than one thing at a time, and how to move changes from one branch to another. That is a lot!
In this chapter we will continue doing more or less the same thing, but with a twist: how about having branches that don't live in your own computer?
If you worked in a project with someone else, you could each work in your own copy of the repo, and then sync changes with each other!
Or, if there was a company that provided the service, there could be a "central" copy of your repository, and you could both sync your codes with it, and then no matter how many people worked on the project, all of them could cooperate!
Good news! There are a number of companies that provide that service. For free! I am going to focus on GitLab mostly because they provide not only a service to give you public repositories of your projects for free, but also private ones for things you don't want to share.
Another good choice is GitHub -- their platform is the most popular, hosting projects from many communities, in many languages, and frameworks. GitHub is a great place to go explore, and to find contributors. The only drawback is that private repos are not free. Yet another alternative is BitBucket.
When I am giving specific instructions, I will give alternatives for GitLab and GitHub. They are very, very similar.
Until now you have been using what is called a local git repository. The most important thing a git hosting service gives you is a remote repository. It's basically the same thing, with branches and commits and all that, but in someone else's machine.
What can you do with a remote repository?
- "push" changes to it. You change something locally, then "push" it to the server, and now the server has a copy.
- "pull" changes from it. If someone pushed a change to the server, you can "pull" it from the server into your local repository.
When you combine those two things, you can collaborate. Suppose there are two persons developing a project. One creates a change, pushes it to a common remote repository, then the other pulls it into his own local repository, and voilá, they are both working on the same code!
Create an account for yourself. Mine is
ralsina so I will use that in the
examples, you use your own!
The details on how to setup the account I leave to you, they are no different to any other online service. Except for SSH keys.
All the communication between you and the site is private and encrypted. To do that, you need to give the site your "public key". This also allows the site to know you are who you say you are. You can sign your code using your keys.
So, if you have a
~/.ssh/id_rsa.pub file, good. If you don't you can create one
with this command:
ssh-keygen -t rsa -C "firstname.lastname@example.org"
And then that will create the
~/.ssh/id_rsa.pub file. That file is your public key. There is also one without the
.pub extension. That is your private key. NEVER SHARE THAT ONE WITH ANYONE. EVER EVER.
REALLY NEVER EVER SHARE THAT ONE.
Open that public file in a text editor and copy its contents.
- On GitLab:
- Top-right user menu ▶ Settings ▶ SSH keys ▶ Paste the public key.
- On GitHub:
- Top-right user menu ▶ Settings ▶ SSH and GPG keys ▶ New SSH key ▶ Paste the public key.
Creating a repository and pushing to it
Creating a new repository your project is simple. Go to:
- On GitLab:
- Top plus sign menu ▶ New project
- On GitHub:
- Top plus sign menu ▶ New repository
Then, you can pick a name for your new project and enter a description. Since we've already created our Git repository and added commits in the previous chapter, you should start from a blank slate (without any README files, without using templates).
Now, you can tell Git about the location of your remote repository. Grab the SSH URL displayed on the repository page, and in your existing repository, do this:
1$ git remote add email@example.com:ralsina/my-new-repo.git 2$ git push -u origin master
-u switch means that
git push and
git pull will operate on the
origin/master branch when you're on
git push completes, you can refresh the browser and see your changes.
One of the most common uses of these platforms is to collaborate with an existing project. For example, this very book is available as a git repository at https://gitlab.com/ralsina/boxes-book
Let's see how you would help a project fix a bug.
Find a problem, or a missing feature
Here is an intentional typo: "the cow is wite".
Oh, the horror!!!! A typo! Surely you have to provide the author with the fix for such a critical problem. Since this is the first time you are collaborating, you don't have permission to make changes in the "original" repository, so you will have to fork it.
To fork a repository in GitLab or GitHub: click on the "fork" button.
This way, you can change things, push changes to the server, and then others can take those changes and adopt them. Or you can just take the part of the book I have written so far, and finish it yourself.
So now there will be a fork of the project at https://gitlab.com/YOURUSER/boxes-book where of course YOURUSER is actually ... your user.
I will use a "ralsina1" account to pretend to be someone else trying to do this.
Now you need a way to get a copy of that repository into your own machine so you can fix that horrible typo.
That is called cloning the repository. First, you need the cloning URL. In
this case it is
firstname.lastname@example.org:ralsina1/boxes-book.git and it's different for
- In GitLab, you can see itright below the name of the project, and you can copy it by clicking on the clipboard icon.
- In GitHub, click "Clone or Download" ▶ Click on the clipboard icon.
Once you have the clone URL:
1$ git clone email@example.com:ralsina1/boxes-book.git 2Cloning into 'boxes-book'... 3remote: Counting objects: 10689, done. 4remote: Compressing objects: 100% (1722/1722), done. 5remote: Total 10689 (delta 9103), reused 10366 (delta 8829) 6Receiving objects: 100% (10689/10689), 16.83 MiB | 2.37 MiB/s, done. 7Resolving deltas: 100% (9103/9103), done.
And there, in the
boxes-book/ folder is your very own copy of the
Fix and Push
Once you have a copy it's just as if you created it yourself, you can change it, create branches, do commits, etc. If you push changes, they will go to your own fork, your own copy of the repository in GitLab.
So, let's find where that typo is:
1$ grep wite -Ril 2src/part3/git_hosting.md
So, I edit that file and fix it. Of course now I need to commit it.
1$ git commit -a -m 'Fix typo' 2[master ca3b37a] Fix typo 3 1 file changed, 1 insertion(+), 1 deletion(-)
And push it:
1$ git push 2Counting objects: 5, done. 3Delta compression using up to 4 threads. 4Compressing objects: 100% (5/5), done. 5Writing objects: 100% (5/5), 431 bytes | 431.00 KiB/s, done. 6Total 5 (delta 4), reused 0 (delta 0) 7To https://gitlab.com/ralsina1/boxes-book.git 8 fe5b41d..eaa053d master -> master
And that's it, it is now in GitLab, in your copy of this book! But how do I give the fix to the original author? Via a Pull Request
Pull Request / Merge Request
A pull or merge request is basically a request that someone else (in this case, the original authors) pull a change from your copy of the project and merge it in his version.
Remember that pulling is basically making a copy of changes.
So, basically "please, author, take this fix I did and merge it in your project".
Let's create one!
- In GitLab: click on "Merge Requests" ▶ "New merge request"
- In GitHub: click on the "New pull request" button.
A Pull request is formed by choosing:
- A "source" repository and branch.
- A "destination" repository and branch.
Then the difference between them will be calculated, and offered as a change for the destination repository owners, which they can adopt by pressing a button.
- In GitHub, the destination is called "base"
- In GitLab, the destination is called "target"
You will have to write a description of what you are changing. That is the channel you are using to communicate with the creators of the project, so be clear, remember that you have very little shared context, so it's better to explain too much than too little.
Here is how that screen looks in GitLab:
Then I click on the submit button and that's it, I submitted it!
How does that look on the other side, to the original author?
From that screen I can ask questions about the change, see what specific files are changed and how, and either accept the change (and merge it) or reject it and close the request.
In this specific case, I will not accept it because I want the typo to stay there. In fact, feel free to fork the repo, find a typo and provide me with a fix. If you don't find any (yeah, right!) just use the same one from the example! I would love to see your merge request!
You can see mine here: https://gitlab.com/ralsina/boxes-book/merge_requests/8
And that is the end of it. You saw a problem, you created a fix, you gave the fix to the original author. That is the core of online collaboration in software development.
If you are working in a company, developing software? There will be a similar process to implement things, or to fix bugs.
If you want to help those who brought you nice things for free on the internet? If they have their code (or books!) hosted on a git provider, you can do just that.