<commit_before>---
layout:     post
title:      "Git revisions explained"
date:       2016-03-15 18:46:00
summary:    "Git has a somewhat complex set of concepts to refer a particular point in history. We have commits, branches, tags, remotes. Moe than enough to get confused!
             I'll try clarify this by sorting out all this concepts in holistic system, connecting them together from simple to complex."
categories: git

jsUrl:      "http://cdn.rawgit.com/nicoespeon/gitgraph.js/v1.1.3/build/gitgraph.js"
js: |
  var config = { 
    colors: [ '#5cb85c', '#5bc0de', '#f0ad4e', '#d9534f',], // branches colors, 1 per column
      branch: {
        lineWidth: 8,
        spacingX: 35,
      },
      commit: {
        spacingY: -25,
        dot: {
          size: 8,
          strokeWidth: 3,
          strokeColor: '#000000',
        },
        message: {
          display: true,
          displayAuthor: false,
          displayBranch: true,
          displayHash: false,
          font: "normal 10pt Arial"
        },
      },
  };

  var myTemplate = new GitGraph.Template( config );
  function createGraph(id) {
    return new GitGraph({ elementId: id, template: myTemplate, orientation: "vertical" })
  }
---

As in any version control system, in git we have a concept of __revisions__. To put it simple, revision is a tracked state of project.
Every revision in git have it's own `sha-1` [^1] hash, and can be referenced by it. From this very simple concept we will start.

* TOC
{:toc}

### Commits
So, what is `sha-1` hash I've mentioned? It's unique 40 character string, containing digits and english letters. In this post we don't care how we get it, let's just stick with that fact, that it's unique and used to identify particular revision.
My last commit here is `482707027ec693dd65a9b5b5b87d0356b48b77b9`. As you can see it is very long, and cumbersome to type. But don't worry, it can be shortened to _minimal non ambiguous sequence_.
In my case it's 4 characters, i.e. command `git show 4827` will work. As repository becomes bigger and bigger,
you'll have to use longer sequences, but it's rarely more than 8-10 characters.

> from __Git Pro Book__
> Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique.

But even short sha is not descriptive enough to work with it. When we work, we wan't to name our revisions in a bit more human-centric way. And next concept I'll show is __tags__.

### Tags
Actually, git has 2 types of tags.
__Lightweight tag__ is a named pointer to existing commit. Just like an alias to existing commit.
Creating this kind of tag it simple: `git tag blog_post_about_revisions`. After that you can use it everywhere, where git expects revision.
Now and I can check it out, without remembering any sha-hashes. `git checkout blog_post_about_revisions`.

There is also an annotated tag. It's a bit different, it has metadata and own sha-code. In that sense it is more like commit of it's own, than just alias.
So, it's used for a long-term history, mostly releases. Don't use it for simple aliasing purpose.

Tag's are fixed in time, and if we wan't our textual alias to move with us, as we progress in our work, we should use __branches__.

### Branches
Branches lay in the core of git, and they are much more wide-known and used, than tags.
At the same time, branch is also just a named pointer to particular commit, exactly as lightweight tag! It does't have it's own sha, it's just an alias.
Main difference from tag, is that it will move as you add commits, allowing you to use same alias for _latest state_ of your work.
With this in mind, it's not surprising, that if you provide branch name to command expecting single revision, last commit from branch will be taken.
Example of these commands are `show` or `cherry-pick`.

### HEAD<commit_msg>Remove TOC.<commit_after>---
layout:     post
title:      "Git revisions explained"
date:       2016-03-15 18:46:00
summary:    "Git has a somewhat complex set of concepts to refer a particular point in history. We have commits, branches, tags, remotes. Moe than enough to get confused!
             I'll try clarify this by sorting out all this concepts in holistic system, connecting them together from simple to complex."
categories: git

jsUrl:      "http://cdn.rawgit.com/nicoespeon/gitgraph.js/v1.1.3/build/gitgraph.js"
js: |
  var config = { 
    colors: [ '#5cb85c', '#5bc0de', '#f0ad4e', '#d9534f',], // branches colors, 1 per column
      branch: {
        lineWidth: 8,
        spacingX: 35,
      },
      commit: {
        spacingY: -25,
        dot: {
          size: 8,
          strokeWidth: 3,
          strokeColor: '#000000',
        },
        message: {
          display: true,
          displayAuthor: false,
          displayBranch: true,
          displayHash: false,
          font: "normal 10pt Arial"
        },
      },
  };

  var myTemplate = new GitGraph.Template( config );
  function createGraph(id) {
    return new GitGraph({ elementId: id, template: myTemplate, orientation: "vertical" })
  }
---

As in any version control system, in git we have a concept of __revisions__. To put it simple, revision is a tracked state of project.
Every revision in git have it's own `sha-1` [^1] hash, and can be referenced by it. From this very simple concept we will start.

### Commits
So, what is `sha-1` hash I've mentioned? It's unique 40 character string, containing digits and english letters. In this post we don't care how we get it, let's just stick with that fact, that it's unique and used to identify particular revision.
My last commit here is `482707027ec693dd65a9b5b5b87d0356b48b77b9`. As you can see it is very long, and cumbersome to type. But don't worry, it can be shortened to _minimal non ambiguous sequence_.
In my case it's 4 characters, i.e. command `git show 4827` will work. As repository becomes bigger and bigger,
you'll have to use longer sequences, but it's rarely more than 8-10 characters.

> from __Git Pro Book__
> Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique.

But even short sha is not descriptive enough to work with it. When we work, we wan't to name our revisions in a bit more human-centric way. And next concept I'll show is __tags__.

### Tags
Actually, git has 2 types of tags.
__Lightweight tag__ is a named pointer to existing commit. Just like an alias to existing commit.
Creating this kind of tag it simple: `git tag blog_post_about_revisions`. After that you can use it everywhere, where git expects revision.
Now and I can check it out, without remembering any sha-hashes. `git checkout blog_post_about_revisions`.

There is also an annotated tag. It's a bit different, it has metadata and own sha-code. In that sense it is more like commit of it's own, than just alias.
So, it's used for a long-term history, mostly releases. Don't use it for simple aliasing purpose.

Tag's are fixed in time, and if we wan't our textual alias to move with us, as we progress in our work, we should use __branches__.

### Branches
Branches lay in the core of git, and they are much more wide-known and used, than tags.
At the same time, branch is also just a named pointer to particular commit, exactly as lightweight tag! It does't have it's own sha, it's just an alias.
Main difference from tag, is that it will move as you add commits, allowing you to use same alias for _latest state_ of your work.
With this in mind, it's not surprising, that if you provide branch name to command expecting single revision, last commit from branch will be taken.
Example of these commands are `show` or `cherry-pick`.

### HEAD
{'fraction_non_alphanumeric': 0.07126582278481013, 'fraction_numerical': 0.02278481012658228, 'mean_word_length': 3.3293150684931505, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5981654', 'n_tokens_mistral': 2362, 'n_tokens_neox': 2132, 'n_words': 1172}