Git - David

From Training Material
Jump to navigation Jump to search
title
Git - Introduction
author
David Parkin (NobleProg Ltd)

What is Git ⌘

British Slang

  • Variant of get
  • A contemptible person, often a fool
  • A bastard

Git-fool.png


Short definition ⌘

Git-definitions.png

Why Git? ⌘

Linus Torvalds has quipped about the name "Git":

"I'm an egotistical bastard, and I name all my projects after myself. First Linux, now git."

Git-why1.png Git-why2.png


Git History ⌘

Git-history.png

  • 2002 - Linux Kernel develops in BitKeeper
  • 2005 Apr 6 - BitMover drops free license and Linus starts GIT project
  • 2005 Jun 16 - GIT is officially used to track Linux
  • 2007 Feb 14 - GIT 1.5.0 is released (more humane)


Getting Help ⌘

 git commit -h 
 git help commit
 man git-commit

Git Locally ⌘

  • Git as an extension to the file system
  • No network required
  • Repository deleted if .git folder is deleted

Initializing a repository for existing files

git init
git add .
git commit

Setting Up Username ⌘

git config --global user.name "Bernard"
git config --global user.email b@noblepog.com
  • we can set up config globally - per user
  • or for everyone --system

git config --global alias.view "log --oneline --decorate --graph --all"

Browsing Repository ⌘

git show rev:file 
git show rev:directory  
git show rev

Basic Commands ⌘

git add file   
git rm file 
git mv file

Moving Files ⌘

git mv afile.txt movedfile.txt

# equivalent to

mv afile.txt movedfile.txt
git rm afile.txt
git add movedfile.txt

File Status⌘

pub?id=1Fp1iYscfMixvIWduFJMejQzmdDmPsvXt3QS3kQ7WSnE&w=800&h=600&.png

Committing new files and changes ⌘

# Commiting new files
git add newfile.txt
git commit


# Changes
echo new line >> afile.txt
git add afile.txt
git commit
or  
echo new line >> afile.txt
git commit -a 

Git-commit-a1.png Git-commit-a2.png

Committing Folders ⌘

mkdir afolder
touch afolder/file1.txt
touch afolder/file2.txt
git add afolder
git commit

Empty Folders ⌘

mkdir emptyfolder
git add emptyfolder
git commit 
# Nothing to commit
#Workaround
touch emptyfolder/.gitignore
git add emptyfolder/.gitignore
git commit
#Worked

Exercises ⌘

1. Create a file structure

sudo mkdir /rcs
sudo chmod 777 /rcs 
mkdir /rcs/repo
cd /rcs/repo
echo first line > afile.txt

2. Initialize repository

3. Stage the file

4. Check whether the file has been staged

5. Commit the changes

6. Check whether the files have been committed

7. What is the SHA1 of the commit?

Tracking Changes ⌘

git status
git diff
git diff rev path
git show

Diff ⌘

pub?id=1_elrohhhWPx8aIqYYZS4D-8Y54VDp_-reloS37NW91A&w=800&h=300&.png

Diff Examples ⌘

echo Commited Changes >> afile.txt 
git commit -a -m "asdf"

echo Staged Changes >> afile.txt 
git add afile.txt

echo Not-tracked Changes >> afile.txt 


git diff
[master c81907a] Commited changes
 1 file changed, 1 insertion(+)
diff --git a/afile.txt b/afile.txt
index fc321d0..978da6e 100644
--- a/afile.txt
+++ b/afile.txt
@@ -1,3 +1,4 @@
 first line
 Commited Changes
 Staged Changes
+Not-tracked Changes
git diff --cached
diff --git a/afile.txt b/afile.txt
index 37a8835..fc321d0 100644
--- a/afile.txt
+++ b/afile.txt
@@ -1,2 +1,3 @@
 first line
 Commited Changes
+Staged Changes
git diff HEAD
diff --git a/afile.txt b/afile.txt
index 37a8835..978da6e 100644
--- a/afile.txt
+++ b/afile.txt
@@ -1,2 +1,4 @@
 first line
 Commited Changes
+Staged Changes
+Not-tracked Changes


