Use the left/right arrow keys to navigate, 's' to enable/disable scrolling.

GIT

Source Code Management in the Cloud-Era

gitlogo

What’s git?

“Git is a distributed version control system

focused on speed, effectivity and real-world

usability on large projects.”

git-scm.com

SCM

Why? What? When?

Why git is better?

Distribuited

local branch are simple and cheap

(you don’t need to email your sysadmin anymore)

Offline work

work from home

work during server maintenance

Fast, Safe and Efficient

a lot of commands work on local copy

any local copy is a backup

git-fsck

let’s git started

configure and customize git


$ git config --global user.name "Luca Greco"
$ git config --global user.email "luca.greco@alcacoop.it"
$ git config --global alias.ci "commit"
$ git config --global alias.who "shortlog -s --"

create your first git repository


$ mkdir hellogit
$ cd hellogit
$ git init
Initialized empty Git repository in .git/

create some file and ignore junk files


$ echo "Hello, git" > README
$ echo "*~" >> .gitignore

see what’s changed


$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	README
# .gitignore
nothing added to commit but untracked files present (use "git add" to track)

your first commit


$ git add .
$ git commit -m "Initial commit"
[master (root-commit) 31177ca] Initial commit
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 README
 create mode 100644 .gitignore

see what’s changed


$ git status
# On branch master
nothing to commit (working directory clean)

add more changes and see what’s changed (again)


$ echo "More content" >> README
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")

save (commit) your changes


$ git commit -a -m "add more content"
[master 7ceec5a] add more content
 1 files changed, 1 insertions(+), 0 deletions(-)

check your history (log)


$ git log
commit 7ceec5a7d68c54f8a2377986a7abf38c76cb9e89
Author: Luca Greco <luca.greco@alcacoop.it>
Date:   Sat May 8 19:59:20 2010 +0200

    add more content

commit 31177cadb6ecfdc0752be2b30258134b0bb2d758
Author: Luca Greco  <luca.greco@alcacoop.it>
Date:   Sat May 8 19:57:25 2010 +0200

    Initial commit

git tools

egit: eclipse plugin

Egit

Project page

User guide

Developing with git

ProGIT File Statuses diagram

(from Pro GIT ebook)

undoing your changes


$ rm *

    DOOOOOOOOOOOOOOOOOHHHHHHHH!!!!
    
$ git checkout .

    FFFFFFFFFFIIIIIIIIIIIIIIIIUUUUU!!!

reverting to specific (1/2)


$ git checkout 31177c README

$ git status
# Not currently on any branch.
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   README

reverting to specific (2/2)


$ git diff HEAD
diff --git a/README b/README
index fe1efe2..22f4644 100644
--- a/README
+++ b/README
@@ -1,2 +1 @@
 Hello, git
-More content

tag a revision


$ git tag 0.1
$ git tag -l
0.1
$ cat .git/refs/tags/0.1 
7ceec5a7d68c54f8a2377986a7abf38c76cb9e89
$ git checkout 0.1 README
$ git status
# On branch master
nothing to commit (working directory clean)
config init status
add rm mv
diff commit log tag

Parallel development

Feature Branches

ProGIT Feature Branches diagram

(from Pro GIT ebook)

Create a branch


$ git checkout -b feature1
Switched to a new branch 'feature1'
$ git status
# On branch feature1
nothing to commit (working directory clean)
$ echo "feature1" > feature1
$ git add feature1
$ git commit -m "added feature1 prototype"
[feature1 329576e] added feature1 prototype
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 feature1

switching branches


$ git checkout master
Switched to branch 'master'
$ echo "bugfix" >> README
$ git commit -a -m "bugfix 01"
[master c8aa13f] bugfix 01
 1 files changed, 1 insertions(+), 0 deletions(-)

gitk –all

gitk all


