BLOB STORAGE
• All data is stored at snapshots on every
commit (full file, no diffs). Only new and
modified files are hashed and stored.
• Blobs are stored as compressed files in:
• .git/objects/*/*
• (sharded using first two SHA-1 characters into
subdirectories)
• Unreferenced (unreachable) blobs are
garbage-collected every so often
Slide 5
Slide 5 text
BRANCHES AND TAGS
• tags are pointers to specific commits
• branches are tags that automatically move
when appending commits to the current
branch
00 01 02 03
04 05 06
master
legacy
deployed
Slide 6
Slide 6 text
TYPES OF TAGS
• lightweight tags
• mutable pointers that can be used to annotate
history (qa-tested, deployed, etc.)
• can be shared across repositories, not pushed
by default
• heavyweight tags
• immutable entities, have full commit info and
are persisted and pushed across repositories
• contain cryptographic signing mechanisms
Slide 7
Slide 7 text
REMOTES, COMMITS AND
BRANCHES
Remotes are git repository URIs (and aliases)
stored in the local repository.
• branches fetched from remotes are read-only
and are labeled as
[remote-name]/[branch-name]
• branches can be set up to map to remote
branches using .git/config directives
• you can still push changes to remotes without
setting up tracking by using explicit URIs
HOW MERGING WORKS
BETWEEN BRANCHES
00 01 02 03
04 05 06
master
new-feature
Slide 10
Slide 10 text
HOW MERGING WORKS
BETWEEN BRANCHES
00 01 02 03
04 05 06
master
new-feature
07
Slide 11
Slide 11 text
HOW MERGING WORKS
BETWEEN BRANCHES
00 01 02 03
04 05 06
07
new-feature
master
Slide 12
Slide 12 text
PULLING REMOTE
CHANGES
Remote branches exist as local read-only
branches that can be merged as any other, but
not modified locally.
To merge changes from a remote:
• git fetch remote-name
• git merge remote-name/branch-name
If you are tracking the current branch:
• git pull [remote-name]
Slide 13
Slide 13 text
SHARING YOUR WORK
You can push a local branch to a remote
repository if the push results in appending
history to the branch without a merge:
• git push remote-name branch-name
If you‘re pushing a new branch to the remote,
you can set up tracking for the branch:
• git push –u remote-name branch-name
Slide 14
Slide 14 text
CUSTOMIZING THE CLI
CLIENT
$ cat ~/.gitconfig
[alias]
st = status
ci = commit
br = branch
co = checkout
$ git st # == git status
Slide 15
Slide 15 text
CUSTOMIZING THE CLI
CLIENT
[alias]
history = log --graph
--pretty=format:'%C(yellow)%h%Creset %C(bold
blue)%an%Creset %Cgreen(%cr)%Creset: %s'
update = !git stash && git fetch && git rebase &&
git stash pop
explicit shell command, not an alias
Slide 16
Slide 16 text
CUSTOMIZING THE CLI
CLIENT
[color]
ui = auto
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
[color "status"]
added = yellow
changed = green
untracked = cyan
Slide 17
Slide 17 text
NUMBER ONE, WHAT‘S
OUR STATUS?
Slide 18
Slide 18 text
NUMBER ONE, WHAT‘S
OUR STATUS?
$ git status
# On branch master
nothing to commit (working directory clean)
$ echo "HELLO" > README && git add README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: README
#
Slide 19
Slide 19 text
NUMBER ONE, WHAT‘S
OUR STATUS?
$ git commit -m "Added greeting"
[master ca59d46] Added greeting
1 file changed, 1 insertion(+)
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
Slide 20
Slide 20 text
UNTRACKED, MODIFIED
AND STAGED CHANGES
• Untracked files are ignored by git (but are
reported by git status as untracked).
• Modifications to tracked files are displayed,
but not commited automatically.
• Staging allows choosing which changes to
put into a commit.
• A commit command takes every staged
change and creates a new commit.
Slide 21
Slide 21 text
GIT DIFF
Show changes to tracked files not yet staged:
• git diff
Show changes that staged for commit:
• git diff --cached
Untracked files are completely ignored until
staged!
Slide 22
Slide 22 text
DEMO: STAGING CHANGES
Slide 23
Slide 23 text
SHOW CONTENTS
OF A COMMIT
Want to know what exactly was changed in a
commit? Easy:
• git show (|...)
This also works for blobs, trees and tags.
Slide 24
Slide 24 text
INITIALISING A REPOSITORY
You can initialise a repository with a working
copy in any directory that doesn‘t contain
other .git directories in their subpaths.
• git init .
• git add .
• git commit -m "Initial commit"
Slide 25
Slide 25 text
BARE REPOSITORIES
To create a bare repository (repo without a
working copy checkout):
• git init my-repo --bare
To push changes to the repository, you need a
clone to push changes from there:
• git clone my-repo my-checkout
• (...work...)
• git push -u origin master
Slide 26
Slide 26 text
ADDING REMOTES
When you clone a repo, the origin remote alias
is added automatically. To add more:
• git remote add remote-name URI
Example:
• git remote add migration \
ssh://user@host/repo.git
• git fetch migration
Slide 27
Slide 27 text
WORKING WITH BRANCHES
Branches are lightweight (dynamic pointers)
and can be created at any time by using the
branch command:
• git branch new-branch-name
This creates a new branch at the revision
currently checked out (but does not switch!):
00 01 03 04
master (checked out)
new-branch-name
Slide 28
Slide 28 text
WORKING WITH BRANCHES
To switch to the branch, use the checkout
command:
• git checkout new-branch-name
Or do it in one step:
• git checkout new-branch-name -b
00 01 03 04
master
new-branch-name
(checked out)
Slide 29
Slide 29 text
COMMITING TO A BRANCH
• (Create and) check out the branch
• Modify and commit your changes
• Push to remote:
• git push -u remote-name new-branch-name
Counting objects: 3, done.
Writing objects: 100% (3/3), 220 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To /tmp/my-repo/
* [new branch] new-branch-name -> new-branch-name
Branch new-branch-name set up to track remote branch
new-branch-name from remote-name.
Slide 30
Slide 30 text
MERGING LOCAL
BRANCHES
Check out the branch to which you want to
merge:
• git checkout main-dev-branch
Merge changes into the working copy:
• git merge feature-branch
Resolve any merge conflicts and mark files as
resolved, then commit:
• git add
Slide 31
Slide 31 text
MERGING REMOTE
BRANCHES
Same as before, but:
• git checkout main-dev-branch
• git fetch remote-name
• git merge \
remote-name/feature-branch
Always fetch before merging remote branches!
Local history for remote branches may not be
up-to-date!
Slide 32
Slide 32 text
HAVE WE DEPLOYED THIS?
Slide 33
Slide 33 text
HAVE WE DEPLOYED THIS?
Show branches already merged into current
branch:
• git branch --merged
Show branches not yet merged into current
branch:
• git branch --no-merged
Slide 34
Slide 34 text
WHO SHAT IN MY POOL?!
To see which parts of a file were updated by
whom and when, use annotations:
• git blame
(There‘s a more humane way of browsing
annotations on GitHub.)
Slide 35
Slide 35 text
DELETING BRANCHES
To delete a local branch:
• git branch -d the-other-branch
To delete a remote branch:
• git push remote-name :branch-name
Slide 36
Slide 36 text
TAKING OUT THE TRASH
After a while, locally tracked remote branches
might become obsolete and deleted. To clean
up remotely deleted branches:
• git remote prune remote-name
Git runs garbage collection periodically, but
you can manually run it if desired:
• git gc
Slide 37
Slide 37 text
REVERTING ALL CHANGES
Want to abandon all working copy changes?
• git reset --hard
Delete all untracked files as well?
• git clean -d -f
Remove only ignored files (.gitignore)?
• git clean -d -X
Slide 38
Slide 38 text
STASHING CHANGES
Sometimes you want to save your edits but
don‘t want to commit just yet. Enter the stash
stack:
• git stash [save [--keep-index] [message]]
This saves the complete changeset to the
working copy. If using --keep-index (or -k),
changes already staged will not be saved with
the stash, but left in the working copy.
Slide 39
Slide 39 text
VIEWING STASHES
To list all stashes on the stack:
• git stash list
To view a specific stash content as a diff:
• git stash show stash@{0}
Substitute 0 with any of the numbers listed in
the stash list to view that stash.
Slide 40
Slide 40 text
MANAGING STASHES
To apply a given stash, use:
• git stash apply stash@{0} [--index]
To throw away a stash (or all of them):
• git stash drop stash@{0}
• git stash clear
To apply and drop in a single command:
• git stash pop stash@{0} [--index]
CREATING A BRANCH
FROM A SPECIFIC STASH
Sometimes you find out you should be doing
something in a separate branch and have a
stash you want moved:
• git stash branch my-branch stash@{0}
This will branch at the commit the stash was
created and pop the stash into the working
copy without commiting.
Slide 43
Slide 43 text
GIT TOOLS
Mac OSX:
• Tower
• GitBox
• Atlassian
SourceTree
• GitHub for Mac
Windows:
• GitHub for
Windows
• TortoiseGit
(ewww)