Advanced Git Tutorial by Sarah Sharp
May 12, 2015
Advanced Git Tutorialby Sarah Sharp
WARNING:I am a unique snowflake
WARNING:This tutorial may make you lazy
WARNING:Some Git features are
dangerous!
What is Git?
● Distributed● Fast● Flexible
Git Basics
● See Everyday Git Tutorial:– http://www.kernel.org/pub/software/scm/git/doc
s/everyday.html
● My git commands:– git add - git commit
– git diff - git log - git show
– git push - git pull
– git fetch - git rebase
Naming commits<Commitish>
● (Indirect) hash of repo files, current commit message, and ancestor commits.
● HEAD refers to the last commit● ~ at the end means commit before that
– e.g. HEAD~– ^ is roughly equivalent to ~
● A branch points to a specific commit● see git rev-parse
Git Philosophy
Git Philosophy
● Commit early, commit often● One commit represents one idea or one
change.– Makes it easy to read patches– Easy to revert unwanted changes later
● Your working directory, index, and local repo are your scratch pads.
Infrequent UseFrequent Use
The Index, the staging area
Front stage:Changes to be committed
Back stage:Uncommited changes
and unadded files
Staging Changes
● git add <file> – adds a file to the Index● git commit – commits added changes to
the local repo● But what about files not added to the
Index?
Staging Changes
● git add <file> – adds a file to the Index● git commit – commits added changes to
the local repo● But what about files not added to the
Index?– Answer: they aren't included in the commit.
● Key idea: You can add and commit files separately from other files.
– This makes separating changes into small patches easier.
What changed?
workspaceindex
localrepository
git diff git diff --cached
git diff HEAD
● git status● git diff
Advanced Staging
Advanced Staging
● git add --patch– try the "split" option to split across hunks
● git add -i– Very powerful tool with lots of options
● Key idea: You can add and commit different parts of a file separately.
Unstaging changes
● Revert to the last commit– git reset --hard HEAD
● Remove all added changes from the index– git reset --mixed HEAD
● Remove some files added to index– git add -i and choose revert, or– git reset HEAD filename(s)
Viewing History
Viewing History
● git log● git log <commit A>..<commit B>– shows history after commit A, up to commit B– can omit either commit– e.g. `git log` `git log origin..` `git log ..v2.6.30`
● git log -p– shows log as a series of patches
● git log --pretty=oneline –abbrev-commit
Viewing old files
● Contents of a file at a particular commit– git show <commitish>:<path to file>
● Contents of a directory– git show <commitish>:<directory>
Pointing Fingers:git blame
Pointing Fingers
● git blame <file>– show who committed each line
● git blame <commit ID> <file>– show the line history before that commit
Branches
Branches
● Only one branch can be checked out– trunk ~= master
● show all branches– git branch -a
● switching branches– git checkout name
● creating new branches– git checkout -b name <commit>
Advanced Branching
● Merge branches with git merge– creates a "merge commit"
● Rebase current branch against branch B– find a common ancestor commit– apply commits from branch B– apply commits from current branch
● Apply a commit from one branch– git cherry-pick
Interacting with other people
Interacting with other people
● Creating a patchset, starting at commitA– git format-patch -o directory commitA^
--cc=<cced-email>– use git send-email or `mutt -H <gitpatch>`
● Applying a patch– git am patchfile– can also take a mailbox or maildir or stdin
● Pushing a new branch– git push remote branch
Changing History
Changing History:DANGER, WILL ROBINSON!
● After a commit, often you will find bugs– could make a new bug fix commit– or you could "amend" the previous commit
● Fix your code● git add <file>– This adds your code to the index
● git commit --amend– This modifies the commit in the local repo– useful to have vim git-commit script installed
Changing History:DANGER, WILL ROBINSON!
● A total history rewrite:– git rebase -i <commit ID>
● Can reorder commits● Can edit commits● Can "squash" one commit into another● May have merge conflicts
– edit files, resolve conflicts surrounded by <<<< and >>>>
– git add files, git rebase --continue
git rebase -i --dontscrewme
● No such command● git rebase -i the safe way:
– git checkout -b master-rebase– use `git rebase -i` to move one patch– resolve any merge conflicts– squash that patch using `git rebase -i`– git diff master master-rebase– git branch -M master master-old– git branch -M master-rebase master
Git Hooks
Git Hooks
● Hooks are scripts found in .git/hooks/
● Enable them with chmod a+x <file>
● Triggered by various git commands
– e.g. git commit, git push
– pre-commit, post-update● Examples
– shipped pre-commit hook checks for white space at the end of line, long lines, etc.
– Checking for swear words?
Git Hooks
● Example post-update hook on remote repo:
#!/bin/sh
cd /home/sarah/blog
unset GIT_DIR
git-fetch origin
git-reset --hard origin/master
● Whenever I push to the remote repository, this goes into the server's checkout of my blog git repo and updates it unconditionally.
Setting up aremote repository
Setting up aremote repository
● Server needs git and sshd installed to use git+ssh to push to your repo
● Server needs webDAV installed to allow push to your repo over https
● http://github.com/ will host your repo● Next directions assume you have your
own server with git installed
Setting up aremote repository
1. Make local repo, commit stuff, etc.
2. ssh to the server:
GIT_DIR=/path/to/repo git init --shared
3. Next, tell the local repo about the server:
git remote add origin git+ssh://hostname/path/to/repo
4. Push to the server from the local repo:
git push origin master
5. Clean up the local repo so that you can pull from the remote server:
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
Resources
● Git work flow diagrams:http://osteele.com/archives/2008/05/my-git-workflow
● The Tangled Working Copy:http://tomayko.com/writings/the-thing-about-git
● http://github.com/
● Kernel module examples at http://lwn.net/Kernel/LDD3/
● vim git-commit script will display commit messages in a more useful manner. Script kept at vim.sourceforge.net.
– sudo aptitude install vim-scripts vim-addon-manager
– vim-addons install git-commit
Creative CommonsImage Attributions
● GIT picture: http://flickr.com/photos/29862082@N06/2908889599/
● Snowflake: http://commons.wikimedia.org/wiki/Image:SnowflakesWilsonBentley.jpg
● Danger:http://flickr.com/photos/dawvon/32305882/
● Cat: http://flickr.com/photos/jamilsoni/118499378/
● Remote: http://flickr.com/photos/markkelley/957631507/
● Philosophy: http://flickr.com/photos/paullew/2442045767/
● Branches: http://flickr.com/photos/shapeshift/136184752/
● Interacting with other people: http://www.flickr.com/photos/exlibris/3222440467/
Creative CommonsImage Attributions
● Front stage: http://flickr.com/photos/69108241@N00/118040089/
● Back stage: http://flickr.com/photos/piotramigo/2561391320/
● Hooks:http://www.flickr.com/photos/yabanji/3175297773/
● Blame: http://flickr.com/photos/iandesign/1205496024/
● Ballet: http://www.flickr.com/photos/oudeschool/3553416511/
● Papyrus: http://flickr.com/photos/charlestilford/2548991271/
Thank you!
● Sarah Sharp● @sarahsharp● http://sarah.thesharps.us