Catalyst – Advanced Git



Catalyst – Advanced Git

4 1


git-advanced

Slides for the Git Advanced course

On Github catalyst-training / git-advanced

Catalyst

Advanced Git

Workflows for Developers

Slides by Matthew B. Gray / @theflimflam

  • Breaks every 30 minutes for 3 minutes
  • Expecting this course to go for 3~4hrs
  • Have the WR ready
  • Check projector light/dark themes

Special thanks to

  • Mike O' – For approving this course
  • Alison Aldred – Organise all the things
  • Evan Giles – Inspiration and advice
  • Robert Higgins – Standardisation and professionalism

Course Overview

  • Part 1: Getting Started
  • Part 2: Personal workflows
  • Part 3: Team workflows
  • Part 4: Releases and Client workflows

Part 1: Getting started

  • Part 2: Personal workflows
  • Part 3: Team workflows
  • Part 4: Releases and Client workflows

Objectives

  • Install some stuff
  • Basic config for these machines
  • Good config defaults
  • Quick review of basic git
  • Unlocking achievements, making git a bit more fun

Install some stuff

Sometimes you run old software :'(

Does running

git --version

Show you something < 1.9???

Lets fix that!

sudo apt-add-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git

Install some stuff

A gui might be nice

sudo apt-get install gitg
            OR
sudo apt-get install gitk

Basic config for these machines

Git would like you to specify

Your full name Your email address Your favourite text editor
git config --global user.name "Dr. Henry Killinger"
git config --global user.email "fu@bar.baz"
git config --global core.editor vim

All these settings are stored in ~/.gitconfig

Sane defaults for day to day use

  • Use colour to highlight branches and diffs
  • Make sure you only push the branch you're on
  • Show branches and tags in git log
  • Setup rebase as the default strategy for git pull
git config --global color.ui always
git config --global push.default current
git config --global log.decorate full
git config --global branch.rebase true
git config --global branch.autosetuprebase always

All these settings are stored in ~/.gitconfig

Quick review of basic git

http://ndpsoftware.com/git-cheatsheet.html

Unlocking achievements, making git a bit more fun

Unlock Achievements!

Track friends over RSS!

Flaunt your achievements with a Splashy page!

Unlocking Achievements in Git

If you have a github account

https://github.com/icefox/git-achievements Fork that repo Go to your forked project, and clone it

No account? You can still run it locally, just don't let it push

git clone https://github.com/icefox/git-achievements.git

Setup

Alias git-achievements in your shellrc file

vim ~/.bashrc

# Put these lines at the bottom of your file
export PATH="$PATH:~/git/git-achievements"
alias git="git-achievements"

# Run this ONLY IF YOU FORKED
git config --global achievement.upload "true"

Keep your achievements after the course, save this file

~/.git-achievements.log

Fun achievements to unlock!

Banker (Level 5)

Join two or more development histories together with git-merge.

Garage Inventor (Level 1)

Used a custom alias for a Git command

Apprentice Thug (Level 3)

Forced pushed a branch with git-push -f

Let there be light

Commit without a parent.

Part 1: Getting started

[COMPLETE]

  • Objectives
    • Install some stuff ✔
    • Basic config for these machines ✔
    • Good config defaults ✔
    • Quick review of basic git ✔
    • Unlocking achievements, making git a bit more fun ✔
  • Part 1: Getting Started ✔

    Part 2: Personal workflows

  • Part 3: Team workflows
  • Part 4: Releases and Client workflows

Objectives

  • Context hunting / Isolate and Triage issues
  • Mastering branches
  • Audit work interactively
  • Manage merge conflicts like a pro

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting <-- you are here
    • Work: Mastering branches
    • Update, Test: Audit work interactively
    • Share: Manage merge conflicts like a pro

Context hunting / Isolate, Triage

This is a BEFORE YOU START thing, helps isolate and triage

Context is important so you can...

  • Avoid regressing your codebase
  • Find out if code is still under warranty
  • Get help if you get stuck, seek out a human

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting
      • Log - Show commit logs <-- you are here!
      • Bisect - binary search for bugs
      • Blame - revision and author for lines of a file
      • Pickaxe - Search commit diffs for changes
    • Work: Mastering branches
    • Update, Test: Audit work interactively
    • Share: Manage merge conflicts like a pro

Regular log

git log

Show me contents of patches

git log -p

Show me a summary of patches

git log --stat

Find changes associated with text in a commit message:

git log --grep '$search_term'
git log --grep 'bug#1234'

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting
      • Log - Show commit logs ✔
      • Bisect - binary search for bugs <-- you are here!
      • Blame - revision and author for lines of a file
      • Pickaxe - Search commit diffs for changes
    • Work: Mastering branches
    • Update, Test: Audit work interactively
    • Share: Manage merge conflicts like a pro

Bisect: Binary search for bugs

You can search 100 commits in 10 steps to find a bad commit!

To bisect, you need...

A ref (tag/hash/branch) to a known bad commit A ref to a known good commit
git bisect start $bad_commit $good_commit

# ... test your code ...
git bisect bad
git bisect good

