.. title: Git! First Steps...
.. date: 2019-07-22
.. slug: git-first-steps
.. updated: 2019-07-23
.. status: published
.. tags: git, revision-control
.. category: revision-control
.. authors: Elia el Lazkani
.. description: Getting your feet wet with git from the beginning.
.. type: text

The topic of ``git`` came up recently a lot at work. Questions were asked about why I like to do what I do and the reasoning beind.
Today, I joined ``#dgplug`` on `freenode <https://freenode.net/>`_ and it turns out it was class time and the topic is ``git`` and writing a post on it.

Which got me thinking... Why not do that ?

.. TEASER_END

Requirements
============

I'd like to start my post with a requirement, ``git``. It has to be installed on your machine, obviously, for you to be able to follow along.

A Few Concepts
==============

I'm going to try to explain a few concepts in a very simple way. That means I am sacrificing accuracy for ease of understanding.

What is revision control?
-------------------------

`Wikipedia <https://en.wikipedia.org/wiki/Version_control>`_ describes it as:

    "A component of software configuration management, version control,
    also known as revision control or source control, is the management
    of changes to documents, computer programs, large web sites, and
    other collections of information."

In simple terms, it keeps track of what you did and when as long as you log that on every change that deserve to be saved.
This is a very good way to keep backups of previous changes, also a way to have a history documenting who changed what and for what reason (NO! Not to blame, to understand why and how to fix it).

What is a git commit?
---------------------

You can read all about what a commit is on the manual page of `git-commit <https://git-scm.com/docs/git-commit>`_.
But the simple way to understand this is, it takes a snapshot of your work and names it a ``SHA`` number (very long string of letters and numbers). A ``SHA`` is a unique name that is derived from information from the current commit and every commit that came before since the beginning of the tree.
In other words, there is an extremely low chance that 2 commits would ever have the same ``SHA``. Let's not also forget the security implication from this. If you have a clone of a repository and someone changed a commit somewhere in the tree history, every commit including the one changed and newer will have to change names. At that point, your fork will have a mismatch and you can know that the history was changed.

What is the ``git add`` thingy for?
-----------------------------------

Well the `git-add <https://git-scm.com/docs/git-add>`_ manual page is very descriptive about the subject but, once again, I'll try to explain it in metaphors.
Think of it this way, ``git-commit`` saves the changes, but what changes ? That's exactly the question to answer. What changes ?
What if I want to commit some changes but not others ? What if I want to commit all the code in one commit and all the comments in another ?

That's where the "staging area" comes in play. You use ``git-add`` to stage files to be committed. And whenever you run the ``git-commit`` command, it will commit whatever is staged to be committed, right ?

Practice
========

Now that we've already explained a few concepts, let's see how this all fits together.

Step 1: Basic git configuration
-------------------------------

The `Getting Started - First-Time Git Setup <https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup>`_ has more detailed setup but I took out what's quick and easy for now.

First setup your name and email.

.. code:: text

   $ git config --global user.name "John Doe"
   $ git config --global user.email johndoe@example.com

You're done !

Step 2: Creating a repository
------------------------------

This is easy. If you want to be able to commit, you need to create a project to work on. A "project" can be translated to a repository and everything in that directory will be tracked.
So let's create a repository

.. code:: text

   $ # Navigate to where you'd like to create the repository
   $ cd ~/Documents/Projects/
   $ # Create repository directory
   $ mkdir example
   $ # Navigate into the newly created directory
   $ cd example
   $ # Create the repository
   $ git init

Yeah, it was only one command ``git init``. Told you it was easy, didn't I?

Step 3: Make a change
---------------------

Let's create a file called ``README.md`` in the current directory (``~/Documents/Projects/example``) and put the following in it.

.. code:: md

  # Example

  This is an example repository.

And save it of course.

Step 4: Staging changes
-----------------------

If you go back to the command line and check the following command, you'll see a similar result.

.. code:: text

   $ git status
   On branch master

   No commits yet

   Untracked files:
     (use "git add <file>..." to include in what will be committed)

      	README.md

   nothing added to commit but untracked files present (use "git add" to track)

and ``README.md`` is in red (if you have colors enabled). This means that there is file that is not tracked in your repository. We would like to track that one, let's stage it.

.. code:: text

   $ git add README.md
   $ git status
   On branch master

   No commits yet

   Changes to be committed:
     (use "git rm --cached <file>..." to unstage)

	   new file:   README.md

And ``README.md`` would now become green (if you have colors enabled). This means that if you commit now, this new file will be added and tracked in the future for changes. Technically though, it is being tracked for changes right now.
Let's prove it.

.. code:: text

   $ echo "This repository is trying to give you a hands on experience with git to complement the post." >> README.md
   $ git status
   On branch master

   No commits yet

   Changes to be committed:
     (use "git rm --cached <file>..." to unstage)

	   new file:   README.md

   Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)

	   modified:   README.md

As you can see, git figured out that the file has been changed. Now let's add these changes too and move forward.

.. code:: text

   $ git add README.md
   $ git status
   On branch master

   No commits yet

   Changes to be committed:
     (use "git rm --cached <file>..." to unstage)

	   new file:   README.md


Step 5: Committing
------------------

This will be as easy as the rest. Let's commit these changes with a good commit message to describe the changes.

.. code:: text

   $ git commit -m "Second commit"
   [master (root-commit) 0bd01aa] Second commit
    1 file changed, 4 insertions(+)
    create mode 100644 README.md

Very descriptive commit indeed !

.. code:: text

   $ git status
   On branch master
   nothing to commit, working tree clean

Of course ! There is nothing to commit !

.. code:: text

   $ git log
   commit 0bd01aa6826675f339c3173d7665ebb44c3894a7 (HEAD -> master)
   Author: John Doe <johndoe@example.com>
   Date:   Mon Jul 22 20:57:40 2019 +0200

       Second commit

You can definitely see who committed it, when and what the message was. You also have access to the changes made in this commit.

Conclusion
==========

I'm going to end this post here, and will continue to build up the knowledge in new posts to come. For now, I think it's a good idea to simply work with commits.
Next concepts to cover would be branching and merging.
