Git - Distributed Source Control System

GIT is a distributed source control system. It allows programmers to work and commit locally (without server interaction), and then synchronize (using git pull/git push) with remote repositories to enable collaboration with other programmers.

The most common setup is to have a main git repository (barebone only, no working directory) living in a server. Each developer can get a "clone" from the remote repository to their local machines, make changes and then commit locally. Once they are ready they can "synchronize" (pull/push) changes with the main repository.

Since the system is distributed programmers can work "offline" once they get a copy. The don't need access to the remote repository while they change and commit locally. Even if the source repository is destroyed it would be possible to reconstruct it (+/- programmer's changes) using any of the programmers local repositories


Short notes about GIT. Please let me know if you see any mistake

Git Online References

Git Website

Git book online (MUST READ)

Git for windows

Git @ Github:

Common terms

working area
Contains all the files that have been modified, added or removed, but are not ready for commit until they are moved to the staging area

staging area (Index)
Contains all the files that have been modified, added or removed, and are ready to be commited
Also called Index

Untracked files
Files that git doesn't know about (new files). "git add ..."is necessary to add them to staging area.

(Not to confuse with CVS HEAD). Current branch that we are working on, default branch is called "master"

If you rebase from branch branch1 onto a branch2 you will put the branch2 commits ON TOP of the commits from branch1.

Global Configs

