Git Advance

"Who" is git ?

  • Linus Torvalds

  • "git - the stupid content tracker"

  • free, open-source (https://github.com/git/git)

  • decentralised

  • suitable to handle large codebase

Nasty details

working directory

staging area

metadata

update

git add

git commit

Immutability

  • git holds information in commit objects
  • once a commit object is created it cannot be changed
  • but there is git amend you say
$ git commit -m "The bets commit message ever."
[master 57d9fc9] The bets commit message ever.
 1 file changed, 1 insertion(+)
 create mode 100644 foo

$ git commit --amend
[master 59a5de1] The best commit message ever.
 Date: Wed Apr 13 00:25:41 2016 +0300
 1 file changed, 1 insertion(+)
 create mode 100644 foo

Here's what happens

Commit hash has changed so it's a different object

Pull vs fetch

  • at heart they both fetch remote metadata
  • pull also updates the working directory
  • fetch only updates the metadata
$ git rev-parse --abbrev-ref @{u}

To see what is the configured remote branch for the current branch

OR

$ cat .git/config 

... and search for your branch

$ git pull --rebase

Pull can also rebase instead of merge

Rebase vs merge

Merging

http://rypress.com/tutorials/git/media/5-1.png

Merging

  • creates merge commit
  • non-destructive operation
  • doesn't modify history
  • but history will be uglier

Merging

git checkout feature
git merge master
git merge master feature

Rebasing

http://rypress.com/tutorials/git/media/4-1.png

Rebasing

  • Moves all the commits on top of other branch
  • Rewrites history
  • Creates brand new commits(remember immutability) 
  • No more merge commit => clean history

Interactive Rebasing

  • Eliminate unwanted commits
  • Even cleaner history

http://rypress.com/tutorials/git/media/5-5.png

Interactive Rebasing

git checkout feature
git rebase -i master
pick 33d4a7a Commit message #1
pick 9543b3d Commit message #2
pick 5c87661 Commit message #3
pick 33d4a7a Commit message #1
fixup 9543b3d Commit message #2
pick 5c87661 Commit message #3

Interactive Adding

$ git add -i
           staged     unstaged path
  1:    unchanged        +2/-2 file1
  2:    unchanged        +1/-1 file2.php

*** Commands ***
  1: status	  2: update	  3: revert	  4: add untracked
  5: patch	  6: diff	  7: quit	  8: help
What now> 

Golden Rule

Never ever use rebase on public branches

git push --force

Hashes, refs and reflogs

Hashes

  • 40 characters long SHA-1

 

 

  • most direct way to identify commits
  • can be specified partially
  • to resolve the hash of a branch :

 

 

4b825dc642cb6eb9a060e54bf8d69288fbee4904

git rev-parse master
commit 5584ba46f089c7389d9fbf7b1d371e468394bb84
Author: Web Developer <web@developer.com>
Date:   Thu Apr 7 00:18:06 2016 +0300

    Commit message details

Refs

  • user-friendly alias to commit hash​
  • stored in .git/refs

 

 

 

 

 

 

.git/refs/
    heads/
        master
        feature
    remotes/
        origin/
            master
    tags/
        v0.1

Reflogs

  • timecapsule
  • kept for 90 days by default
$ git reflog
59a5de1 HEAD@{0}: commit (amend): Commit message #1.
57d9fc9 HEAD@{1}: commit (initial): Commit message #2.
$ git checkout HEAD@{1}
$ git reset --hard HEAD@{1}

Git hooks

  • local / user hooks
  • server hooks
  • hook into git's workflow
  • they live in .git/hooks
  • you can write them in any scripting language

 

#!/bin/sh

#!/usr/bin/env python

Local / user hooks

  • pre-commit
  • commit-msg
  • post-commit
  • ...

Server hooks

  • pre-receive
  • update
  • post-receive
  • ...

Git Template

  • used to populate .git folder
  • enable custom hooks by default
$ git config --global init.templatedir 'templatedir'

The power of logs

Pretty Logs

$ git log --graph --oneline --decorate
* 7a48ea2 (HEAD, master) Commit message #5.
* 075ce36 Commit message #4.
*   62cbf27 Merge branch 'branch'
|\
| * 5a40d5a Commit message branch#2.
| * dd0109a Commit message branch#1.
* |  dd0f5d6 Commit message #3.
|/
* 13d1b4b Commit message #2.
* 45de2f7 Commit message #1.

Some visual tools : gitg, gitk, SourceTree

Shortlog

$ git shortlog
Penguin (2):
      Added going for a swim feature.
      Fix not working leg.

Archibald (3):
      Added some voodoo magic.
      Merge branch 'fix_leg'.
      Playing with basic magic config.

Filtering logs

$ git log sincerev..untilrev --summary --diff-filter=D

get all the files that were deleted between two revisions

$ git log --after="2016-4-1" --before="2016-4-12"

get commits between specific dates

$ git log --merges

get only comits with at least two parents

Some sugar and spice

locate bug introducing commit

$ git bisect

see diff from staged files

$ git diff --cached

get commit from different branch

$ git cherry-pick sha1

safe revert public commit

$ git revert

Aliases

setup shortcuts for your favourite commands

$ git config --global alias.visual '!gitk'
$ git config --global alias.unstage 'reset HEAD --'
$ git config --global alias.history 'log --graph --oneline --decorate'
$ git config --global alias.pr 'pull --rebase'

Commit often, commit small things, commit even stupid stuff because there is no downside, commits are small, commits are easy to work with, commits are easy to get rid of.

Linus Torvalds

 

References

http://marc.helbling.fr/2014/09/practical-git-introduction

http://marc.helbling.fr/talks/git.html

http://rypress.com/tutorials/git/the-basics

https://www.atlassian.com/git/tutorials/advanced-overview

https://en.wikipedia.org/wiki/Git_(software)

https://try.github.io

http://pcottle.github.io/learnGitBranching/

https://www.codeschool.com/courses/git-real

DevOps Day 02 - Git 2.1

By Tarun Sharma

DevOps Day 02 - Git 2.1

git Advance

  • 949