Git in Practice

Lukáš Zapletal

About me

@lzap and lukas.zapletalovi.com

Agenda

  • Easy git
  • Advanced git
  • Hardcore git

Recommended reading

Image

What is git

Image

How does it look like

# rpm -ql git git-core | less

It's just a tool

Image

Initial config

# git config --global user.name "Lukas Zapletal"
# git config --global user.email lzap+git@redhat.com

Initial config

# git config --global core.editor my-editor
# cat ~/.gitconfig

Basic usage

# alias for git
alias g=git

Create a repo

# git init

Create a repo

# ls -1 .git
HEAD
config
description
branches/
refs/
info/
objects/
hooks/

Basic usage

# git status
# git status -sb

Basic usage

# alias gg
alias gg='clear && git status'

Basic usage

Image

Basic usage - adding files

# git add AUTHORS

Basic usage - adding files

# git commit

Basic usage - adding files

# git log

Basic usage - adding files

# git config -l | grep unstage
alias.unstage=reset HEAD --

Basic usage - adding files

# git add -p

Basic usage - adding files

# git add -A
# git commit -m "Adding the other files"

Basic usage - adding files

# git commit -am "Adding the other files"

Basic usage - adding files

# git config -l | grep cam
alias.cam=commit -am

Basic usage - adding files

# vim dunst-checkmail.c
# git diff
# git add dunst-checkmail.c
# git diff --cached

Basic usage

Image

Basic usage - deleting files

# rm README
# git status
# git add README
# git commit -m "Would delete README, but..."

Basic usage - deleting files

# git reset HEAD -- README
# git checkout HEAD -- README

Basic usage - deleting files

# git checkout README
# git rm README
# git status
# git commit -m "Deleted README"

Basic usage - renaming files

# mv README NEW-README
# git status
# git add -A
# git status

Basic usage - renaming files

# git reset --hard HEAD
# git clean -f
# git mv README NEW-README
# git status
# git commit -m "Renamed NEW-README"

Basic usage - ignored files

# make
# git status
# vim .gitignore
# git add .gitignore
# git commit -m "Adding .gitignore"

Basic usage - ignored files

# git status --ignored

Basic usage - browsing history

# git log --pretty=oneline
# git log --pretty=oneline --abbrev-commit
# git log --pretty=oneline --abbrev-commit --graph

Basic usage - browsing history

# git config --get alias.g
log --graph --pretty=format:'%Cred%h%Creset
    -%C(yellow)%d%Creset %s
    %Cgreen(%cr) %C(bold blue)<%an>%Creset'
    --abbrev-commit --date=relative

Basic usage - browsing history

# gitk
# tig

Basic usage - browsing history

# git blame dunst-checkmail.c
# tig 1ee1babe

Basic usage - browsing history

# tig blame dunst-checkmail.c
(, for parents)

Basic usage - anatomy

Image

Basic usage - anatomy

Image

Basic usage - anatomy

Image

Basic usage - anatomy

# find .git/

Basic usage - anatomy

# find .git/
# git gc
# git gc --aggressive
# find .git/

Basic usage - anatomy

# file .git/objects/19/3bb7f58a514512dfeaad6b440d5467294fc200

Basic usage - anatomy

# git cat-file -p master^{tree}

Basic usage - anatomy

# git cat-file -p e111d37f3

Basic usage - anatomy

# git verify-pack -v .git/objects/pack/pack-ec08*.pack

Referencing

# git show
# git show HEAD
# git show master
# git show HEAD^
# git show master^^
# git show master~3

Referencing

# git diff master~3
# git diff master~3..master
# git diff master..master~3

Working with history - amend

# vim dunst-checkmail.c
# git commit -am "Better incorrect change" --amend

Working with history - interactive rebase

# for X in 1 2 3 4 5
  do
    echo "Jan Novak $X." >> AUTHORS
    git commit -am "Random change $X"
  done

# tig

Working with history - interactive rebase

# git rebase -i HEAD~5

Workflow

Image

Workflow

Image