# put things back with
git bisect reset

Bisect: When it's not testable

If your history has broken commits, maybe it's impossible to test

# test around an problematic commit
git bisect skip

# or save where you're up to, and come back later
git bisect log > bisect.log
# ... time passes
git bisect reset
git bisect replay bisect.log

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting
      • Log - Show commit logs ✔
      • Bisect - binary search for bugs ✔
      • Blame - revision and author for lines of a file <-- you are here!
      • Pickaxe - Search commit diffs for changes
    • Work: Mastering branches
    • Update, Test: Audit work interactively
    • Share: Manage merge conflicts like a pro

Blame: Basic usage

git blame $filename

# to get the context around the change of a line
git show $hash

Blame: Power tools

  • Ignore whitespace changes (might be hiding a commit)
  • Copy paste detection in a file, and across the repo
  • Track refactorings of methods across a codebase
git blame -w $filename # ignore whitespace
git blame -m $filename # copy paste within the same file
git blame -C $filename # copy paste over the repo

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting
      • Log - Show commit logs ✔
      • Bisect - binary search for bugs ✔
      • Blame - revision and author for lines of a file ✔
      • Pickaxe - Search commit diffs for changes <-- you are here!
    • Work: Mastering branches
    • Update, Test: Audit work interactively
    • Share: Manage merge conflicts like a pro

Pickaxe

What happened to myFabuliousFunc(), it's gone!

When did $mySillyVariable get referenced everywhere?

Search commit diffs for changes

  • Find all the changes to a line in your entire history
  • The pickaxe can help find code that’s been deleted or moved
  • Works with log, diff, format-patch and tig
git log -S 'some distinct line that changed'
git log --stat -S '$racebook_uri_result'

Activity: Testing bisect

Clone the jabberwocky repo, pull tags Checkout the changes made with git log Use bisect with v1 and v2 tags as good/bad commits find the commit that broke the page
git clone https://github.com/catalyst-training/jabberwocky
cd jabberwocky
git fetch --tags
git log -p
git log --stat
git bisect start $bad $good

# Now test the code!
# When a commit exhibits wanted behaviour
git bisect good

# When a commit exhibits unwanted behaviour
git bisect bad

Don't forget to tidy up with...

git bisect reset

Activity: Testing log, pickaxe, blame and show

Clone jquery repo Use git log to find fixes to issue #14756 Use pickaxe to find commits that added or removed 'parseFloat' Try git blame on the .gitignore file With this info, show the commit that blacklisted bower_components
git clone https://github.com/jquery/jquery
git log --grep 'asdf'
git log -S 'asdf'
git blame $file
git show $hash

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting ✔
    • Work: Mastering branches <-- you are here!
    • Update, Test: Audit work interactively
    • Share: Manage merge conflicts like a pro

Mastering branches: Overview

Git thinks in Snapshots, Not Differences

The major difference between Git and any other VCS (Subversion and friends included) is the way Git thinks about its data.

quote from git-scm.com, ch 1.3 "Getting Started: Git Basics"

Branches: Git vs SVN

Branching should reflect your team's workflow.

Isolate work till you're ready to release

Commits in context

  • A single commit: you refer to an entire filesystem layout
  • Multiple commits: you usually think in diffs
  • Commits are immutable, but you can re-create a new history

You can describe nodes with a...

  • branch - a name to track your work
  • tag - a label, it doesn't move
  • commit hash - complete history and set of files
  • HEAD - your current checkout
  • $ref^ - above are $refs, chain ^ or ~ to go up a branch

Lets look at how we can use these with commands

Mastering branches: Commands

Interesting commands with branches

git checkout $branch
git reset $ref
git rebase $branch
git rebase --interactive $branch
  • Checkout: context dependent command...
  • Either reset unstaged file(s)
  • Or switch branches
  • Rebase: Batch move commits and rewrite history
  • Reset: Move branches around arbitarily
  • Reflog: Save my ass! What have I had 'checked out' recently?

Whiteboard time!

# ...fiddle fiddle fiddle, fixing one thing
# OOP... NOOOOOOO!!!! Undo undo undo!
git reflog

Mastering branches: Headless state

If you're not on a branch, git puts you in a headless state

git checkout $tag
git checkout $commit

Trying something like this...

git checkout HEAD^

But don't worry, git is being melodramatic when it says...

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b new_branch_name

HEAD is now at f4b37d8... CSS: Return values should be numbers

Activity: Mastering Branches

Navigate to your Jabberwocky repo clone Checkout 'master' Fix the bug, commit Interactive rebase onto the tag v1 Squash your fix with 'Oops' and give it a message.
cd $jabberwocky_dir
vim jabberwocky.html
git add jabberwocky.html
git commit
git log
git rebase $ref --interactive
git log -p

...it's as if the error was never there.

Now put it back

git reset origin/master --hard

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting ✔
    • Work: Mastering branches ✔
    • Update, Test: Audit work interactively <-- you are here!
    • Share: Manage merge conflicts like a pro

Audit work interactively

Audit your work interactively with your staging area

