Master Git in 15 minutes

What is Git

By far, the most widely used modern version control system in the world today is Git. Git is a mature, actively maintained open source project originally developed in 2005 by Linus Torvalds, the famous creator of the Linux operating system kernel. A staggering number of software projects rely on Git for version control, including commercial projects as well as open-source. Developers who have worked with Git are well represented in the pool of available software development talent and it works well on a wide range of operating systems and IDEs (Integrated Development Environments).

Having a distributed architecture, Git is an example of a DVCS (hence Distributed Version Control System). Rather than have only one single place for the full version history of the software as is common in once-popular version control systems like CVS or Subversion (also known as SVN), in Git, every developer's working copy of the code is also a repository that can contain the full history of all changes.

In addition to being distributed, Git has been designed with performance, security, and flexibility in mind.

Installing Git


To check if you have Git installed to run in your terminal:


If you don't have it, follow instructions on https://git-scm.com/downloads. Mac users can install it with brew: brew install git

Configuring Git


There are just a few things we want to configure:


You can see the current global configuration with:


Git stores configuration in plain text and, if you prefer, you can edit a global configuration directly in ~/.gitconfig or ~/.config/git/config.

As the command suggests, removing --global would make these commands scoped to the current folder. But to test that out we need a repository.


Creating new repository


A repository is just a folder with all the stuff you want to track. To create one run:


This command creates a folder .git inside gitexample folder. That hidden .git folder is what makes a repository: all local configuration and changes are stored there

Making changes


Let's create something in the repository:


If we ran git status, we'll see the newly created untracked file:


As the output suggests, let add the file. It can be done directly with:


If you check on the repository status now, you'll see that the file is added (aka staged), but not yet committed:


To record the changes, let's commit them:


Pro tip: git commit -m  is a shorthand command, you can use git commit to open editor (mostly vim) and provide a detailed commit description instead.

Let's check the changes with:



It will show something like:


Creating branches


Having a separate version of the initial code can be useful in a lot of situations: e.g. when testing out a feature you're unsure about or to avoid code conflicts when working together. That's exactly what a git branch is: it grows from a particular point in history.


To create a branch run git branch NAME and to switch branch run git checkout NAME. Or simply:



Let's change something in the hello.txt file and commit the changes:


Now let's switch back to the main version:


As you can see, the file contents are still the same as they were. To compare branches we can run:


Let's make changes in the main branch as well:


Now let's try to combine the changes:


Because the file was changed in the same place twice we got a conflict. Look at the file:


There is also a tool to see changes separately:


You can manually edit the file and commit the changes, but let's imagine we only want one of the versions. We'll start with aborting merge:


And restarting merge with "theirs" strategy, meaning that in case of conflict we'll use whatever incoming branch insists on:


The opposite to this strategy is "ours". Merging both changes together will require manual editing (or use of git mergetool).


To see a list of all branches run:



Finally, to delete the branch run:


Rebasing branches


Branches "grow" from a particular point in the git history, rebase allows changing that point. Let's create another branch and add some changes to hello.txt once more time:


Now, let's come back to the main branch and add changes there:


To replay the changes we made in main to story branch run:



You can see new file created in main branch being added to story branch:

Word of caution: do not rebase branches that someone else might have used, e.g. the main branch. Also, keep in mind that every history manipulation on a remote repository will require forcing these changes to take effect.

Remote repository 


If you haven't yet, create a GitHub account, login and create a new empty repository (private or public).


Assuming the repository name was "example" run the following command (change to your username):



You can refresh the page and see files in main branch. To push all local branches to remote repository run:



Let's edit something on GitHub: just click any file and the pencil icon. Add a line with any text you want and press "Commit changes".


Now run this command locally to get the remote changes:




Managing uncommitted changes


If you want to save your local changes for later you can use git stash:




Now you can use the following command to check, apply or discard these changes:



Pro tip: you can use stash number, i.e. git stash pop 0 to apply a particular stash or git stash drop 0 to drop it.


If you want to discard all local changes and simply restore the repository to the last committed changes to run:




Managing committed changes


Once you create a commit, this change is saved in the local git history. As mentioned before, all changes affecting remote history would require a git push --force. Keep it in mind for all following commands.


Let's start with editing the last commit message :



How about we reset everything to the very beginning?

To find the ID of the very first commit run this command and scroll (with arrow down) to the very end:


Now run this to reset the repository, but keep all changes unstaged:


As opposed to it, you can also make a hard reset and get rid of all the changes with git reset --hard COMMIT

There are several other types of reset that you can learn from Git Documentation

Aliases


Most of the times you'll be using just a handful of command (checkout, add ,commit, pull, push and merge mostly), but are some things you might want to have around for "just in case".


One way to store those are git aliases. To configure an alias just set it in a config.


For example, one alias I use a lot is git tree, it prints a nice history log in a form of a tree:



Another useful alias deletes all merged branches:


As you can see it's prefixed with "!", which allows us to use any command, not only git commands.

That's all for today, hope it helps in your developer journey. 

As always, feel free to share your thoughts and feedback in the comments. Till the next time!


Follow me on GitHub: Madhusha Prasad






Comments

Popular posts from this blog

Bootstrap for beginners

Html History

History of the web browser