Git 101

Hey! Today I'll write about Git, a tool that will allow you to control your project files and to manage simultaneous changes when working on a team, avoiding bottlenecks. For now, I will keep it simple and on the next article, I will talk about commands a bit more sophisticated.

Brief history

Git history starts when one of the Linux kernel developers (Andrew Tridgell) tried to reverse-engineer the source control management tool (SCM) called BitKeeper. That broke the free using agreement of the tool, pushing Linus Torvalds (Linux creator) to create a customized SCM tool so they could keep working on their projects because the other SCM's available didn't seem good enough to him. Here is a link to a interview with Linus celebrating 10 years of Git where you can see more about Git history.

Since 2005, the year that 1.0v was released, Git is becoming more and more used not only for big companies but even for academic/personal purposes.

Git is pre-installed on mac, so we can skip this step and create a remote repository, a place where you can upload your project files and access it everywhere (e.g: GitHub or Bitbucket) Let's suppose that your username on GitHub is Tom and your repository name is Example.

1 — Configure your Git to your e-mail using:

$ git config --global user.email tom@gmail.com

2 — Navigate to your project folder

$ cd Desktop/Projects/Example

3 — Initialize git in the same path:

$ git init

Now, if you use "ls -a" to see the hidden files, you might see some files such as .DS_STORE and .git. The cool thing about git (which Linus kinda copied from BitKeeper) is that it gives you a local and a remote repository allowing you to work on a project locally with a different state from the remote one.

4 — Link your local repository to your remote repository

$ git remote add origin https://github.com/tom/Example.git

This last command just linked your local repository on this folder to your remote repository located on the URL https://… which we have just created. Now to see the changes (since you never uploaded anything, everything is a change) use:

$ git status

You will be able to see all the files that you touched, created, removed or changed. Depending on your bash preferences, there will be some green/red colored file paths. The reason why they are colored is to tell you what is staged and what is unstaged. Basically what you stage (next command), is what you are including on your next commit. Then, you might want to stage everything (or not), and you can…

5 — Stage all the changes using:

$ git add .

You could have also used the following command (which is preferable) in case you didn't want to add all of your changes but just a part of them:

$ git add Path/To/File

To unstage your files, use:

$ git reset

And all of your added changes will be back into the unstaged area, you still have them on your project, but they are not added to the current commit anymore. Now if you want to get rid of the modifications use:

$ git checkout -- .

If you knew you already wanted to get rid of it before removing it from the current commit, you could have just done:

$ git reset --hard

The 'hard' flag will ignore your changes and really go back to the previous state. If you are re-setting commits till a certain point but you want to keep your file changes on the unstaged area, use the flag 'soft'.

$ git reset HEAD^ --soft

The "^" means one commit back, but you can change this for ~N where N is the number of commits you want to go back, example:

$ git reset --hard HEAD~3
This is more or less what you have now — like a box with everything you did.

6 — Create a commit with a comment.

$ git commit -m"Here are my high school books"
Now the box is closed with a tag — let’s send it to your storage house and keep it there!

But you want to get rid of it so you can pack your next changes. Let's dispatch this to a storage house, put it in your basement or…

7 — Push it to the repo using:

$ git push origin master

If we check what we just did, we can see that on the end of the command we used 'origin master' but why? By using 'origin' we mean that the following word is a remote branch — which in this case is called 'master'. Git automatically created a branch for you called master but you don't have to keep working on it, we will see more about it in a second.

Done all of the previous steps, you might have uploaded your files/changes to the remote repo. Now supposing that your computer was completely destroyed, stolen or simply you just want to access your project from a different computer, just follow the next steps:

Now John wants to clone (have access/download) your project, so he can easily do this by going to the path where he wants to store the project:

$ cd Desktop/John/Projects
$ git clone https://github.com/tom/Example.git

If this is a public project (it is in our case), John will be able to clone the current remote state of this project but now locally and than he will have it just like Tom.

The thing is: now that both Tom and John have the project, both can do separate changes on it simultaneously just like when Tom did commits and pushed it. They can work on the same branch by pulling the differences made before every commit like if John just changed something and now he wants to push it to the repo, before he pushes it, pull the differences using:

$ git fetch
$ git pull

Or, they could work on separate branches which is the easiest way and also a good-practice. First of all, the master branch should be used for releasing versions, and these actions we did before should be done on a separate branch usually called dev or development. To make it even more organized, Tom and John could work on feature branches that would be checked out from the develop branch.

"topic" is a branch from Tom for example called: tom-fixes-welcome-screen. They could branch out from any branch using:

$ git checkout -b tom-fixes-welcome-screen

After Tom finished his changes for this specific issue, he can merge this branch into develop branch using:

$ git checkout develop
$ git merge tom-fixes-welcome-screen

So now you probably noticed that you can navigate through the branches using:

$ git checkout branch-name

So, for now, that's it. With this commands, you can go on until… well until you face merging conflicts or a situation when you need to cherry-pick a commit from a branch to another or… there are plenty of stuff to talk about still, but I will keep them to the next article so if you think this was useful you will see that this is just a small part of what you can do using git.