2014/05/19, CMU
http://www.cs.cmu.edu/~soonhok
Git: "The stupid content tracker"
"I did not really expect anyone to use it
because it’s so hard to use…"
-"Linus Torvalds goes off on Linux and Git"
(Fake Interview)
"Once you realize that git is just a DAG
with commit objects as vertices,
and pointers (refs) into that graph,
it becomes a lot simpler to understand"
Repository \(\simeq\) Graph
Node (Commit) \(\simeq\) Files
Label (refs) \(\simeq\) Branch / Tag / etc
OSX
$ brew install git
Linux
$ sudo apt-get install git
Windows
Visit http://git-scm.com/
$ git config --global user.name "your-name"
$ git config --global user.email "your-email-address"
# Colorize console output
$ git config --global color.ui auto
# Force files to be LF on Mac/Linux
$ git config --global core.autocrlf input
# Force Windows to convert to CRLF
# on checkout and to LF on `add`
$ git config --global core.autocrlf true
By default for "git log –all"
Now, "git la"
From Scratch
# New project
$ git init newproject
$ cd newproject
# ...start coding
From Existing Dir
# Legacy project tree
$ cd existingproject
$ git init
# Add all the code
$ git add .
$ git commit -m "Initial import"
git add
git status
git commit -m "Helpful message"
$ git clone git@github.com:soonhokong/dreal
Cloning into 'dreal'...
remote: Reusing existing pack: 79707, done.
remote: Counting objects: 127, done.
remote: Compressing objects: 100% (98/98), done.
remote: Total 79834 (delta 37), reused 74 (delta 29)
Receiving objects: 100% (79834/79834), 49.25 MiB | 2.34 MiB/s, done.
Resolving deltas: 100% (39555/39555), done.
Checking connectivity... done.
$ git remote -v
origin git@github.com:soonhokong/dreal (fetch)
origin git@github.com:soonhokong/dreal (push)
$ git push
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 286 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@github.com:soonhokong/dreal
bee5818..40155b4 master -> master
$ git fetch origin
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:soonhokong/dreal
bee5818..40155b4 master -> origin/master
$ git merge origin/master
Updating bee5818..40155b4
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
$ git pull origin master
From github.com:soonhokong/dreal
* branch master -> FETCH_HEAD
Updating bee5818..40155b4
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
Don't use git pull!
Use git fetch and then git rebase (or git merge)
The way people are using SVN
You can use git in this way, too
What's a problem?
I'm working at CMU…
I want to go home and resume the work.
So I push what I've done so far to the repo
@Home, I pull what I pushed and resume the work.
In the meantime, Leo pushed a commit to the repo.
I finished my part at home, push to the repo.
Problem: Repo will be filled with intermediate commits
Problem: Single Sync Point = \(\uparrow\) Merge Conflicts
Not Scalable (\(\le\) 5 members)
There is the Blessed repository.
Clone personal repo (origin):
$ git clone git@github.com:soonhokong/dreal.git
$ git remote -v
origin git@github.com:soonhokong/dreal.git (fetch)
origin git@github.com:soonhokong/dreal.git (push)
Add blessed repo:
$ git remote add blessed git@github.com:dreal/dreal
$ git remote -v
blessed git@github.com:dreal/dreal.git (fetch)
blessed git@github.com:dreal/dreal.git (push)
origin git@github.com:soonhokong/dreal.git (fetch)
origin git@github.com:soonhokong/dreal.git (push)
Most of time, we push to personal repos.
You can do destructive update (forced push) on your repo.
When the work is solid, we push to the blessed.
or make a pull-request.
Many meaningful git operations
can be expressed
in terms of the rebase command.
Fresh Morning!
Commit three changes.
Push to the personal repo.
Attempt to push to the blessed repo.
$ git push blessed master
Counting objects: 28, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 955 bytes | 0 bytes/s, done.
Total 9 (delta 6), reused 0 (delta 0)
To git@github.com:dreal/dreal.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:dreal/dreal.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
non-fast-forward??
git fetch –all
non-fast-forward!
git merge blessed/master
git push blessed master – OK…
OK?
OK?
Merge Hell
git rebase will free you!!
non-fast-forward!
Let's rebase my three commits on top of blessed/master.
rebase blessed/master
fast-forwardable
git push blessed master
I want to combine the three commits into one.
git rebase origin/master doesn't do anything.
Run git rebase -i origin/master
Run git rebase -i origin/master
pick 40155b4 Fix an Issue #1
pick 42e5db9 Minor Fix of Previous Fix
pick a31c7cd Minor Minor Fix or Previous Fix
# Rebase ec2ae2b..cf0977c onto ec2ae2b
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Run git rebase -i origin/master
pick 40155b4 Fix an Issue #1
f 42e5db9 Minor Fix of Previous Fix
f a31c7cd Minor Minor Fix or Previous Fix
# Rebase ec2ae2b..cf0977c onto ec2ae2b
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Rebase will create a new commit.
It's OK to rebase and destructively update personal repo.
It's OK to rebase and destructively update personal repo.
But you should not destructively update the blessed repo.
Because other users base on blessed/master.
"Git Reset Demystified"
(Available from package-list)