git-hero
From git-zero to
Michał Urbanek
Git as we know it
- clone
- branch
- add
- commit
- pull
- status
- push
- log
- checkout
- merge
- blame
- ...

Environment
PS1='\[\e[0;33m\]\u\[\e[0m\]@\[\e[0;32m\]\h\[\e[0m\]:
\[\e[0;34m\]\w\[\e[0;31m\]$(git_prompt)\[\e[0m\]\$ '
git_prompt ()
{
if ! git rev-parse --git-dir > /dev/null 2>&1; then
return 0
fi
git_branch=$(git branch 2>/dev/null| sed -n '/^\*/s/^\* //p')
echo " [$git_branch]"
}
# git completion
source ~/.git-completion.bash
Aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.visual "!gitk"
- no need to type long commands
- shortcuts for most frequent commands
- create commands that you think should exist
- run external commands with !
Staging area

# add file.txt to staging area
git add file.txt
# display changes scheduled for committing
git diff --cached
# add only patch of given file
git add -p
Work in progress
# git stash with description MESSAGE
git stash save MESSAGE
# list all stashes
git stash list
# show diff from stash STASH
git stash show -p STASH
# apply and remove last stash
git stash pop
# apply and remove stash STASH
git stash pop STASH
# custom alias to actually make a commit
git save
alias.save !git add -A && git commit -m 'SAVEPOINT'

Debugging with git
# see commits with last changes file.txt in lines 5-10
git blame -L5,10 file.txt
# see commits with last changes in file.txt before commit <COMMIT-ID>
git blame COMMIT-ID -- file.txt
# get all commits which diff contained TEXT
git log -S"TEXT"
# start bisect between GOOD and BAD commits
git bisect start BAD GOOD
# mark commit as correct
git bisect good
# mark commit as invalid
git bisect bad
# run command "test.sh" automatically for each commit
git bisect run test.sh

Are git commits immutable?

Git model
A DAG of immutable commit objects where branches are named mutable pointers into it

git commit --amend
- fix up the most recent commit
- combine staged changes with previous commit
- simply edit previous commit message

- actually it completely replaces previous commit with a new one

merge vs rebase
- they both solve the same problem
- integrate changes from one branch to another
- they just do it in very different ways
git merge
- easier to understand
- creates a new "merge" commit
- non-destructive
- easy to revert
- log might be confusing


git merge master feature
git rebase
- moves entire "feature" branch to begin on the tip of the master branch
- rewrites/simplifies project history
- creates brand new commits for each commit in original branch

git checkout feature
git rebase master


git pull --rebase
- by default pull performs merge
- this way it will rather perform rebase
- this behaviour can be set to default



rebase pros
- much cleaner project history
- no merge commits
- perfectly linear history - no forks
- easier to navigate with git bisect, git log, gitk



The dark side of rebase

The dark side of rebase
- loses context of workflow
- potentially catastrophic for collaboration workflow
The golden rule of rebase

- Is anyone else looking at this branch?
- YES - take your hands off the keyboard. NOW!
- NO - just do it!


Interactive rebase


git checkout feature
git rebase -i master
- more powerful then automated rebase
- offers full control over branche's history
- clean up messy history before merge
- like git commit --amend on steroids
- split, reorder, remove, alter existing commits

Rule of thumb
- use pull --rebase
- DO rebase small local branches
- do NOT rebase long living branches on which you collaborate with others
- in such case it's better to do an explicit merge --no-ff

Trust this guy
People can (and probably should) rebase their private trees (their own work). That's a cleanup.
But never other peoples code. That's a "destroy history".
Linus Torvalds

Where did my commits go?

Reflog
The reflog is Git’s safety net. It records almost every change you make in your repository, regardless of whether you committed a snapshot or not.
git reflog
Submodules

# add submodule from repository at <MODULE-URL>
git submodule add <MODULE-URL>
# see detailed submodule changes
git diff --submodule
# init submodule after clone
git submodule init
# populate submodule
git submodule update
# update submodule to newest version from submodules repo
git submodule update --remote
# update submodule and rebase local changes (if any)
git submodule update --remote --rebase
# push changes together with all local submodule commits
git push --recurse-submodules=on-demand
# useful aliases
git config alias.sdiff '!'"git diff && git submodule foreach 'git diff'"
git config alias.spush 'push --recurse-submodules=on-demand'
git config alias.supdate 'submodule update --remote --merge'

Cleaning up..
Command | Scope | Common use cases |
---|---|---|
git reset | Commit-level | Discard commits in a private branch or throw away uncommited changes |
git reset | File-level | Unstage a file |
git checkout | Commit-level | Switch between branches or inspect old snapshots |
git checkout | File-level | Discard changes in the working directory |
git revert | Commit-level | Undo commits in a public branch |
git revert | File-level | (N/A) |
git reset

git revert

References
- https://git-scm.com/book/en/v2/Getting-Started-Git-Basics
- https://git-scm.com/book/en/v2/Git-Tools-Submodules
- https://www.atlassian.com/git/tutorials
- http://git-scm.com/book/en/v2/Git-Branching-Rebasing
- https://blog.sourcetreeapp.com/2012/08/21/merge-or-rebase/
- http://nathanleclaire.com/blog/2014/09/14/dont-be-scared-of-git-rebase/
- http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html
- https://github.com/jakubnabrdalik/gitkurwa
- http://haacked.com/archive/2014/07/28/github-flow-aliases/

From git-zero to git-hero extended
By urbmic
From git-zero to git-hero extended
- 779