View
426
Download
3
Category
Tags:
Preview:
DESCRIPTION
Notions of git, important commands and use cases.
Citation preview
of every dayNotions and more
Alan DescoinsTryolabs, 2014
Goals● Better understand what we do every day● Ask less questions (understand the man)● Improve some practices● Make fewer mistakes● Do something super specific ;)
● 2005, Linux kernel● Efficiency, simple design● Non-linear development
(thousands of parallel branches)
● Completely distributed
Origins and philosophy
Distributed● Nearly all operations
are local● All the machines have
ALL the information● Contrast with SVN,
CVS, etc.
Some theory● git init initializes a repository● Creates only one .git directory in the root (doesn’t
pollute)● Mini filesystem● Snapshots, not differences!
Git and the content● Tracking of content, NOT files● Vocabulary: tracked / untracked● Git objects
○ Blob (content)○ Tree (structure)○ Commit (points to a tree, + data)○ Tag (points to a commit, + data)
SHA-1
● One file per “content”● SHA-1 of the content (zlib) + a
header● Initially, loose object● Then packfile (efficiency,
heuristics…)● Example: find .git/objects -type f
Blob
Tree● Like a directory structure● Pointers to blobs or other trees● Represents a complete
snapshot of the state● Example: git ls-tree <sha-1>
Commit● Information about the trees● Who, when, why saved the tree● Points to the top level tree of the project● Tree hierarchy● Also SHA-1, different hash than the tree it
points to
Commit (2)
Tags● Pointer to a commit● Additional information, signature● So we don’t have to remember
the SHA-1...
The Holy TrinityA content may be in three states:● Committed● Modified● Staged
The Holy Trinity (2)Three parts of a project:● Working directory● Staging area (or index)● .git (repository)
Basic commands● git add - adds to the index (staging)● git commit - saves the index together with author,
message, date, etc.● git status - shows the file with differences between the
working dir, staging, and the untracked● git diff - what changed but is not staged● git diff --cached - what is going in the next commit● git log
Avoiding the staging● Sometimes, it may be easier to avoid the
staging area● git commit -a | git commit <archivo>● Automatically add to the staging, then
commit
Branches● Simply a pointer to a commit● As fast as it is to write 41 characters to a file
(SHA-1 + \n)● By default master● Special pointer HEAD (current branch)● Example: cat .git/HEAD
Branches (2)● git checkout to
switch branches
References● The HEAD pointer is a special case● Tags too: “an unmovable branch”
(lightweight tags)
Example: find .git/refs
Remotes● No central server● Can add several remotes, external copies of
the repo (URL)● The famous origin :)
Remote branches● Save the state of branches in remote repositories● They are local, but cannot be moved, only when you do
network operations (eg. git fetch).● The form is <remote>/<branch>
Example: cat .git/refs/remotes/origin/master
Fetch, push● git fetch - sync and update remote branches (moves
pointers)● Eg. git fetch <remote>● git pull - equivalent to git fetch and the git merge,
merges the local branch with the changes in the remote
● git push - update the remote branch with the local data● Eg. git push <remote> <branch>
Tracking branches● Local branches can “track” remote ones● Two possibilities:
○ git checkout --track <remote>/<branch>○ git push --set-upstream <remote> <branch>
● Now, when pushing you don’t have to type the name of the remote and the branch :)
Merges
● Fast-forward: git is smart and only needs to move a pointer
● Integrate changes of one branch into another
Merges (2)● Three way merge: commit not direct
ancestor of what I am merging in (non linear)● Git determines the best common ancestor● A merge commit is created, special because
it has more than one parent● Conflicts...
Three way merge
Rebasing● Another way to introduce changes of one
branch into another● Rewind & replay, rewrites the commits● From a common ancestor● History is always linear, even though it was
work originally done in parallel
Rebasing (2)● git rebase <new-base>
moves the commits from the current branch to the new base
● git rebase -i <new-base>lets us select actions for every commit
● git pull --rebase
● Never do rebase of a branch that is already pushed, or you pulled from somebody else○ Duplicate commits if someone does merge○ Arguable: if the remote branch is yours and used as backup○ Use git push --force, if you are certain nobody else works in the
branch● If you rebase to get changes by other developers
locally, do it as often as possible.
Golden rules
Rebase vs MergeWhy rebase?● Clean, linear history● Open-source collaboration, many demand it● Easier for code review
Why merge?● Easier to solve conflicts (only once)● Less risk
git reset● Often used● Used wrong, can cause loss of data
(workdir unsafe)● Three most used options:
○ --soft○ --mixed○ --hard
git reset...● move the branch HEAD points to so it points to target
commit (stop if --soft)● then make the staging look like that (stop if --mixed,
default option)● then make the working dir look like that (if --hard, it is
workdir usafe!)
Examples of git reset● With HEAD in dev branch, do git reset master
○ now dev y master point to the same commit● With HEAD in branch master, do git reset --hard
origin/master○ now my local master branch is identical to the
remote (discard local changes)● git reset --soft HEAD~
○ Undo the last commit without losing changes
Unstaging files● When doing git reset <file> we don’t specify
a branch or commit SHA● Equivalent to git reset --mixed HEAD <file>● Moves a particular file out of staging,
opposite of git add :)
git checkout● git checkout <branch> is superficially similar
to git reset --hard <branch>
● Two differences:○ Workdir safe! :D Checks to avoid data loss.○ reset moves the branch that HEAD points to,
checkout moves the HEAD pointer itself.
git checkout of a file● git checkout <branch> <file>
○ As with reset, now it doesn’t make sense for it to move HEAD. Replaces only <file> in the workdir (workdir usafe!).
○ Would be the same as git reset --hard <branch> <file>
○ But that command does not exist :)
Common situations (1)● “I need to pull but there are changes I am
working on, and I don’t want to commit yet”○ git stash○ It’s a stack○ Apply with git stash pop.
Common situations (2)● “There is a bug in a branch, I need to know
what commit introduced it”○ git bisect○ Binary search, driven by git. Very easy!○ git bisect start
git bisect bad <commit>git bisect good <commit>
● Test on every step (git makes a checkout)
Common situations (3)● “I made one (or several) commits in the
wrong branch, haven’t yet pushed though!”○ If the correct branch does not yet exist
■ git checkout -b <correct branch>■ git reset over the old branch
○ If the branch already existed■ git cherry-pick (or git rebase --onto)■ git reset over the old branch
Common situations (4)● “I have many changes in a file and only want
to commit some of them”○ git add -p or git commit -p○ git will ask for every part, whether to add it or not
Common situations (5)● “I need to change some commits”● “I need to delete some commits”● “I need to change the order of some
commits”○ git rebase -i (--interactive)○ Easy to use○ Rewrites history, asking us what to do for each
commit
Common situations (6)● “I am doing a merge with many conflicts and
I want to stop it and get back to where I was before”○ git merge --abort
(Images from git-scm and others ;) )
Didn’t learn git
Recommended