Git
🤔 WTF is it?
Sylvain Fankhauser
Liip
May 2017
Q: what are branches / tags?
A commit is identified by a hash
commit 66959dab20a37949828ac0502509656ac775f56d Author: Sylvain Fankhauser <sylvain.fankhauser@liip.ch> Date: Wed Nov 30 13:32:30 2016 +0100 Remove duplicate import
A branch/tag is a shortcut to a commit
$ git rev-parse master
66959dab20a37949828ac0502509656ac775f56d
It is stored as a file in .git/refs/heads
And contains the hash it points to
$ cat .git/refs/heads/master
66959dab20a37949828ac0502509656ac775f56d
Q: what does git fetch do?
git fetch updates your remote branches & tags pointers
eg. origin/master
Q: how do I compare revisions?
git log master..origin/master
Show remote commits that are not in local master branch. That's how pull requests work!
git log master...origin/master
Show commits that are not common to both branches
Q: how do I commit a file?

Reset
Working tree ➝ index
Playing with the index
# add file to the index
git add [-p] path/to/file
# remove file from the index
git reset [-p] path/to/file
# stash status of working directory, including index (-u means include untracked files)
git stash [-u]
# stash status of working directory and index and give the stash a name
git stash save "WIP try to fix this mess"
# show contents of stash (-p means show the diff)
git stash show [-p]
# show the list of existing stashes
git stash list [-p]
# apply stash and remove it
git stash pop [stash@{n}]
My commit process
# add everything to the index
git add --all
# review changes
git diff --cached
# reset chunks if necessary
git reset -p path/to/file
# review changes
git diff --cached
# finally, commit with meaningful commit message (define a standard!)
git commit
Q: I can't push
To gitlab.liip.ch:tooyoo/tooyoo
! [rejected] HEAD -> sprint-3/mdb-21 (non-fast-forward)
error: failed to push some refs to 'git@gitlab.liip.ch:tooyoo/tooyoo'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git pull? git fetch? git merge? git rebase? git push --force?
Does it matter?
Interlude: what does push do?
Without argument, pushes to tracking branch
As set by --set-upstream-to and recorded in .git/config
Destination can be set explicitly
$ git push origin
$ git push origin master
$ git push origin master:newbranch # push master to newbranch
$ git push origin :newbranch # delete newbranch
Q: what is a merge?
Fast-forward merges
mdb-72 / A---B---C---D---E origin/mdb-72
A---B---C---D---E origin/mdb-72 mdb-72
Merged branch only has common ancestors with current branch
git merge [--ff-only] origin/mdb-72
Non fast-forward merges
D---E mdb-72 / A---B---C \ origin/mdb-72
Current branch has ancestors absent from merged branch
git merge [--no-ff] origin/mdb-72
D---E---m mdb-72 / / A---B---C---/ \ origin/mdb-72
Q: what is a rebase?
Rebasing avoids merges with local commits
Rebase
D---E mdb-72 / A---B---C \ origin/mdb-72
Replays non-common ancestors. This recreates commits!
git rebase origin/mdb-72
D'---E' mdb-72 / A---B---C \ origin/mdb-72
REBASING
KILLS
Be careful with rebase
- Only rebase local commits
- Never EVER rebase a merge commit because someday someone will notice and will come knocking at your door and bad things will happen
Q: enough with the warnings, how should I rebase?
Try to fast-forward merge first
[merge]
ff = only
[pull]
ff = only
rebase = false
Then either use git pull or git fetch + git merge
until...
fatal: Not possible to fast-forward, aborting.
Know what you rebase
It's dangerous to go alone! Take this:
[alias]
incoming = "!git log ..@{u}"
outgoing = "!git log @{u}.."
inc = "!git incoming"
out = "!git outgoing"
You don't want to break the repository
Make sure you know what you're rebasing with git outgoing
If git outgoing --merges outputs anything, DO NOT rebase!
DO NOT REBASE!
DO. NOT. REBASE!
Q: what about git pull?
git pull = fetch + merge
But it depends on your configuration
Q:
I SCREWED UP. STOP. SEND HALP. STOP. KTHXBAI. STOP.
--abort is your BFF
Works with merge and rebase
git reflog is your 2nd BFF
$> git reflog
83b206d HEAD@{0}: checkout: moving from sprint-4/mdb-20 to HEAD^
0e7b8ae HEAD@{1}: commit (amend): MDB-20 review fixes
051a6db HEAD@{2}: rebase finished: returning to refs/heads/sprint-4/mdb-20
051a6db HEAD@{3}: rebase: MDB-20 review fixes
83b206d HEAD@{4}: rebase: checkout refs/remotes/origin/sprint-4/mdb-20
753d540 HEAD@{5}: commit: MDB-20 review fixes
136b954 HEAD@{6}: commit (merge): Merge remote-tracking branch 'origin/sprint-4/master' into sprint-4/mdb-20
Combine it with the reset command
D---E mdb-72 / A---B---C \ origin/mdb-72
D---E
/
A---B---C
\
origin/mdb-72
mdb-72
git reset --hard origin/mdb-72
Use show to view a specific version of a file
$ git show master:index.php
Best practices
1. Have a git expert
In case you screw up
2. Create atomic commits
add -p / reset -p / stash -p are your friends
3. Review git history during code review
Check for unrelated commits
4. Run tests after merging
You have tests, right?
5. Don't be afraid to merge
It's okay to merge an in-progress feature branch in your feature branch
6. Make it easy to run any revision of the code
Fixtures anyone?
7. Commit non-feature specific fixes on master branch
To make sure everyone benefits from them
8. Use --no-ff when merging into master
To keep track of the merge
9. Always refer to remote branch when merging
This will avoid problems when your local branch is not up-to-date
10. If you force push, use --force-with-lease
Your coworkers will thank you
11. Write meaningful commit messages
Use multiple lines!
commit 10016ebf1603d0771b50b61720efd7fbd311b688
Author: Sylvain Fankhauser <sylvain.fankhauser@liip.ch>
Date: Mon Jan 9 15:50:33 2017 +0100
KOMPRA-230 fix empty graphs
If a competence layer doesn't have any children the outer bubble won't
appear. That's probably because this piece of code was copy-pasted from
StackOverflow and wasn't adapted.
12. Do not rebase pushed commits
Unless you're absolutely sure no one used them
13. Leave conflict mentions in commit message
They can help debugging if something goes wrong
Finally
Ask any question you have now 🤓
Thank you!
master
- Sprint 4 starts, Alice starts working on MDB-82 and creates a commit
- 1 day later, Bob starts working on MDB-83 which depends on MDB-82
- Alice finishes working on MDB-82 and requests a dev review
- Bob reviews Alice's work and merges it into
sprint-4/master - Chloe fixes an important bug in production, MDB-404
- Her commit is reviewed and merged into master
- master is merged into the current sprint branch
sprint-4/master
sprint-4/mdb-82
sprint-4/mdb-82
sprint-4/mdb-83
sprint-4/mdb-82
sprint-4/master
support/mdb-404
master
sprint-4/master
Team rawbot
workflow
WTF is git
By Sylvain Roflmao
WTF is git
- 206