$ git log --graph --all --oneline
* c8aa13f bugfix 01
| * 329576e added feature1 prototype
|/  
* 7ceec5a add more content
* 31177ca Initial commit

$ git log --graph --all
* commit c8aa13f07ea074cf25ba4b9adfce6fb20ee702a3
| Author: Luca Greco <luca.greco@alcacoop.it>
| Date:   Sat May 8 20:51:36 2010 +0200
| 
|     bugfix 01
|    
| * commit 329576ee58336a01f379b7325cf3e5577f1d6094
|/  Author: Luca Greco <luca.greco@alcacoop.it>
|   Date:   Sat May 8 20:50:09 2010 +0200
|   
|       added feature1 prototype
|  
* commit 7ceec5a7d68c54f8a2377986a7abf38c76cb9e89
| Author: Luca Greco <luca.greco@alcacoop.it>
| Date:   Sat May 8 19:59:20 2010 +0200
| 
|     add more content
| 
* commit 31177cadb6ecfdc0752be2b30258134b0bb2d758
  Author: Luca Greco <luca.greco@alcacoop.it>
  Date:   Sat May 8 19:57:25 2010 +0200
  
      Initial commit

git log –since=2.weeks

merge a local feature branch

git merge gitk view


$ git checkout master

$ git merge feature1
Merge made by recursive.
 feature1 |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 feature1

or rebase a short life branch (1/2)


$ git checkout feature1

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added feature1 prototype

or rebase a short life branch (2/2)


$ git checkout master
Switched to branch 'master'

$ git merge feature1
Updating c8aa13f..cace0c8
Fast forward
 feature1 |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 feature1

$ git status
# On branch master
nothing to commit (working directory clean)

after rebase…

git rebase gitk view

… and after merge

git rebase gitk view

clone checkout branch
pull push fetch
merge rebase

submodules (1/2)


$ mkdir bigproject
$ cd bigproject

$ git init
Initialized empty Git repository in /tmp/bigproject/.git/

$ git submodule add http://github.com/rpl/hello-world.git hello-world
Initialized empty Git repository in /tmp/bigproject/hello-world/.git/
got fabf8ce92a771c4b2f1b93d9f0cf0383e37d14dc
...

submodules (2/2)


$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   .gitmodules
#	new file:   hello-world

$ git commit -m "added hello-world submodule"
[master (root-commit) e1beace] added hello-world submodule
 2 files changed, 4 insertions(+), 0 deletions(-)
 create mode 100644 .gitmodules
 create mode 160000 hello-world

set a submodules to a specific revision (1/2)


$ cd hello-world/

$ git checkout 3fa7c4
Note: moving to '3fa7c4' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 3fa7c46... Added BIT , a horribly verbose language

set a submodules to a specific revision (2/2)


$ cd ..

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   hello-world
#
no changes added to commit (use "git add" and/or "git commit -a")

$ git commit -a -m "revert hello-world submodule to a previous revision"
[master b008d2a] revert hello-world submodule to a previous revision
 1 files changed, 1 insertions(+), 1 deletions(-)

git supports your workflow…

mixing centralized decentralized development

(from “A successful Git branching model”)

ANY workflow

collaborating with git

github octocat

(from tachikoma)

github

=

social coding

lots of opensource projects

lots of opensource developers

free public repository hosting

fast and simple fork/merge from web

companies using github

Yahoo

Facebook

TechCrunch

projects using github

hadoop

cassandra

jquery

rails

erlang

clone an hosted repository


$ git clone http://github.com/git/hello-world.git
Initialized empty Git repository in /tmp/hello-world/.git/
Getting alternates list for http://github.com/git/hello-world.git
Getting pack list for http://github.com/git/hello-world.git
Getting index for pack 8fdd83b4a87545a242e85a41075c5889ecd8a4e7
Getting pack 8fdd83b4a87545a242e85a41075c5889ecd8a4e7
 which contains 3fa7c46d11b11d61f1cbadc6888be5d0eae21969
