Background:  I remember driving through the Peak District with snow piled five or six feet high either side of the road as we came off the hills to the converted barn we were staying in.  Great snow drifts for the kids, and even with the distractions I learnt all about Git….

All details herin are cribbed from Scott Chacon and Pro Git.

This work is a reminder for the author and in no way represents a full guide,  if you want the truth please refer to Scott’s book.

Git stores head ptrs for every snapshot, with ptrs going back through time. A snapshot can be a local branch, a master branch, a remote branch or a tag(non editable snapshot).

Every file (blob) is stored with a SHA-1 hash (checksum), and has a set of files which means it can assocaiate blobs with Sha codes to files and versions. Unlike other version control systems Git has a full history of every file held locally in the .git sub dir. This makes it really quick. You can create branches, switch to them, work, stage the changes, switch to other branches, merge stuff, push and pull stuff from remote repositories all in a hodge podge of collaboration - unlike SVN (say) which has one central repository. Git is famous for being used by Android, Linux Kernal etc. Linux have a Dictator, Lieutenant, developer hierachy which means devs can work on topic branches, Lieutenants merge into their master branches, Dictator merges thier branches into the master branch and then pushes his/her master into the blessed repository.

So, you can have central SVN like repo’s, or you can have peers with their own and resynch as you wish etc. Its all alot more chaotic and you can structure how you work in many ways. Even ignore all that, get going and worry about that stuff later.

Note git does not track files moving between dirs.

There is a short section on Stash at the end of this page.

For workflow, read this: https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow (Open in Chrome)

What is SHA-1

40 character string calculated on a hash of the file contents.

Stages of work

You edit a file, you can stash it (preserve it to switch branches).

Or you can stage it - prepare a snapshot of files for the next commmit.Commmit and all staged files are moved permanently into the Git directory.Tracked files were in the last snapshot and can be: unmodified, modified or staged.

Config

/etc/gitconfig values for every user ~/.gitconfig specific for user (c:\Documents and Settings$USER) .git/config specific to the single repository

First time setup

git config --global user.name "John Doe"
gif config --global user.email "me@myemail.com"

Editor setup

git config --global core.editor emacs

diff tool

git config --global merge.tool vimdiff

What are my settings

git config --list
git config user.name

Help pages

git help <verb>
git <verb> --help
man git <verb>

Track an existing dir

git init

version control files

git add [wild cards, or file names etc]

eg git add *.java

Starting a server (eg for you to clone on your lan)

git daemon --base-path=/c/2013-dev/javaprojects/ --export-all

Note: where c:/git is the base of all your dev work. and is readonly, for a push access use:

git daemon --base-path=/c/2013-dev/javaprojects/ --export-all --enable=receive-pack

Note: I run this from the Git bash shell, seems to work…

Clone a repo

git clone [url]

Url protocols

depends on the server, so git://, or http(s)://, or user@server:/path.git

Whats going on/

git status

Track new files

git add [filename]

Stage modified files

git add [filename]

NOTE: this stages it at this time, if you edit it again the staged version will NOT include the new edits. Run git add again to include the new edits

How to ignore files

cat .gitignore
# comment, this is ignored
*.a
# no .a files etc etc

What has changed but not staged

git diff

What is staged

git diff --staged
git diff --cached

Commit the staged stuff

git commit
git commit -m "Jire ABC:7676 Fixed the null ptr on user logout"

Commit staged and modified stuff (miss out git add)

git commit -a -m 'a commment'

Remove file from git

git rm [filename]

Force removal of modified file

git rm -f [filename]

Remove a file from Git but keep on disk

git rm --cached [filename]

Move a file

git mv file_from file_to

Note this like using the OS to rename a file and then using git rm, git add

See commmits in reverse order

git log

See changes in each commit

git log -p

Limit log to last x entries

git log -p -2

See abbreviated stats

git log --stat

Log with shorter form

git log --pretty=oneline

–pretty can take short, full and fuller