git diff HEAD^
diff --git a/afile.txt b/afile.txt
index 08fe272..978da6e 100644
--- a/afile.txt
+++ b/afile.txt
@@ -1 +1,4 @@
 first line
+Commited Changes
+Staged Changes
+Not-tracked Changes

Who fixed (spoiled) it? - git annotate ⌘

git annotate afile.txt
03be4dec        (   Bernard     2012-09-02 14:53:27 +0200       1)first line
c81907a9        (   Bernard     2012-09-02 16:50:24 +0200       2)Commited Changes
00000000        (Not Committed Yet      2012-09-02 17:08:44 +0200       3)Staged Changes
00000000        (Not Committed Yet      2012-09-02 17:08:44 +0200       4)Not-tracked Changes

Undoing Changes ⌘

git checkout --        # Remove not staged changes and local copy
git reset HEAD         # Remove changes from cache but leaves local copy intact

Amending latest commit⌘

You can amend your latest commit (re-edit the metadata as well as update the tree)

git commit –amend

To toss your latest commit away completely

Exercise (Index) ⌘

  1. Add the new line to afile.txt
  2. Check the difference between index and the file
  3. Add the file
  4. Check the difference between repository and the staging
  5. Revert all not committed changes to the file (the file should be the same as in the repo)
  6. Add new line to a file
  7. Commit the changes

Reverting with New Commit ⌘

Revert the most recent commit:

git revert HEAD

This will create a new commit which undoes the change in HEAD.

Other example:

git revert HEAD^


Exercise (git revert) ⌘

  1. Add the line “bad changes” to afile.txt
  2. Commit your changes
  3. Use git revert to remove

Cleaning Untracked Files ⌘

touch untrackedfile.txt
git status
echo untrackedfile.txt > .gitignore
git status
git clean -n
git clean -f

.gitignore syntax ⌘

Lines starting with '#' are considered comments.

# Ignore any file named foo.txt.
foo.txt
# Ignore (generated) html files,
*.html
# except foo.html which is maintained by hand.
!foo.html
# Ignore objects and archives.
*.[oa]

http://git-scm.com/docs/gitignore

gitignore vs excludes ⌘

.gitignore

  • version-controlled
  • distributed to other repositories via clone (i.e., files that all developers will want to ignore)

$GIT_DIR/info/exclude

  • specific to a particular repository but which do not need to be shared with other related repositories (e.g., auxiliary files that live inside the repository but are specific to one user’s workflow)

~/.gitconfig (core.excludesfile)

  • ignore in all situations (e.g., backup or temporary files generated by the user’s editor of choice)

Exercise ⌘

  • echo something > Thumb.db
  • Add Thumb.db file to .gitignore
  • Add .gitignore to the repository and commit
  • Check whether Thumb.db is ignored in afolder
  • Clone the repo to /rcs/repoclone
  • Check whether the Thumb.db is ignored there

Browsing Repo ⌘

gitk
git gui
git log
git show 
git show HEAD:afolder
git show HEAD:afile
git show commit (can be tag or branch)
 git show HEAD^
 git show master
 git show c01a0d43


GIT under the bonnet ⌘

  • Object Database
  • SHA1
  • DAG (Directed Acyclical Graph)
  • Index

Object Types ⌘

blob

  • store file data

tree

  • ties one or more "blob" objects into a directory structure
  • a tree object can refer to other tree objects, thus creating a directory hierarchy

commit

  • ties such directory hierarchies together into a directed acyclic graph (DAG) of revisions
  • each commit contains the object name of exactly one tree (snapshot of the tree)
  • a commit refers to "parent" commit objects that describe the history of how we arrived at that directory hierarchy

tag

  • symbolically identifies and can be used to sign other objects
  • It contains
    • object name (SHA1, e.g. 232A...)
    • type of another object
    • a symbolic name (e.g. version 1.0.1)
    • optionally, a signature (PGP or GPG)


Directed Acyclic Graph (DAG) ⌘

Git-dag.png
  • Stored as a linked list
  • Uses SHA1 as references
  • One root (object without parents)
  • Multiple parents allowed
    • merge (2 parents)
    • octopus merge (3 or more)

DAG and gitk

Git-gitk.png


DAG and Git objects

Git-dag-git-o.png

Staging Changes ⌘

