= git =
Git is a distributed version control and source code management (SCM) system.

[[http://git-scm.com/]] 

== SSH public key generation ==
{{{#!highlight sh
ls ~/.ssh
ssh-keygen # create ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub keys
cat ~/.ssh/id_rsa.pub # shows key to be sent to the git server admin
}}}

== Config ==
{{{#!highlight sh
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
git config --list
}}}

== Local config for repository ==
{{{#!highlight sh
git config user.name "John Doe"
git config user.email johndoe@example.com
git config --local --list
cat .git/config # [user]
}}}

== Create repository ==
{{{#!highlight sh
cd <project>
git init #create folder .git
touch README.md
touch .gitignore
git add . 
git commit -m 'Initial commit'
git remote add origin git@gitserver:/opt/git/project.git # setup origin for repository
git push origin master
}}}

Edit .gitignore
#for Java
 * *.jar
 * *.war
 * *.ear
 * *.zip

Sample .gitignore
{{{
*~
.metadata
*.class
*.jar
*.war 
*.ear 
*.zip
target/
}}}

== Clone repository ==
 * git clone git@git.server.net:repository.git # by ssh
 * git clone https://git.server.net/repository.git #by https
 * cd repository

== Branch creation based on current branch ==
 * git branch #show current branch
 * git checkout -b B/20130801/BRANCH-XYZ master # create new branch based on branch master
 * git branch -m B/20130801/BRANCH-XYZ B/20130801/BRANCH-ZZZ # rename local branch
 * git push origin B/20130801/BRANCH-ZZZ # push branch B/20130801/BRANCH-ZZZ to remote

== Commit to remote branch ==
 * git commit -am 'Message commit xyz ' --all #commit locally
 * git pull origin B/20130801/BRANCH-ZZZ # sync with remote branch
 # fix conflicts and commit conflict resolution
 * git push origin B/20130801/BRANCH-ZZZ # send changes to remote branch

 * git commit -am 'Message commit asdf ' --all #commit locally
 * git pull --rebase origin B/20130801/BRANCH-ZZZ # sync with remote branch with rebase
 # fix conflicts and commit conflict resolution
 * git push origin B/20130801/BRANCH-ZZZ # send changes to remote branch

== Merge to other branch ==
 * git checkout master # merge destination branch 
 * git pull origin master # sync dest branch
 * git merge --no-ff B/20130801/BRANCH-ZZZ # merge branch B/20130801/BRANCH-ZZZ to branch master
 * git pull origin master
 * git push origin master

{{{#!highlight bash
git checkout development
git checkout -b feature_branch origin/feature_branch
git add .
git commit -m "msg" # commit in feature branch
git checkout development
git pull origin development
git checkout feature_branch
git merge --no-ff development
git pull origin feature_branch
git push origin feature_branch
}}}

== Reapply .gitignore ==
 * cd <projectFolder>
 * git rm -r -f --cached .
 * git add .
 * git status #check files to be commited


= Setup git server on RHEL =
http://git-scm.com/book/en/Git-on-the-Server-Setting-Up-the-Server

Home folder for git user must have permissions only for that user. 
 * chown git . -R
 * chgrp git . -R

The bare repositories folders must have permissions only for git user. 
 * chown git . -R
 * chgrp git . -R

{{{#!highlight bash
sudo bash 
adduser git
su git
cd
mkdir .ssh
cd .ssh
git --version # git version 1.7.1

#generate and paste the pub key from my user on local machine
ssh-keygen -f id_rsa -p
cat ~/.ssh/id_rsa.pub #local machine

# in the git server
cd .ssh # git account
vim authorized_keys  #git server, paste the content of id_rsa.pub
cd ~
chmod 700 .ssh/
chmod 600 .ssh/authorized_keys 
ssh git@bitarus.allowed.org # test connection from local machine
vim /etc/passwd #change shell for git user
git:x:505:505::/home/git:/usr/bin/git-shell 

# create project on git server
cd /home/git
mkdir hello.git
cd hello.git
git --bare init

#create project on local machine
cd ~
cd gitRepository
mkdir hello
cd hello
git init
touch README
git add .
git commit -m 'initial commit'
git config --list #check config
git remote add origin git@bitarus.allowed.org:/home/git/hello.git
git push origin master
git log

}}}

== Revert file to original ==
 * git checkout -- testFile.txt

== Github change from https to ssh ==
 * git remote -v # check current remote repository
 * git remote set-url origin git@github.com:user/project.git

== Delete local branch development and checkout remote development branch ==
 * git branch -d development
 * git checkout -b development origin/development # get local branch from remote branch

== Switch between branches ==
 * git checkout development
 * git branch # check current branch 
 * git checkout master
 * git branch # check current branch 

== Get remote branch to local branch ==
 * git fetch origin
 * git checkout -b wiki origin/wiki # local branch wiki from remote origin/wiki

== Revert to HEAD revision ==
 * git reset --hard HEAD

== Make colors show properly on git diff and git log ==
 * git config --global core.pager 'less -R'

== Change commit message before a push ==
 * git commit --amend

== Files in branch changed between revisions ==
 * git diff --name-only hash1 hash2
 * git diff --name-only hash1 HEAD

== Clean untracked files and folders ==
 * git clean -n -d
 * git clean -f -d


== Reset to version in remote repository ==
 * git fetch origin
 * git reset --hard origin/master

== Git for windows (git bash) ==
 * https://git-scm.com/download/win

== Join several commits not pushed ==
Use the git rebase. 

 * git rebase -i origin/master

Pick (choose) several commits and put them all with the "squash" commit that usually is the most recent one. 
It may be cancelled using '''git rebase --abort'''.

== Difference between remote and local branch ==
 *  git diff origin/master..master

== GitFlow ==
 * https://datasift.github.io/gitflow/IntroducingGitFlow.html
{{{
New development (new features, non-emergency bug fixes) are built in feature branches:

Feature branches are branched off of the develop branch, and finished features and fixes are merged back into the develop branch when they’re ready for release

When it is time to make a release, a release branch is created off of develop:

The code in the release branch is deployed onto a suitable test environment, tested, and any problems are fixed directly in the release branch. This deploy -> test -> fix -> redeploy -> retest cycle continues until you’re happy that the release is good enough to release to customers.

When the release is finished, the release branch is merged into master and into develop too, to make sure that any changes made in the release branch aren’t accidentally lost by new development.

The master branch tracks released code only. The only commits to master are merges from release branches and hotfix branches.

Hotfix branches are used to create emergency fixes:

They are branched directly from a tagged release in the master branch, and when finished are merged back into both master and develop to make sure that the hotfix isn’t accidentally lost when the next regular release occurs.
}}}

== Create local branch from commit in current branch ==
 * git checkout -b test <commit sha1>

== Show differences in added/staged files with git add ==
{{{#!highlight bash
git add filex
git status
git diff --staged
git diff --cached
}}}

== Stash ==
{{{#!highlight bash
git stash
git stash list
git stash show -p > ~/Documents/stash_diff.txt
less ~/Documents/stash_diff.txt
git stash pop 
git stash clear # clear all stashes
}}}

== Update old commit message already pushed ==
{{{#!highlight bash
# mark as reword the commit to update
git rebase -i HEAD~2
reword 9b5ca7af9  Old commit
pick 7331d8be5 [prefix] good commit with prefix
# will show new console to add the missing prefix
# [prefix] Old commit
git log 
# replace pick with reword each commit that needs to be changed 
git push origin develop --force
}}}