Git

Why and how to use Git?

Dyn Inc Lunch n' Learn Seminar (Part I)

Goals

...

take a minute and write your own ones.

Git

Git is revision control system. You use one to make sure changes you do over time could be restored.

Git positions itself as distributed, decentralized RCS.

Every working copy is effectively a fully functional fork of git's Direct Acyclic Graph structures and work files extracted from them.

(stores all revision information in BLOBs optimized for fast operations)

"Git" stands for...

I’m an egotistical bastard, and I name all my projects after myself. First ‘Linux’, now ‘git’.
(Linus Torvalds, according to Wikipedia and its sources)

“Why do I need all this?!
        Just say how to use it!”

 

...but directed graphs are so cool!

  • Revision is the product of previous state and applied diff.
  • Git is one big hierarchy of objects that represent revisions.
  • HEAD, master and others track history of revision objects they point to.

Creating Git Repository

$ git init myrepo
Initialized empty Git repository in myrepo/.git/
$ cd myrepo
$ echo "Hello World" > test.txt
$ git add test.txt
$ git commit test.txt -m 'Adding a greeting'
[master (root-commit) 4be30d5] Adding a greeting
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 test.txt
$ git log
commit 581ff59640caec1cf54d1390c626a1a40e7a74b0
Author: Alex Sergeyev 
Date:   Fri Jun 1 18:02:36 2012 -0400

    Adding a greeting

try it with "git status" after various steps

Branching

"checkout -b" is same as
git branch feature; git checkout feature
$ git checkout -b feature
Switched to a new branch 'feature'
$ git branch -v
* feature 581ff59 Adding a greeting
  master  581ff59 Adding a greeting
$ echo 'Git is cool' > aboutgit.txt
$ git add aboutgit.txt
$ git commit -m 'New article'
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 aboutgit.txt
$ git checkout master
Switched to branch 'master'
$ git branch -v
  feature f11314d New article
* master  581ff59 Adding a greeting
$ ls
test.txt
$ echo "As introduced by Brian Kernighan & Dennis Ritchie" >> test.txt
$ git commit test.txt -m 'Some background info'
[master 6fb241a] Some background info
 1 files changed, 1 insertions(+), 0 deletions(-)

Cloning/remote branching

$ git clone ssh://localhost/~/myrepo newdir
Cloning into 'newdir'...
asergeyev@localhost's password: 
remote: Counting objects: 22, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 22 (delta 5), reused 0 (delta 0)
Receiving objects: 100% (22/22), done.
Resolving deltas: 100% (5/5), done.
$ cd newdir
$ git branch -v
* master 6fb241a Some background info
$ git branch -rv
  origin/HEAD    -> origin/master
  origin/feature f11314d New article
  origin/master  6fb241a Some background info
no backtracking here
$ cd ../myrepo
$ git branch -r
$ 

Remote branches are fully independent from yours.

You can change name of branch when you pulling it.

Reflog

(nap if you did not like DAG part)

$ git reflog master
6fb241a master@{0}: commit: Some background info
581ff59 master@{1}: commit (initial): Adding a greeting
$ git reflog feature
f11314d feature@{0}: commit: New article
581ff59 feature@{1}: branch: Created from HEAD
$ git checkout feature
Switched to branch 'feature'
$ git checkout -q master
$ git checkout -q feature
$ git reflog HEAD
f11314d HEAD@{0}: checkout: moving from master to feature
6fb241a HEAD@{1}: checkout: moving from feature to master
f11314d HEAD@{2}: checkout: moving from master to feature
6fb241a HEAD@{3}: commit: Some background info
581ff59 HEAD@{4}: checkout: moving from feature to master
f11314d HEAD@{5}: commit: New article
581ff59 HEAD@{6}: checkout: moving from master to feature
581ff59 HEAD@{7}: commit (initial): Adding a greeting

As long as you are not re-writing the history
and commit often you are safe with git.

Tags: Named References

  1. You can push/pull tags adding "--tags" to them.
  2. Tags work for commands that use commit id or branch name.
  3. Tags can be PGP signed and verified later.

Simple Merge

$ git checkout -q feature
$ ls > catalog
$ git add catalog
$ git commit -m "Article catalog"
[feature 95f74c0] Article catalog
 1 files changed, 3 insertions(+), 0 deletions(-)
  create mode 100644 catalog
git merge <branchname>
$ git checkout -q master
$ git merge feature
Merge made by the 'recursive' strategy.
 aboutgit.txt |     1 +
 catalog      |     3 +++
 2 files changed, 4 insertions(+), 0 deletions(-)
 create mode 100644 aboutgit.txt
 create mode 100644 catalog
$ git commit .
# On branch master
nothing to commit (working directory clean)
$ WT* WHY!?
bash: !?: event not found
(auto-commits the changeset)
$ git reflog master
14efb87 master@{0}: merge feature: Merge made by the 'recursive' strategy.
6fb241a master@{1}: commit: Some background info
581ff59 master@{2}: commit (initial): Adding a greeting

Rebase

$ git checkout -qb newart
$ git add story.txt
$ git commit -aqm 'New story'
$ git checkout -q master
$ git mv test.txt hello.txt
$ git commit -aqm "Better file name"
$ git checkout -q newart
$ ls >> catalog
$ git commit -aqm 'Adding story to the catalog'
$ git checkout -q master
git rebase <branchname>
$ git rebase newart
First, rewinding head to replay your work on top of it...
Applying: Better file name
$ git log --graph --pretty=oneline --abbrev-commit
* a60f50e Better file name
* 8dcbafb Adding story to the catalog
* c3dcc45 New story
*   14efb87 Merge branch 'feature'
|\  
| * 95f74c0 Article catalog
| * f11314d New article
* | 6fb241a Some background info
|/  
* 581ff59 Adding a greeting
very good reading
$ man git-merge
$ man git-rebase

What happens

(merge)
(rebase)

Working with remotes

1. List/update current remotes

$ git remote -v
$ man git-remote

2. Sending your work to remote branch

$ git push myremote localbranch:remotebranch
$ git push myremote
$ git push myremote +localbranch:remotetomerge

3. Checking out changes made by others

$ git pull --no-commit myremote remotebranch:localbranch
$ git pull myremote

4. Applying patches

$ git apply somepatch.diff

Undoing things

Staged file back to one saved in repo:

$ git checkout -- filename.ext

Appending stuff to last commit:

$ git commit --amend

Reverting state to "before last commit:" (be careful)

$ git reset --soft HEAD^

Preparing reversed changeset:

$ git revert -n COMMIT_OR_REF

You are going to like git when you...

1. will know what HEAD~3^2 means

$ git show HEAD^^^^2

2. would consider making your own command aliases

$ git config --global alias.granny 'show HEAD^^'

3. will know difference between two and three dots

$ git log --left-right --oneline origin/master...master

4. will finish reading about commands with dashes

$ man git-cherry-pick
$ man git-diff-tree
$ man git-read-tree
$ git merge --squash -s subtree --no-commit mybranch

5. would figure out interactive git tools (very helpful)

$ git rebase -i HEAD~3
$ git add -i
$ git add -p
$ git mergetool

QUESTIONS?