Git-stag-change.PNG

Getting Existing Repo ⌘

git clone  http://git.drupal.org/project/pathauto.git
cd pathauto
git remote -v


git branch -a
* 7.x-1.x
 remotes/origin/4.6.x-1.x
 remotes/origin/4.7.x-1.x
 remotes/origin/5.x-1.x
 remotes/origin/5.x-2.x
 remotes/origin/6.x-1.x
 remotes/origin/6.x-2.x
 remotes/origin/7.x-1.x
 remotes/origin/HEAD -> origin/7.x-1.x
 remotes/origin/MAIN
 remotes/origin/master


Getting new Changes ⌘

git pull gituser@git.nobleprog.net:/gitrepo/pathauto


Push Changes to central repo ⌘

echo Change in readme >> README.txt 
git commit -a
git push
git push gituser@git.nobleprog.net:/gitrepo/pathauto

Adding Remote ⌘

git remote add central  gituser@git.nobleprog.net:/gitrepo/pathauto
git pull central 7.x-1.x
git push central 7.x-1.x

Exercises ⌘

  1. create a bare repository in rcs/main
  2. Clone bare repo in myrepo
  3. Modify a file
  4. Push your changes to main

Tagging ⌘

  • Tag is not a copy of the repo
  • Tag doesn't create a revision
  • Tag is just an another name for a revision (apart of SHA1)
git tag tagname # creates  tag from HEAD of the current branch
git tag # shows all tags
git tag tagname -m “message”
git tag tagname 6544ce
git tag -l v1

Lightweight vs Object Tags ⌘

Lightweight Object Tags
git tag v1.1.0 1b2e1d63n
git push –tags (optional presentation with cloning)  
  • “a branch that never moves”
  • cannot include a comment
  • cannot be signed cryptographically
git tag -a stable-1 1b2e1d63ff

  • If one of -a, -s, or -u <key-id> options is passed
  • Needs to contain a message (can be empty)
  • can tag any object (not only commit object)


Exercise (Tagging) ⌘

  • Tag the HEAD as v1.0
  • Add another line to a file
echo second line >> afile.txt
  • Commit changes
  • Tag the commit as v1.1
  • Add third line and commit
echo third line >> afile
  • Show difference (use git diff) between HEAD and the tag v1.0
  • List all the tags

Branching and Merging ⌘

git branch

list all branches

git branch <branch>

create a new branch named <branch>, referencing the same point in history as the current branch

git branch <branch> <start-point>

create a new branch named <branch>, referencing <start-point> (branch, tag or commit)

git branch -d <branch>

delete the branch <branch>; if the branch you are deleting points to a commit which is not reachable from the current branch, this command will fail with a warning.

git branch -D <branch>
  • forces to do even branch points to a commit not reachable from the current branch
  • failed experiment branches
  • use only for changes in your repository
git checkout <branch>

switch to the <branch>

git checkout -b <new> <start-point>

create a new branch <new> referencing <start-point>, and check it out


Dealing with Branches and Tags ⌘

 git clone git://git.kernel.org/pub/scm/git/git.git
 git branch
 git branch -r
 git tag
 git checkout maint
 git branch
 git checkout v1.7.4
 git branch

Creating Branches ⌘

cp repo/ repo.bak -R; cp central/ central.bak -R

Create new branch and switch working copy

git branch experiment
git checkout experiment
git checkout -b experiment

Merging ⌘

  • switch to experiment
  • modify the afile.txt
git commit -a
git checkout master
modify afile.txt (different part)
git commit -a
gitk --all
git branch
git merge experiment
gitk --all


Exercise (REmoving) ⌘

  1. Create branch v2.x
  2. Modify a couple of files in the branch
  3. Merge the branch with master
  4. Remove the branch v2.x

Exercises (remote branching) ⌘

  • Create a branch “quickfix” from a master branch
git checkout master
git checkout -b quickfix
  • create quickfix.txt in quickfix branch and commit
touch quickfix.txt
git add quickfix.txt
git commit -m "quickfix"
  • switch to master
git checkout master
  • Commit 2 changes into the master branch
echo 1 >> afile.txt; git commit -a -m "change1"
echo 2  >> afile.txt; git commit -a -m "change2"
  • switch back to quickfix
