This post is part of a series:
In the previous post, we have seen how to work with branches in Git. And now, in this post, we are going to cover how to work with a remote repository. Therefor, we are going to use GitHub. So, if you don’t have an account yet, you need to create one (which is free) to follow along with the tutorial.
Side note: We are only using the remote to share our project publicly and to have a back-up of it in the cloud. So, this post is not going to cover how collaboration via GitHub works.
Connecting the local Repo to the remote Repo
Once we have an account on GitHub, we can start creating repos. Therefor, we need to click on the plus sign in the top right corner and click on “new repository”.
See slide 1
On the next page, we need to fill out some information about the repo.
See slide 2
We need to give it a name. So, let’s call it “Tic Tac Toe Game”. After that, we can write down a more detailed description if we want to. Then, we need to choose if the repo should be public or private. We choose public so that other people can find it.
And lastly, we are not going to tick the box to “Initialize this repository with a README”. And that’s because, just like it is stated above that, we can skip this step if we are importing an existing repository. That’s exactly what we do because we have already created our project.
When we are done with that, we can click the green “Create repository” button. This brings us to a new page.
See slide 3
And with that, we have created an empty repository. So now, we need to populate it with something. And GitHub provides us 3 different ways of doing that. And we need to choose the second option because we already have an existing repository.
So, we simply need to run the two commands, that are given under this option, in our command line.
See slide 4
Here, the actual command is “git remote add”. This command connects a “remote repository”, which is the repo on GitHub, to our “local repository” that we have on our computer. Then, we can give the remote a name. In this case, it is “origin”, which is the default name for a remote (just like “master” is the default name for the main branch). And lastly, we need to specify where the remote lives. In this case, it is at “https://github.com/SebastianMantey/test-repo.git”.
Now, the remote repo is created but still empty.
See slide 5
So, let’s push the commit history from our local repo to the remote. That’s what the second command is for:
See slide 6
Here, the actual command is “git push”. Then, we need to specify where we want to push to. In this case, we push to “origin”, so to our remote. And then, we need to specify what we want to push. Here, we want to push the “master” branch of our project. The “-u” option makes sure that our local “master” branch is going to track the remote “master” branch. What that exactly means we will see later.
And if we run the command, then we will push our local “master” branch to the remote repo (side note: if you push for the first time to GitHub, a window should open where you have to pass in your GitHub user name and password).
See slide 7
So now, our local commit history is also available on the remote repo.
See slide 8
And if we refresh the browser, we can see that our project is now available on GitHub.
See slide 9
Pushing to GitHub
So now, to see what a typical workflow with such a remote repo looks like, let’s say we keep working on our project (coding session 7 in “code_snippets.py”). And the next thing that we want to do is to make the game board look somewhat nicer.
See slide 10
Namely, there shouldn’t be any square brackets and zeros depicted. And instead of using ones and twos, we would like to actually use “Xs” and “Os”. To do that, we adjust our code.
See slides 11-12
So, let’s see if it works.
See slide 13
It does. So, let’s create a new commit.
See slide 14
And now, let’s run “git log”.
See slide 15
Here, we can see that our local repo is now one commit ahead of our remote repo. We can also see that by running “git status”.
See slide 16
This is why we used the “-u” option of the “git push” command earlier to make sure that the local “master” branch tracks the remote “master” branch. Otherwise, we wouldn’t get this information from “git status”.
And what this now means is that locally, we have the most up to date version of our game. The one with the “Xs” and “Os”. But on our remote, the one that other people can access, we still only have the version with ones and twos. If we click on the “game.py” file on GitHub, we can also see that.
See slide 17
So, let’s make sure that we also have the most up to date version of the game on the remote repository. Therefor, we simply need to push our local “master” again to the remote.
See slide 18
So, let’s run “git log” again.
See slide 19
As we can see, the local “master” branch and the remote “master” branch are at the same commit. So, they are in sync. We can also see that by running “git status”.
See slide 20
And if we refresh the browser, we can see that the players are now named “X” and “O”.
See slide 21
So, that’s how we can push changes to GitHub. And here is a summary of what we have done:
See slides 22-24
Pulling from GitHub
But we can’t only push changes, that we have made locally, to GitHub, we can also do that the other way around. So, we make changes on GitHub and then we want to pull those changes to our local repo.
Side note: Here I have to say, though, that this is probably not a typical workflow when you are working alone on a project. It is more important when you work collaboratively on a project where other people can also push to the remote. Nonetheless, I would like to show how that works.
So, let’s say that we look at our repo on GitHub and there we realize that there is a typo in the README.
See slide 25
It says “craete” instead of “create”. So, since fixing this is only a very minor change, we can do it right on GitHub itself. Therefor, we click on “README.md”.
See slide 26
On the next page, we then click on the “edit this file” button.
See slide 27
Here, we can fix the typo.
See slide 28
And then, we scroll down, create a commit title and click the green “Commit changes” button
See slide 29
With that, we have now created a commit on GitHub. So, the remote “master” branch is now one commit ahead of our local “master” branch. But, if we run “git log”, we can see that “master” and “origin/master” are still at the same commit and that the “fix typo in README” commit isn’t there.
See slide 30
That’s because the local and remote repos don’t sync up automatically. They only get updated when we explicitly tell them to sync.
So, as we have already seen, for the case that our local repo is ahead of the remote, we use the command “git push” to update the remote repo. And, the other way around, if the remote is ahead of the local repo, then we can use the command “git fetch”.
See slide 31
Here, we have to specify from where we want to fetch. So, in this case we fetch from “origin”.
After running the above command, let’s run “git log” again.
See slide 32
And here, we can see that we now also have the “fix typo in README”-commit locally and that “origin/master” is one commit ahead of “master”. We can also see that by running “git status”.
See slide 33
So, the “git fetch” command doesn’t automatically update “master” to be at the same commit as “origin/master” (like “git push” did the other way around). This means that locally we still have the typo in our README.
See slide 34
So, let’s now update our local “master” branch, i.e. we are going to merge in the changes from “origin/master” in to “master”.
See slide 35
And if we now run “git log” again, we can see that “master” is up to date with “origin/master”.
See slide 36
So, that’s how we can pull changes from GitHub. And here is a summary of what we have done:
See slides 37-40
As a side note, I would like to mention that we could have also ran the command “git pull origin master” to update the local repo. This would have automatically executed the “git fetch” and the “git merge” commands. But since this automatically merges “origin/master” into “master”, this gives us a little less control.
And with that we have now reached the end of this tutorial. And since we have now seen a lot of different commands, I have created this overview slide.
See slide 41
Here, I have listed all the commands that we have used in the tutorial and I arranged them according to the topics that we have covered.
First, we looked at version control in general and we have seen how we can inspect the commit history of an existing project. Then, we have seen how to create a commit. After that, we have seen how to work with branches. And finally, we have seen how to work with remotes.
And here are all the commands together with the options that we have used:
See slide 42
PS: I will delete the “Tic-Tac-Toe-Game” repo from my GitHub account again. Instead you can download the “Git-Tutorial” repo if you want to check it out. It is basically the same.