Git - David
What is Git ⌘
British Slang
- Variant of get
- A contemptible person, often a fool
- A bastard
Short definition ⌘
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 History ⌘
- 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 Community Book http://book.git-scm.com/
- Manual (must read) http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
- Git – SVN Crash Course http://git.or.cz/course/svn.html
- Git - CVS Crash Course http://git.or.cz/course/cvs.html
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⌘
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
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 ⌘
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) ⌘
- Add the new line to afile.txt
- Check the difference between index and the file
- Add the file
- Check the difference between repository and the staging
- Revert all not committed changes to the file (the file should be the same as in the repo)
- Add new line to a file
- 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) ⌘
- Add the line “bad changes” to afile.txt
- Commit your changes
- 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) ⌘
|
DAG and gitk
DAG and Git objects
Staging Changes ⌘
Getting Existing Repo ⌘
git clone http://git.drupal.org/project/pathauto.git cd pathauto
git remote -v
origin http://git.drupal.org/project/pathauto.git (fetch) origin http://git.drupal.org/project/pathauto.git (push)
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 ⌘
- create a bare repository in rcs/main
- Clone bare repo in myrepo
- Modify a file
- 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)
|
git tag -a stable-1 1b2e1d63ff
|
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) ⌘
- Create branch v2.x
- Modify a couple of files in the branch
- Merge the branch with master
- 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 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 ⌘
- Create a branch “quickfix”
- add a couple of changes afile.txt in quickfix branch
- switch to master
- Commit 2 changes into the master branch
- switch back to quickfix
- analyse situation in gitk --all
- rebase quickfix branch to master
- analyse situation in gitk -all
- prune dangling objects
- gitk --all
Cherry Picking ⌘
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 ⌘
Combining Commits ⌘
- Version upto 1.6
git format-patch v1.0..HEAD git reset v1.0 git apply *.patch git commit
- 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