Git quick help

This is just quick review of git explaining basic "how to".

If you need you could always read "official documentation":http://git-scm.com/documentation or man.

Getting project from git repository
It's as simple as it could be:

$ git clone ssh://your_login@osll.spb.ru/git/geo2tag/ Initialized empty Git repository in /home/your_login/geo2tag/.git/ your_login@osll.spb.ru's password: remote: Counting objects: 9355, done. remote: Compressing objects: 100% (8905/8905), done. remote: Total 9355 (delta 4989), reused 0 (delta 0) Receiving objects: 100% (9355/9355), 19.32 MiB | 83 KiB/s, done. Resolving deltas: 100% (4989/4989), done. $

But it's important to understand what this thing is realy mean: In contrast to the svn you haven't got some main repository - you just have some parrent (origin) which from your pjogect was cloned. So you could clone even from your local copy:

$ ls geo2tag $ git clone geo2tag geo2tag_local Initialized empty Git repository in /home/your_login/geo2tag_local/.git/ $ ls geo2tag geo2tag_local $

Preparing example
The best way to learn something is practice - let's try to do this.

First we need to emulate server. With git it's very simple:

~$ cd /tmp/ /tmp$ mkdir test /tmp$ cd ./test/ /tmp/test$ mkdir server /tmp/test$ cd ./server/ /tmp/test/server$ git init --bare Initialized empty Git repository in /tmp/test/server/ /tmp/test/server$ cd .. /tmp/test$ ls server

That's it =)

PS Flag --bare means that in this copy will be in some way "root" copy

Get local copy
/tmp/test$ git clone server local Initialized empty Git repository in /tmp/test/local/.git/ warning: You appear to have cloned an empty repository. /tmp/test$ ls local server /tmp/test$

Let's make one other local copy (explain why later)

/tmp/test$ git clone server local2 Initialized empty Git repository in /tmp/test/local2/.git/ warning: You appear to have cloned an empty repository. /tmp/test$ ls local local2 server /tmp/test$

Adding and commit files into git
Let's add some file to server and add it to git:

/tmp/test$ cd ./local/ /tmp/test/local$ /tmp/test/local$ touch readme /tmp/test/local$ git add ./readme /tmp/test/local$ git commit -am "Add readme file" [master (root-commit) f1aa941] Add readme file 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 readme /tmp/test/local$

Flag -a means that all changes will be commited.

Getting latest version from server
/tmp/test/local$ cd ../local2/ /tmp/test/local2$ ls -a . ..  .git /tmp/test/local2$ git pull remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From /tmp/test/server * [new branch]     master     -> origin/master /tmp/test/local2$ ls readme /tmp/test/local2$

Using branches
Some times we need to change code which will could block work of other people. That's why we must use branches.

Create branch
Let's create new branch:

/tmp/test/local$ git branch /tmp/test/local$ git branch our_branch /tmp/test/local$ git branch our_branch /tmp/test/local$ git checkout our_branch Switched to branch 'our_branch' /tmp/test/local$ git branch master /tmp/test/local$
 * master
 * master
 * our_branch

We should notice that after creating branch, we still stay on old branch. For switching between branches use "git checkout" "git branch" lists branches and points current branch

Work in branch
/tmp/test/local$ touch new_file_in_branch /tmp/test/local$ git add ./new_file_in_branch /tmp/test/local$ git commit -am "new file in branch" [our_branch ffd16bd] new file in branch 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 new_file_in_branch /tmp/test/local$ ls new_file_in_branch readme /tmp/test/local$ git checkout master Switched to branch 'master' /tmp/test/local$ ls readme /tmp/test/local$ git checkout our_branch Switched to branch 'our_branch' /tmp/test/local$

We could see that file know exists in our branch but doesn't exist in master branch

Merge branches
At first we will change something on server - while we were doing something in branch server version could be changed!

/tmp/test/local$ cd ../local2 /tmp/test/local2$ vim readme /tmp/test/local2$ git status no changes added to commit (use "git add" and/or "git commit -a") /tmp/test/local2$ git diff diff --git a/readme b/readme index e69de29..3f421ec 100644 --- a/readme +++ b/readme @@ -0,0 +1 @@ +Some changes in server version /tmp/test/local2$ git commit -am"Some changes in server version" [master 205be70] Some changes in server version 1 files changed, 1 insertions(+), 0 deletions(-) /tmp/test/local2$ git push origin master Counting objects: 5, done. Writing objects: 100% (3/3), 279 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To /tmp/test/server d70e083..205be70 master -> master /tmp/test/local2$ cd ../local /tmp/test/local2$
 * 1) On branch master
 * 2) Changed but not updated:
 * 3)   (use "git add ..." to update what will be committed)
 * 4)   (use "git checkout -- ..." to discard changes in working directory)
 * 5) 	modified:  readme
 * 1) 	modified:  readme