When you're ready to commit locally When you want to break up a monstor commit

Quick activity

Add your own verse to the jabberwocky poem, then run

git add -p

Check what's happened with

git status

Put stuff back with

git reset HEAD

Part 2: Personal workflow

  • Objectives
    • Isolate and Triage: Context hunting ✔
    • Work: Mastering branches ✔
    • Update, Test: Audit work interactively ✔
    • Share: Manage merge conflicts like a pro <-- you are here!

Manage merge conflicts like a pro

Source control is about social coding and interactions.

A conflict should be a conversation. When you see

CONFLICT (content): Merge conflict in jabberwocky.html
Automatic merge failed; fix conflicts and then commit the result.

Get info with

git status
git blame $file

Markers are usually HEAD and a $ref, where:

HEAD is work of yours $ref is the thing you're in conflict with
git reflog
git merge $ref

Part 2: Personal workflow [COMPLETE]

  • Objectives
    • Isolate and Triage: Context hunting ✔
    • Work: Mastering branches ✔
    • Update, Test: Audit work interactively ✔
    • Share: Manage merge conflicts like a pro ✔
  • Part 1: Getting Started ✔
  • Part 2: Personal workflows ✔

    Part 3: Team workflows

  • Part 4: Releases and Client workflows

Objectives

  • Quickly setup local, network accessible repos
  • Working with people who don't enjoy source control
  • Clean history, rebase verses merge

When you use git to share your stuff

Quickly setup local, network accessible repos

Quickly setup local, network accessible repos

Git just tracks content. All history is stored in .git directory, and sharing is just mushing content around in there.

To modify remotes...

git remote add $alias $location
git remote rm $alias $location

Location can be...

ssh://[user@]host.xz[:port]/path/to/repo.git/ git://host.xz[:port]/path/to/repo.git/ http[s]://host.xz[:port]/path/to/repo.git/ ftp[s]://host.xz[:port]/path/to/repo.git/ rsync://host.xz/path/to/repo.git/

Quickly setup local, network accessible repos

Enter custom alias! You just need to run this once...

git config --global alias.serve "daemon --verbose --export-all
        --base-path=.git --reuseaddr --strict-paths .git/"

Now you too can share your terrible poetry with your neighbour!

Navigate to your repository, and run

git serve

And you'll be Ready to rumble

Pull work from your neighbour

# Find your IP address (or hostname)
ip ad

# Serve your jabberwocky poem to the network
cd ~/jabberwocky
git serve

# Get your neighbours network details
# Lets add their work to your repo
git remote add git://$host/ neighbour
git fetch

# What's different between our branches?
git diff neighbour/master master

# Merge their work in (merge conflict ahead)
git merge neighbour/master

Working with people who don't enjoy source control

Idea #1: Empower them, let them manage their commits, but manage their merges

Working with people who don't enjoy source control

Idea #2: Manage their commits and merges

while true; do
    clear;
    git add .
    git commit -m "$designer updated UX."
    sleep 5;
done;

Wrestling with git

Clean history, rebase verses merge

  • When to merge: If you've pushed it, you can't change things without pain.
  • If you have multiple conflicts, try for a merge
  • Use KISS where possible

Discuss:

git pull --rebase
git config --global branch.autosetuprebase always
git pull
git rebase --abort
git merge --abort

Part 3: Team workflows [COMPLETE]

  • Objectives
    • Quickly setup local, network accessible repos ✔
    • Working with people who don't enjoy source control ✔
    • Clean history, rebase verses merge ✔
  • Part 1: Getting Started ✔
  • Part 2: Personal workflows ✔
  • Part 3: Team workflows ✔

    Part 4: Release Management

Objectives

  • Strategies for dealing with release requirements
  • Strategies for database patching on branches

Database patching on branches

Git doesn't care about non-filesystem entities

Database patching is important to get right

You can either use convention, or process to manage this

Numeric patch - set 1+$current in your filename Automatic numeric patch - use a merge script on release

Strategies for dealing with client requirements

The battle of flexibility vs simplicity

A typical client may ask you to be flexible on the following

  • Track changes, find bugs and release when you can
  • Working on releases in parallel
  • Construct release candidates based on feature sets
  • Release partial applications (modular)

Release all the things!

Client requirements: Linear history

  • Simple
  • Track changes, find bugs and release when you can
  • Easy to bring new devs on board

Client requirements: Merge forward releases

  • Fairly simple
  • Work on multiple releases at the same time
  • Can work on upstream while downstream is still going

Client requirements: Feature releases

  • Every piece of work is a feature
  • Features are octo-merged into a release candidate
  • Need to track production somehow
  • Cannot release 'backwards'

Feature releases... omg

Feature releases... more woah

Client requirements: Microkernel architecture

  • Difficulty is abstracted to the application
  • Modules of application can be worked on at the same time
  • Release would package together multiple pieces of work

Each has its costs! Choose the one that works best

Further Reading

Attribution

Course Information

Slides can be found on

github.com/catalyst-training/git-advanced

Feedback? Corrections? Questions?

Please leave an issue against the course github page.

open source technologists