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 mistakeCommon Terms
Cloning Remote repository
Things to avoid
Working with branches
Working with Remote Repositories
Common Git flows
Git Online References
Git book online (MUST READ)
Git for windows
Git @ Github:
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
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.
Setting up user/email to identify with remote git repository (i.e: github.com)git config --global user.name "userremoterepository" git config --global user.email email@example.com
Cloning remote repository
Getting remote repository files into local machine to start changing and commiting files locally. This Will create folder "mylocalproject"git clone https://github.com/someUserXXX/remoteRepository.git 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!!!
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 statusViewing differencesgit 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 filesgit 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 filesgit 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_nameTo CommitCommitting 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 committinggit 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 historygit 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 commitAllows 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 repositorygit commit --ammendUnstaging a filegit reset HEAD file_name (move from staging area to working area)Get clean version of filegit checkout -- file_name (get latest commited version from local repository and overrides local changes!)
Working with Branches
Working with branchesCreating a branchgit branch mynewbranch (mynewbranch created in local repository only)Showing current working branchHEAD 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 branchgit 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 branchgit 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 nameShowing all branchesgit branch (-v for verbose to show last commit) * The current working branch (HEAD) will have "*" in front of its name.Nerging branches - No conflictsgit 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 branch1Nerging branches - Conflictsgit 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!
Using git stash save/popIf 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 filenameXXX 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 output: branch1 *master *In example above branches without "*" (branch1) can be deleted safely since it has already been merged with head (master)Deleting branchesgit 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!) TO FORCE DELETE AND LOSE WORK!!!: git branch -D mybranch1 (upper D!!!)Pushing a branch to remote repositorygit 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 repositoryGetting branches from remote repositorygit 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/newbranch1Deleting remote branchesTo remote remote branch "mybranch1": git push origin :mybranch1 *Deletion is implied since there's nothing berfore the ":" symbol!!
Working with Remote Repositories
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 repositoriesgit 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://github.com/someuser/someproject.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 pushSynchronizing with Remote Repositorygit 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
Merge flow vs rebase flow
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)