walk 3fa7c46d11b11d61f1cbadc6888be5d0eae21969
...

pull from origin


$ git pull origin master
From http://github.com/git/hello-world
 * branch            master     -> FETCH_HEAD
Updating 85a0e40..3fa7c46
Fast forward
 BIT.bit |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 BIT.bit

add changes to master


$ echo '(insert "Hello world")' > elisp_hw.elisp
$ git add elisp_hw.elisp
$ git commit -m "Added elisp"
[master fabf8ce] Added elisp
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 elisp_hw.elisp

fork on github

Fork on github

push changes


$ git remote add myfork git@github.com:rpl/hello-world.git
$ git push myfork master
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 295 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:rpl/hello-world.git
   3fa7c46..fabf8ce  master -> master

pull request

Pull request

amend


$ git commit -a -m "small fix on REAME"
[branch1 10d2deb] small fix on REAME
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git commit -a -m "small fix on README" --amend
[branch1 5313811] small fix on README
 1 files changed, 1 insertions(+), 1 deletions(-)

resolve conflicts (1/6)


$ git checkout -b branch_xyz HEAD^
Switched to a new branch 'branch_xyz'

$ edit README # create a conflict

$ git commit -a -m "fix and cleanup README"
[branch_xyz 78e4185] fix and cleanup README
 1 files changed, 1 insertions(+), 19 deletions(-)
 
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.

$ git merge branch_xyz 
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.

resolve conflicts (2/6)


$ git status
README: needs merge
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	unmerged:   README
#
no changes added to commit (use "git add" and/or "git commit -a")

resolve conflicts (3/6)


$ git mergetool
merge tool candidates: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge emerge vimdiff
Merging the files: README

Normal merge conflict for 'README':
  {local}: modified
  {remote}: modified
Hit return to start merge resolution tool (meld): 

resolve conflicts (4/6)

meld conflicts

resolve conflicts (5/6)

meld conflicts resolved

resolve conflits (6/6)


$ git commit -a -m "MERGE: merged branch_xyz and resolved some conflicts on README"
[master 3217c1f] MERGE: merged branch_xyz and resolved some conflicts on README

resolve rebase conflicts (1/3)


$ git reset HEAD^ ; git checkout . ; git checkout branch_xyz
README: locally modified
Switched to branch 'branch_xyz'

$ edit README # do some other change

$ git commit -a -m "added todo in the README"
[branch_xyz 320e9b4] added todo in the README
 1 files changed, 2 insertions(+), 0 deletions(-)

resolve rebase conflicts (2/3)


$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: fix and cleanup README
error: patch failed: README:1
error: README: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging README
CONFLICT (content): Merge conflict in README
Failed to merge in the changes.
Patch failed at 0001 fix and cleanup README

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

resolve rebase conflicts (3/3)


$ git mergetool
[...]

$ git rebase --continue
Applying: fix and cleanup README
Applying: added todo in the README

create a simple git server

given a linux base server

create a git user

add your developer keys into ~git/.ssh/authorized_keys

install git-core on server (and clients)

scp -r myproject/.git git@server:~/repository.git

cd myproject

git remote add origin git+ssh://git@server/home/git/repository.git

git push origin master

git-web

git instaweb –httpd=[apache|lighttpd|webrick]

git instaweb –stop

gitosis and gitolite

manage a git server

managed from a git repository (full of configuration files and ssh keys)

create new git repositories

per user/group/repo ACL


from PROGIT: gitosis howto | gitolite howto

convert repositories from X to git

Interaction with other SCM

git hooks

ticketing integrations

automatic deploy

fine grained ACL on commit/push

email on commit/push


ProGIT: Customizing Git - Git Hooks

Copyright (C) 2010 - Alca Società Cooperativa

http://learn.alcacoop.it - learn@alcacoop.it

released under CreativeCommons 2.5 by-nc-sa