On Github catalyst-training / git-advanced
Slides by Matthew B. Gray / @theflimflam
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
A gui might be nice
sudo apt-get install gitg OR sudo apt-get install gitk
Git would like you to specify
Your full name Your email address Your favourite text editorgit 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
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
Unlock Achievements!
Track friends over RSS!
Flaunt your achievements with a Splashy page!
If you have a github account
https://github.com/icefox/git-achievements Fork that repo Go to your forked project, and clone itNo account? You can still run it locally, just don't let it push
git clone https://github.com/icefox/git-achievements.git
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
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.
This is a BEFORE YOU START thing, helps isolate and triage
Context is important so you can...
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'
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 commitgit bisect start $bad_commit $good_commit # ... test your code ... git bisect bad git bisect good # put things back with git bisect reset
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
git blame $filename # to get the context around the change of a line git show $hash
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
What happened to myFabuliousFunc(), it's gone!
When did $mySillyVariable get referenced everywhere?
Search commit diffs for changes
git log -S 'some distinct line that changed' git log --stat -S '$racebook_uri_result'
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
git clone https://github.com/jquery/jquery git log --grep 'asdf' git log -S 'asdf' git blame $file git show $hash
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"
Branching should reflect your team's workflow.
Isolate work till you're ready to release
You can describe nodes with a...
Lets look at how we can use these with commands
Interesting commands with branches
git checkout $branch git reset $ref git rebase $branch git rebase --interactive $branch
Whiteboard time!
# ...fiddle fiddle fiddle, fixing one thing # OOP... NOOOOOOO!!!! Undo undo undo! git reflog
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
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
Audit your work interactively with your staging area
When you're ready to commit locally When you want to break up a monstor commitAdd 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
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 withgit reflog git merge $ref
When you use git to share your stuff
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/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
# 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
Idea #1: Empower them, let them manage their commits, but manage their merges
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
Discuss:
git pull --rebase
git config --global branch.autosetuprebase always git pull
git rebase --abort git merge --abort
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 releaseThe battle of flexibility vs simplicity
A typical client may ask you to be flexible on the following
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