Setting up user/email to identify with remote git repository (i.e:

git config --global "userremoterepository"
git config --global

Cloning remote repository

Getting remote repository files into local machine to start changing and commiting files locally. This Will create folder "mylocalproject"

git clone mylocalproject		

Things to avoid

  • Avoid rebasing onto a remote branch, this will cause many problems with other developers history, etc... You can still rebase onto a local branch (rebase flow)

  • Avoid git push --force. It can erase history/commits from other users!!!

Common Operations

To move changes from working area to staging area:

git add -u  (move all changes to staging area except for new files)
git add .  (move all changes to staging area except for rm deletes)
git add -A  (move all changes to staging area)		 	

To view which files are in working area and which are in staging area:

git status		 	

Viewing differences

git diff (differences between working directory and stating area)

git diff --cached (difference between staging area and last commit!!!)

git diff [filename]  (for a specific file name)


Removing/deleting files

git rm filename  (stages the removal of the file, and also removes the file from working directory) 

git rm --cached filename (stages the removal of the file, doesn't remove from working directory) 

Renaming files

git mv old_file_name new_file_name					 	

Above command is a shortcut for:

mv old_file_name new_file_name
git rm old_file_name
git add new_file_name			

To Commit

Committing will use the staging area, not the working area. Changes in the working area are not committed!. Used "git add....." to move modified changes from working to stating area before committing
git commit -m 'my commit description...' (commits from staging area)

git commit -a -m 'my commit description...' (add things from working area into staging area and then commits)

Viewing history

git log (Show all commits)

git log [filename]  (show commits for file)

git log -p  (Show all commits and the diffs as well)

git log -2  (show last 2 commits)

git log -p -2   (show diffs for last 2 commits)

gitk (Visual tool to view difs!!!)

Modifying last commit

Allows for modification of last commit message, and adds any staging area change to the previous commit
NOT RECOMMENDED since can cause conflicts for other users when updating repository
git commit --ammend  		

Unstaging a file

git reset HEAD file_name  (move from staging area to working area)  		

Get clean version of file

git checkout -- file_name   (get latest commited version from local repository and overrides local changes!)  		

Working with Branches

Helpful Links:
Working with branches

Creating a branch

git branch mynewbranch  (mynewbranch created in local repository only)

Showing current working branch

HEAD always points to the current working branch.
git branch

* Will show all branches, and the current working branch will have * in front of its name
* Default working branch is "master"

Changing current working branch

git checkout mynewbranch  (HEAD points to mynewbranch now!!)

* Not to confuse with CVS checkout, this only changes the current working branch

Changing to another branch while having uncomitted changes in current branch

If we have uncommited changes in one branch and change to another branch then GIT will attempt to merge changes.
If there are not conflicts thew new HEAD branch will have the merged changes

But if there are conflicts you need to pass the -m option so git tries to merge them explicitly

git checkout -m mysecondbranch  (will try to merge uncommited changes from previous branch into mysecondbranch and only then switch)


Creating branch and making current working branch

git checkoub -b mynewbranch2

* THis creates "mynewbranch2" in local repository only
* It also makes "mynewbranch2" the current working branch, so doing "git branch" will show
  new branch with "*" before name

Showing all branches

git branch  (-v for verbose to show last commit)

* The current working branch (HEAD) will have "*" in front of its name.

Nerging branches - No conflicts

git merge branch1  
*Will merge branch1 commits into the current working branch (pointed by HEAD)

Usually after merging from a temporary branch (branch1 in example above) we want
to delete it if no longer necessary

git branch -d branch1

Nerging branches - Conflicts

git merge branch1  

* if there are any conflicts git won't create create a new commit point. Instead users need to manually fix the conflicts, then "git add" the resolved files and commit

Running "git status" will show files that had conflicts, something like this: 

# On branch master
# Unmerged paths:
#   (use "git add/rm file..." as appropriate to mark resolution)
#       both modified:      myfilewithconflict
no changes added to commit (use "git add" and/or "git commit -a")	

- Running "git status" shows "unmerged" entries that need to be fixed
- Once conflicts have been fixed run "git add" to move changes to staging and them comimt.

Merging branch into another branch with uncommited changes!

Helpful links
Using git stash save/pop

If we have uncommited files in our working branch (HEAD) and "git merge" has to update any of these files then GIT won't allow the merge until we first commit our undo uncommited changes!.

Erorr would be like this:

error: Your local changes to the following files would be overwritten by merge
Please, commit your changes or stash them before you can merge.

To fix this we can do a stash.

git stash save "saving uncommited changes in stash before i do merge"
git merge branch2  (merge from branch2, this shoudl work now)
git stash pop  (reapply uncommited changes to the merged files)

Showing branches you already merged with head (current branch)

git branch --merged


*In example above branches without "*" (branch1) can be deleted safely since it has already been merged with head (master)

Deleting branches

git branch -d mybranch1

*Will not work if this branch is not an ancestor of current working branch (HEAD)
(because it hasn't been merged with current working branch (HEAD) yet!)


git branch -D mybranch1  (upper D!!!)


Pushing a branch to remote repository

git push origin mybranchiwanttopush
*Pushes "mybranchiwanttopush" to remote repository

git push origin mylocalbranch:newserverbranch1  
*Pushes "mylocalbranch" into remote repository, but the branch will be named "newserverbranch1" in remote repository

git push --all origin
*pushes all branches to remote repository

Getting branches from remote repository

git fetch origin
* Get all  branches (including new branches created by other users) from remote repository into local repository. Doesn't merge 

To start working on a remote branch (origin/branch3) we just fetched do:

git checkout -b localbranch3  origin/branch3   (creates a tracking branch)

* creates localbranch3 which is a tracking branch for remote origin/branch3, and now HEAD poits to localbranch3

To merge a remote branch we just fetched (origin/branch3) with current working branch (HEAD) do:

git merge origin/newbranch1

Deleting remote branches

To remote remote branch "mybranch1":
git push origin :mybranch1   

*Deletion is implied since there's nothing berfore the ":" symbol!!


Working with Remote Repositories

Helpful Links:
Working with remotes

Git is distributed, which means you clone from some remote repository into your local machine and then work "offline" making changes and local commits.

At some point we need to synchronize with the remote repository so other developers can see our changes and we can see their changes as well.

Managing remote repositories

git remote -v

* show all remotes repositories we are using
* This will usually show "origin" pointing to remote repository from which we cloned

git remote add secondremote git:// 

* Adds remote repository "someproject" and links it to "secondremote"
* If we do "git remote -v" we will see "origin" and then "secondremote"

git remote show origin
* Shows information about remote repository, branches, and tracking branches configuration for git pull/git push


Synchronizing with Remote Repository

git fetch -all

*fetches all changes from all remote repositories into local repository, doesn't merge

git fetch origin

*fetches all changes from origin remote repository into local repository, doesn't merge

git pull origin

*fetches all changes from and then tries to merge but only with working branch	

Common Git Flows

Helpful links
Merge flow vs rebase flow

We exectute "git push origin master" to synchronize with remote repository. If some other user has pushed other changes we will need to do a "git pull" first to get all the changes.

Merge Flow

- Change files and commit locally
- Before you synchronize do a "git pull" and fix any resulting merging conflicts
- After having resolved conflicts and commited locally (if necessary) do a "git push"

Rebase Flow

- Change files and commit locally
- Execute "git pull --rebase". This will put our local commits on top of the latest changes from remote repository
- Now execute git push (shouldn't cause any issues since we have already rebased locally)