Workflow

Image

Workflow

Image

Working in team - creating repo

# git clone https://github.com/lzap/project.git
# git clone git://github.com/lzap/project.git
# git clone git@github.com:lzap/project.git

Working in team - creating repo

# mkdir project.git
# cd project.git
# git init
# git remote add origin https://github.com/lzap/project.git
# git fetch origin
# git merge origin/master

Working in team - merge vs rebase

# mkdir /tmp/shared
# pushd /tmp/shared
# git init --bare
# find
# popd
# git clone /tmp/shared ./aranka
# git clone /tmp/shared ./brona

Working in team - merge vs rebase

aranka# git config --local user.name Aranka
aranka# touch one && git add -A && git commit -am One
aranka# git push origin master

Working in team - merge vs rebase

brona# git fetch origin
brona# git merge --ff-only origin/master
brona# git pull

Working in team - merge vs rebase

brona# git config --local user.name Brona
brona# touch two && git add -A && git commit -am Two
brona# git push origin master

Working in team - merge vs rebase

aranka# touch three && git add -A && git commit -am Three
aranka# git push origin master
 ! [rejected]        master -> master (non-fast-forward)

Working in team - merge vs rebase

aranka# git fetch --all
aranka# git rebase origin/master
aranka# git push

Creating patches - two-way merge

aranka# git diff HEAD^
aranka# git diff HEAD^..HEAD
aranka# git diff HEAD^ > ../brona/change.patch
brona# git reset --hard HEAD^
brona# git apply change.patch

Creating patches - three-way merge

# git format-patch HEAD^ --to=project@fedorahosted.org
# git send-email *.patch
# vim 0001-*
# git am 0001-*

Annotated tags

# git tag v1.0 cae4a78
# git tag
# cat .git/refs/tags/mytag
# git tag -a v1.1
# git show v1.1
# git tag -d v1.1

Signed tags

# gpg -K
# git tag -s v1.2

Branches

Image

Branches

# git branch testing
# cat .git/refs/heads/branch
# git branch
# git checkout testing
# git commit -am "Testing"
# git checkout master
# git branch -d testing
# git branch -D testing

Branches

# git checkout -b testing

Branches

# git fetch colleague
# git checkout -b testing -t colleague/testing
# git pull
# git pull -f

Branches

Image

Branches

Image

Branches

Image

Branches

Image

Branches - commit vs ff vs rebase

Image

Branches

# git checkout -b testing
# vim HACKING && git commit -am "Testing edit"
# git checkout master
# vim LICENSE && git commit -am "Master edit"
# tig --all

Branches

# git checkout master
# git merge --ff-only testing
# git merge --no-ff testing
# git merge testing
# gitk --all

Branches

# git reset --hard HEAD^
# git checkout testing
# git rebase 
# gitk --all
# git checkout master
# git merge --ff-only testing

Conflicts

Image

Conflicts

# git checkout -b conflict
# vim Makefile && git commit -am "Makefile edit"
# git checkout master
# vim Makefile && git commit -am "Makefile edit"
# tig --all

Conflicts

# git merge conflict
# vim Makefile

Conflicts

# vim ~/.gitconfig
# git mergetool

Other tricks

Image

Other tricks

# git pull --rebase

Other tricks

# git cherry-pick c4febabe

Other tricks

# git stash
# git stash pop

Other tricks

# git reflog

Other tricks

# git reflog expire --expire=1.month --all
# git gc --aggressive --prune=1.month

Other tricks

# git config -l | grep cleanup
alias.cleanup=!git branch --merged master | grep -v 'master$' | xargs -r git branch -d

Other tricks

https://github.com/lzap/git-xcleaner

Other tricks

# git bisect test.sh

Other tricks

# git git filter-branch --force --index-filter \
    'git rm --cached --ignore-unmatch WINDOWS_10.ISO' \
    --prune-empty --tag-name-filter cat -- --all
# git reflog expire --expire=now --all
# git gc --prune=now

Other tricks

# hub

We are done

Thanks!