Log with formatting, eg for auto parsing

git log --pretty=format:"%h - %an"

%H=hash, %h=short hash, %T=tree hash, %t=short tree hash, %P=parent hash, %p=short parent hash, %an=author, %ae=email, %ad=date, %ar=relative date, %cn=committer name, %ce=email, %cd=date, %cr=relative date, %s=subject

Committer is the person promoting towards master branch, author is the author.

See an version graph

git log --pretty=format:"%h %s" --graph

Other log options

-p for patch
--stat
--shortstat
--nameonly
--name-status
--abbbrev-commit
--since=2.weeks
--since=2013-03-29
--grep etc etc

To see graphical logs

gitk

Changing your last commit

git commmit --amend

You could do a git add prior to this, and the file will be added to the previous commmit.

To unstage a file

git reset HEAD filename

Revert any edits to a modified file

git checkout -- filename

See which remote repos

git remote

See remote urls

git remote -v

Add a remote repo

git remote add [remote-name] [url]

Get from remote repo

git fetch [remote-name]

Note that this gets the data, but does not checkout over your work, so you can do this with no risk

Clone to the origin

git clone [url]

This creates a special remote-name called origin. So you could update it using

git fetch origin

Get from remote and merge into your work

git pull

Publish your work upstream

git push [remote-name] [branch-name]

So, if you cloned then you have an automatically assigned remote name of origin as your master branch. So to push to where you cloned from

git push origin master

Info on a remote repo

git remote show [remote-name]

Rename a remotes shortname

git remote rename [current name] [new name]

so if it was called jonathan and is now called tony then the branch has changed from jonathan/master to tony/master

Remove reference to remote

git remote rm tony

List tags

git tag

List tags starting

git tag -l 'v1.4.*'

Create annoted tag

git tag -a v1.4 -m 'My version 1.4'

you could then use git show v1.4 to see details.

Sign a tag with GNU Provacy Guard (GPG)

git tag -s v1.5 -m 'my signed 1.4'

Note that we used -s this time

Verifying tags

git tag -v [tag-name]

You need the signers public key for this to work well.

Sharing tags

git push [tag-name]

Auto-completion

in Git source code download in contrib/completion/git-completion.bash Copy into your home dir and add to .bashrc the line source ~/.git-completion.bash Press tab tab and auto completion should work

Aliases

git config --global alias.co checkout

would mean you could do git co rather than git checkout

Create a branch

git branch [branch name]

Switch to a branch

get checkout [branch name]

Create branch and switch to it

git checkout -b jira7676

Merge branch back to master

git checkout master
git merge jira7676

Fast forward

If the merge can be done with the same history (ie no conflicts) then this is called fast forward.

Delete a branch

git branch -d jira7676

Merge conflicts

git status

After a merge this will highlight any conflicts, which you can manually  fix, look for <<<< and ====== and >>>> You can also use git mergetool

See your branches

git branch

See branches and last commit

git branch -v

See whats merged into my current branch

git branch --merged

Branched not merged with work on

git branch --no-merged

Force delete a branch with modifications

git branch -D jira7676

Remote branches

There are commands to create remote branches, rename them, track them and so on, read the book!

Rebasing Rather than merging changes into my current branch, we can go back to the commmon ancestor and reapply the changes from the rebased branch onto my current checked out branch, and then reapply my changes on my current branch. eg you have edits on jira7676 branch, and others have edited master. So

git checkout jira7676
git rebase master
git checkout master
git merge jira 7676

This will make it look like master has a linear set of checkin’s rater than show a jumble of branches. Very useful if contributing to someone elses master.

Rebase shorthand

git rebase [basebranch] [jira branch]

This is shorthand to replay [jira branch] onto the [basebranch], then you checkout [basebranch] and git merge [jira branch] again.

Rebase no-no

Do not rebase commmits that you have not pushed to a public repo. If you do you will be changing SHA’s for the same work and messing with your colleagues code - they will have to merge etc.

Eclipse plug-in

eGit