git checkout quickfix
  • analyse situation in
git log --oneline --decorate --graph --all
  • Push the quickfix to the production
push origin quickfix
  • On production
git fetch origin quickfix
git branch -a
git checkout origin/quickfix -b quickfix
  • On Devel
merge quickfix into master

revert merge

rebase quickfix into master

  • delete quickfix branch

Reverting Merges ⌘

Adding commit with reverted changes

git revert

Before Committing

git reset --hard HEAD

After Committing

git reset --hard ORIG_HEAD

use only if you committed it only to your private repo

Rebasing ⌘

Git-rebasing1.png Git-rebasing2.png Git-rebasing3.png

git checkout -b mywork origin
echo mywork changes >> afile.txt
git commit -a
git checkout master
echo some new func >> afile_master.txt
git add afile_master.txt
git commit
gitk --all
git rebase mywork
gitk --all
git prune
gitk -all


Exercise ⌘

  1. Create a branch “quickfix”
  2. add a couple of changes afile.txt in quickfix branch
  3. switch to master
  4. Commit 2 changes into the master branch
  5. switch back to quickfix
  6. analyse situation in gitk --all
  7. rebase quickfix branch to master
  8. analyse situation in gitk -all
  9. prune dangling objects
  10. gitk --all


Cherry Picking ⌘

Git-cherry-picking.jpg
git checkout -b exp
echo Not Cherry1 >> afile.txt 
git commit -a -m NotCherry1
echo Cherry >> afile.txt 
git commit -a -m Cherry
echo Not Cherry2 >> afile.txt 
git commit -a -m NotCherry2
git checkout master
echo masterchange >> afile_master.txt 
git add afile_master.txt
git commit -a -m "Master Change"
git log exp
git cherry-pick 3c8f

Git-cherry.png


Stashing ⌘

  • git-stash to save the current state of your work
  • git stash save "work in progress for foo feature"
  • echo “bug fix” >> afile.txt
  • git commit -a -m "fixed the bug"
  • git stash pop


Workflow Structure ⌘

Git-wf-structure.png


Combining Commits ⌘

  1. Version upto 1.6
git format-patch  v1.0..HEAD
git reset v1.0
git apply *.patch
git commit
  1. Version 1.7 onwords
 git reset v1.0
 git commit

Git - Bisect ⌘

 # Initiallize repo
 cd /g
 mkdir /g/tmp
 cd tmp
 mkdir repo
 cd repo/
 git init  


  echo "exit 0" > code.sh
  git add code.sh; 
  git commit -a -m "c0"
  
  # Genereate 10 revision which do not spoil the script
  for i in $(seq 10) ; do   echo "# round 1 $i" >> code.sh ; git commit -a -m "c$i" ; done
  
  # Spoil the script
  echo "exit 1" > code.sh
  git commit -a -m "bug revision"
 
  # generate 20 revisions which do not spoil already spoiled script
  for i in $(seq 20) ; do   echo "# round 2 $i" >> code.sh ; git commit -a -m "c$i" ; done
 


 git bisect start
 git bisect bad
 # mark first revision as good
 git bisect good  6d34b 

 git bisect run bash code.sh
running bash code.sh
Bisecting: 7 revisions left to test after this (roughly 3 steps)
[65e896df0fb1a865e8678bc2145f1621b802acfd] c7
running bash code.sh
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[480515f739bf6dd9a2a6ab47d8626aea805d4880] bug revision
running bash code.sh
Bisecting: 1 revision left to test after this (roughly 1 step)
[52de39416f0f93a1b95f744de05699baa85ab224] c9
running bash code.sh
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[22ef2aaf18c69aa420534303ceeec2078154357c] c10
running bash code.sh
480515f739bf6dd9a2a6ab47d8626aea805d4880 is the first bad commit
commit 480515f739bf6dd9a2a6ab47d8626aea805d4880
Author: Your Name <you@example.com>
Date:   Tue Dec 4 00:02:09 2012 +0000

    bug revision

:100644 100644 68d815b9ee3a9b590f2be9db2adfe37d715f964f 379a4c986e3265e08e9da42c56ec747619c56a33 M	code.sh
bisect run success