A newbie’s guide to Git and GitHub
Over the past few weeks, a lot of my friends have asked me on how to get started with git and GitHub. To someone who is new to all this, those two terms could confusing, and the tutorials online bring a whole plethora of new words. So, I’ve decided to share the most simplistic approach to Git and GitHub.
I will be drawing a lot of analogies and making a lot of assumptions in the course of this post, some of which may not be technically accurate, but bear in mind this is for someone who is entirely new to Git and GitHub.
Lets start with defining the two things.
The simplest explanation which I read on one of the forums, was that Git is a technology, while GitHub is a organisation. The reason they’re confused so often, is because GitHub is the largest collection of open source software, as their website claims, so they have been used interchangeably by users. Most of the colleges and resume-building websites would ask you for your GitHub link. They have a similar relationship as texting and sending a message on WhatsApp, or searching on the internet and googling.
Coming back to it, what exactly is version control? There is plenty of stuff you can do with version control. However, the primary function of such a system is managing multiple versions of the source code. I will illustrate the importance of this feature with an example.
Let’s suppose, for a class assignment, you’re working on website. You are maybe new to coding, and you have chosen Flask to write your source code. Now, you worked for two days straight, and you have a pretty good basic framework designed. Now, you want to try out a new feature, where maybe the user can have a dashboard. However, you are unsure about how to do this. So, you get skeptical and you make a “backup” of your code. What you do is, maybe you copy the files and zip it and keep it in a new folder. However, after a few iterations, this process gets messy and repetitive. This is where version control comes in.
With Git, doing this becomes much much easier. Because you’re not storing your files manually, but you’re letting git take care of it. Along with managing the various previous versions, git also allows you some nice little tidbits of data to store along with your commits, or your saved snapshots. This serves as a reference to what has been changed corresponding to that commit. If used well, these features can provide a lot of help to the future you, or someone else who may be reading your post.
Now, coming back to the how. We start at the beginning. Assuming you’ve never heard of git and GitHub. We would need a GitHub account, and the git Command Line Interface for this.
- Getting the git CLI
Git comes with a command line interface for Windows — the Git Bash. You can download it here. You can also use WSL for this, or you can use git in PowerShell (However, the last time I checked this, there were some issues with branches. What are branches? I will write an article on that later). For Linux based OSes, you will have git preinstalled in your terminal.
After downloading it, you need to set a few things to initialize it. Those things being a username and an email. Since Git was developed with collaboration in mind, each commit is associated with a name and an email. This helps in identifying the who-did-what about the code. To set these for the first time, you need to run the following commands.
$ git config --global user.name <your name here>
$ git config --global user.email <your email here>
You can use quotes to string together first name and last name as a single entity.
2. Setting up a repository
Coming back to our example with the Flask app. You may have written a code in a folder, to keep things together at once place. Now, we start with defining a repository (or repo for short). From here, things start getting confusing, as there are multiple paths to do this. So, we are going to look at some of the possible ways to do it, and what is happening with each.
a. A majority of tutorials you will see online will tell you initialize a repository. You can do it with the following command.
$ git init
If things go alright, you will see the following output
Initialized empty Git repository in /path/to/the/project/folder/.git/
Now, what just happened is, you made a repository in your local machine. This will tell the git bash, or any other terminal, that this particular folder is a git repository, and it will support the various git features in that folder. Take a note that nothing has happened with regard to GitHub as of now.
b. Now, once you have this initialized a repository, you can start adding files to it. To do this, if you have initialized it in an empty folder, you have to first copy your source code in this folder. If you have it already, great. Next step would be to run the following command
$ git add <filename>
But since most of the times, we have a lot of files, and it doesn’t make sense to add it all one by one. So, we replace filename with a dot, to add all the files present in that folder
Cloning a repository —$ git add .
What has happened, is that git has now added those files to a staging area. If this is done correctly, you can now see the status by running the git status command.
$ git status
You will get an output something like this
On branch masterNo commits yetChanges to be committed:
(use "git rm --cached <file>..." to unstage)
new file: <filename>
Think of it like a two-step process, where we first stage the changes, and then we commit to those changes.
c. Now, you can commit these changes to the repository through the following command.
$ git commit -m "<some commit message>"
After successful execution of this, you will see the following output.
[master (root-commit) 68e1e3c] first commit
1 file changed, 2 insertions(+)
create mode 100644 <filename>
Now, take a note of the string “68e1e3c”. This is the last few bits of the hash which has been assigned to this particular commit. This is done to uniquely identify each commit.
At this point, note that still, we have not done anything with regard to GitHub yet. We may not even have an account, and we would be able to do all this. All we have done is that we have made a local repository and we have committed some changes to that. Next comes the remote repository, for which we have to go to GitHub and sign up for an account. After logging in, you will see an option to create a repository there as well. Do that, and get done with the initial setup of the repository.
Now, remember the confusion which I mentioned earlier? This is the part where people get confused. Since we have initialized a repository on the GitHub website, it may ask us to add a README.md file, as well as a License and a .gitignore file. While adding those things is a good practice for writing open-source code, if you’re trying to link that remote repository to your local one, the contents of both the repositories will be different.
To tackle this, the simplest thing would be to pull the changes from GitHub to your local repo. We will get to this option in a bit. But another way to approach this could be to create an empty repo on GitHub, with no License, README or anything. Then, once you are done, you will get a unique link to your GitHub repo, which will look something like this.
We need to link this to GitHub to our local repository. We can do this with the following command.
$ git remote add origin https://github.com/<your_username>/<your_repo_name>.git
Upon successful execution, this command will link your local repository to your remote repository. However, still, no code has been transferred to GitHub.
If you have created a GitHub repository with README or License files, you have to pull the changes first, with the following command.
$ git pull origin master --allow-unrelated-histories
The flag at the end tells the git that you have no issues with merging the repositories. This is needed because both the repositories have different version histories, and mostly they won’t have any common files. After doing this, you will see the following message.
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
LICENSE | 21 +++++++++++++++++++++
README.md | 2 ++
2 files changed, 23 insertions(+)
create mode 100644 LICENSE
create mode 100644 README.md
You need not do this, if your remote repository does not have any commits in it.
3. Cloning a repository
This is a workaround to this whole procedure of initializing and adding a repository. This works well if you are starting out a new project, and are doing this at the beginning.
The idea is that git offers a method to download all the files of a repository, in your local machine, or in other words, make a clone of it. The primary purpose of this is to download others’ source code, but you can do this with your own repository and start adding files to it directly.
$ git clone https://github.com/<your_username>/<your_repo_name>.git
Once you have cloned this repository, the local copy is already up to date with the remote repository, and the origin data is already present in .git file. However, the downside is that you cannot use this with repositories you may already be working with. So, doing this at the start of a project is generally a good idea.
Now, once you have copied, it follows the same path as before — adding the files and committing them. However, now your local repository is a commit ahead of your remote repository.
4. Pushing the changes to GitHub
Here comes the most lucrative part of the whole exercise, to push the changes to your remote repository (GitHub repository). To do this, you have to run the following command
$ git push -u origin master
Now, if you’re on Windows, you’ll see a popup asking for your GitHub account details, since changes on GitHub repository will have to have a GitHub account associated with them. Since I am using a Linux based OS, it has given me this prompt in terminal.
Username for 'https://github.com': <username>
Password for 'https://<username>@github.com':
Once you do this correctly, you will see something like this as output
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 845 bytes | 422.00 KiB/s, done.
Total 8 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), done.
8fc5cb7..87324d6 master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'
And with this, you have pushed your changes to your GitHub repository.
But we have still not used git for the purpose which it was created, that is version control and branching. I will write an article for that later.
Thank you for reading.