Then pull this changes to local copy to branch *master*:

/tmp/test/local$ git branch master /tmp/test/local$ git checkout master Switched to branch 'master' /tmp/test/local$ git pull remote: Counting objects: 5, done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From /tmp/test/server 06564e6..89b5dae master     -> origin/master Updating 06564e6..89b5dae Fast forward readme |   1 + 1 files changed, 1 insertions(+), 0 deletions(-) victor@NBDell:/tmp/test/local$ cat ./readme Some changes in server version /tmp/test/local$
 * our_branch

Now everything ready to merge branches:

/tmp/test/local$ git branch our_branch /tmp/test/local$ git merge our_branch Merge made by recursive. 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 new_file_in_branch victor@NBDell:/tmp/test/local$ ls new_file_in_branch readme /tmp/test/local$
 * master

Conflicts while merging branches
Let's learn how to resolve conflicts in merge

Make some conflict: /tmp/test/local$ git checkout conflict_branch Switched to branch 'conflict_branch' /tmp/test/local$ vim ./readme /tmp/test/local$ git commit -am "Some change in conflict branch" [conflict_branch f4f2e66] Some change in conflict branch 1 files changed, 1 insertions(+), 0 deletions(-) /tmp/test/local$ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 2 commits. /tmp/test/local$ vim readme /tmp/test/local$ git commit -am "Some change in master" [master f36c2b7] Some change in master 1 files changed, 1 insertions(+), 0 deletions(-) /tmp/test/local$

And try to merge this branches:

/tmp/test/local$ git branch conflict_branch our_branch /tmp/test/local$ git merge conflict_branch Auto-merging readme CONFLICT (content): Merge conflict in readme Automatic merge failed; fix conflicts and then commit the result. /tmp/test/local$
 * master

Ouch!

Resolve conflicts
We could use git mergetool to resolve conflict

/tmp/test/local$ 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 (kdiff3): victor@NBDell:/tmp/test/local$ ls new_file_in_branch readme  readme.orig victor@NBDell:/tmp/test/local$ cat readme Some changes in server version New line in conflict branch victor@NBDell:/tmp/test/local$ cat readme.orig Some changes in server version <<<<<<< HEAD:readme New line in master branch

=
New line in conflict branch >>>>>>> conflict_branch:readme /tmp/test/local$ git commit -am "conflict resolved" [master 100acd0] conflict resolved victor@NBDell:/tmp/test/local$

Without commit we could not push anything because it will be blocked by MERGE_HEAD: You have not concluded your merge. (MERGE_HEAD exists)

Push to server
After merging and checking that every thing is ok we need to push all changes to server:

/tmp/test/local$ git push warning: You did not specify any refspecs to push, and the current remote warning: has not configured any push refspecs. The default action in this warning: case is to push all matching refspecs, that is, all branches warning: that exist both locally and remotely will be updated. This may warning: not necessarily be what you want to happen. warning: warning: You can specify what action you want to take in this case, and warning: avoid seeing this message again, by configuring 'push.default' to: warning:  'nothing'  : Do not push anything warning:  'matching' : Push all matching branches (default) warning:  'tracking' : Push the current branch to whatever it is tracking warning:  'current'  : Push the current branch Counting objects: 15, done. Delta compression using up to 2 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (11/11), 1.29 KiB, done. Total 11 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (11/11), done. warning: updating the current branch warning: Updating the currently checked out branch may cause confusion, warning: as the index and work tree do not reflect changes that are in HEAD. warning: As a result, you may see the changes you just pushed into it warning: reverted when you run 'git diff' over there, and you may want warning: to run 'git reset --hard' before starting to work to recover. warning: warning: You can set 'receive.denyCurrentBranch' configuration variable to warning: 'refuse' in the remote repository to forbid pushing into its warning: current branch. warning: To allow pushing into the current branch, you can set it to 'ignore'; warning: but this is not recommended unless you arranged to update its work warning: tree to match what you pushed in some other way. warning: warning: To squelch this message, you can set it to 'warn'. warning: warning: Note that the default will change in a future version of git warning: to refuse updating the current branch unless you have the warning: configuration variable set to either 'ignore' or 'warn'. To /tmp/test/server 89b5dae..100acd0 master -> master /tmp/test/local$

Warnings here only because we didn't configure server

Gui for git
You could use some program with gui if it's hard to understand what's happenning in your git copy. For example:

QGit GITK