#Git Basics
###Get the Repository
git clone ssh://source.example.com/var/GITREP/myproject
cd myproject
This copies the myproject repo at the given location to the myproject sub-directory.
To download updates from your original repository, and merge changes into your current branch:
git pull
To update the repo, and merge the changes yourself on your master branch
git fetch
get merge origin # This is also called a "fast forward" merge for newer changes
To send updates to branches on the original repo:
git push
##Switching Branches
What branches exist?
git branch # Lists local branches
git branch -a # Lists all (local + remote) branches
git branch -v # Shows last commit message
To create the remote staging branch as your staging branch, use the checkout -b option:
git checkout -b staging origin/staging
To switch back to the master branch
git checkout master
To create an new branch, for issues, features, or experimentation:
git checkout -b 1287-purge-feature
You can do this before or after you start working, your uncommitted changed will be kept with the new branch. Your current branch is the starting point for the new branch, usually the branch in which you will merge the changes back (staging).
###Sharing the Branch If you want to send your branch up to the original repository to share it with others:
git push origin 1234-feature-branch
In order to pull changes to that branch back into your repository, you must add this to your .git/config file on the root of the repo:
[branch "1234-feature-branch"]
remote = origin
merge = refs/heads/1234-feature-branch
To remove the remote branch:
git branch -d -r origin/1234-feature-branch
###Finishing the Branch When you are done with the branch, merge it back into the original branch, and delete it
git checkout staging
git merge --no-ff 1234-feature-branch
git branch -d 1234-feature-branch
The --no-ff (no fast-forward) merge option keeps the group of commits to the source branch in a separate path, and creates a "merge" point. Fast forward merges will not show the branching history.
The -d option deletes the branch if merged. If you do not want to merge it, blow it away with the -D option
git branch -D 1234-experimental-branch
###Branch Naming Conventions
Long-lived branches are common names master: Production branch. (CVS "trunk") staging: Beta release branch, recent features and fixes for next release
Feature and issue branches incorporate the Mantis ticket number and description
ticket-issue_feature-title-of-feature-or-issue 1234-feature-title 1234-hotfix-title 1234-issue-title
##Making Changes
Switch to the branch you wish to commit the change. Edit away.
What files are changed?
git status
this shows known, modified files in the first section, then (new) untracked files, and deleted files. Deleted files are removed from the repository on commit.
What are my changes I am about to commit?
git diff [--color] [--word-diff]
To restore a file to its original state, or copy from another branch:
git checkout filename # Discard changes to it
git checkout branch filename # Cherry-pick this file from another branch/tag/commit
To rollback all changes to the previous commit:
git reset --hard
or, if you want to save them for later and want to do something else now
git stash # Stores them in the "stash" stack: `git stash apply` will restore them
Rename, move and delete files:
git mv source destination # Rename or new location
git rm files
rm files # git detects deleted files and will delete them too
###Staging your Commit
Commits to all known files can be made with:
git commit -a
git commit -a -m'commit message'
If you want to commit only certain changed files:
git commit file file ...
If you want to also add changed files, or new files to the commit (and repository), use 'git add'. They are then staged and committed with the next commit action.
git add file file ...
git commit
You can examine and accept/decline each chunk of change in each file. This is useful to make sure any unintended test code is not committed, and to review your work.
git commit -p
###Commit Message Conventions
Refer to a Mantis ticket number and type on the commit message, or start the commit message with the following action verbs: fixed, added, hotfix (I know), removed, updated, or similar.
fixes #1234 feature-name issue-description
adds #1234 feature-name description
hotfix #1234 issue description
Try to include the feature-name as the process, program or webpage name.
The commit will print out the branch name, commit hash, and commit message. Copy and paste this into the Mantis ticket when resolving the issue, allowing the change to be identified and inspected later if necessary.
Alternate git commit message conventions to consider: [http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html](A note about git commit messages)
##Workflow
Workflow overview:
- Fixes and features are developed in separate branches (unless the change is trivial)
- Fix and Feature branches are merged into the "staging" branch.
- The "beta tester" accounts on the staging branches are updated
- When all is acceptable, staging is merged into master, and tagged.
- All other accounts are updated to HEAD on master, usually at the tag point.
- The there is much celebration!
Update your repository and merge changes into your current branch, switch to the starting branch (staging) and create your work branch:
git pull
git checkout staging
git checkout -b 1234-feature-name
Sometimes, you want to rebase your work on the current state of the starting branch. Rebasing removes your commits, fast-forwards the initial branch point to the current HEAD (last commit) of the starting branch. It them "replays" your commits onto the new starting point.
git pull
git rebase
After finishing your changes, test and commit, then prepare to merge back into the starting branch
git commit ...
git checkout staging
git pull # Updates repository and fast-forwards branch
git merge --no-ff 1234-feature-name
git push # Sends merged branch upstream
git branch -d 1234-feature-name
###Interrupted Development By keeping your work separate, you can switch back to the staging branch for a hotfix at anytime
git stash # Stores uncommitted changes for later
git checkout staging
git pull
Make and test your changes...
git commit -a -m'hotfix #1111 ...'
git push
git checkout 1234-feature-name
git stash apply # Restores uncommitted changes
###Large-scale Workflow
My workflow understand came from this great post: http://nvie.com/posts/a-successful-git-branching-model/
The https://github.com/nvie/gitflow extensions help implement and enforce this style of workflow.
##Inspecting the Repository
Use the git log command to display the commit chain of a branch. On the command line it will be
git log [options] [since..until] [branch] [filenames]
git log
git log files
git log staging bl-manage
git log --pretty=oneline --abrev-commit --graph --color
You can also specify the starting and ending points to display. "since" and "until" here can be commit hashes, tags, HEAD, or not specified to indicate the beginning of time or current commit (HEAD)
since.. # From commit/tag to HEAD
since..until # Between commits/tags
..until # Up until the point
commithash # This commit only
Use the whatchanged command to show the changed files for the commits
git whatchanged [options] [since..until] [branch] [filenames]
git whatchanged --pretty=oneline --abbrev-commit
c260028 Fixed redirect after login (php reg globals)
:100755 100755 04816ea... 51a264a... M www/mlm/controller/home.php
:100755 100755 0b36ac1... 0869628... M www/mlm/main.php
###Inspecting with git diff
The git diff command can show differences between two commits for all files or given files.
git diff [options] [since..until] [branch] [filenames]
git diff # Uncommitted changes
git diff [since..until]
git diff --word-diff=color # Readable diffs with red (removed) and green (added)
###Inspecting a commit
The 'git show' command prints information from the log and diff commands together
git show [options] [since..until] [branch] [filenames]
###The tig command
The https://git.wiki.kernel.org/index.php/Tig package is a ncurses-based git browser. Very awesome.
tig
tig [options] [since..until] [branch] [filenames]
Use it to review commits, and show the revisions.
###GUI Tools
Git comes with a Tcl/Tk browser:
git gui
There are several options for each platform:
- gitweb: A web application
- getalist [http://www.gitalist.com/]: web application
- gitorious [http://gitorious.org/]: open-sourced web hosting platform
- gitx [http://gitx.frim.nl/]: Mac OS X client
##Releasing
Release are merges of changes in the staging branch into the master branch.
git checkout master
git merge --no-ff staging
git tag -a v1.2.3 # Opens commit message in editor for details
git push --tags
To update a repo, simply pull, or checkout to a tag
git fetch # Downloads new tags, branches and commits
git pull # Does a fetch, and merges into current branch
git checkout v1.2.3 # Sets the repo to the given tag or commit hash
Due to the distributed topology of git, once tags are pushed, they should be considered permanent.
###See new changes before updating
Running a "git pull" both fetches updates from the origin repository, and merges them into your working tree. To look at what will be coming in, you can separate the fetch and merge commands, checking the log and diffs in between.
git fetch # Download updates for origin repo
git log ..origin/master # Show commits that will be applied ((here)..there)
git log ..origin/master -p # The -p flag shows code diff between commits
git merge origin/master # Merge in the changes (or do: git pull)
###Hotfixes
Hotfixes are added directly to the master branch, as they need to be separate from the other changed already present in the staging branch. The change should be applied to both branches, using the cherry-pick command.
git commit -a -m'hotfix #1234: can not delete records'
[staging 8cf5623] hotfix #1234: can not delete records
git pull
git checkout master
git cherry-pick 8cf5623
git push
This will copy the commit to the master branch. It will have different hash on the new branch because it is applied to a different point in the repository.
Take a project directory and make it a git repo.
cd project
git init # Creates .git subdirectory to hold repo
vim .gitingnore # Create file of filename patterns to ignore
*.swp # Like vim swap files
*.log # and log files
git add . # Adds files in directory to staged commit
git commit -m'Initial commit to git' # Commit project
Now let's share it on our network
ssh source.example.com
cd /var/GITREP
git clone --bare originalhost:path/to/project project.git
touch project.git/git-daemon-export-ok # if using git-daemon instead of ssh
chmod -R g+w project.git # Allow everyone to write to the repo
Point your project repo to use this new one as the origin
cd project
git config remote.origin.url ssh://source.example.com/path/to/project.git
##Git Resources
Git command offer a --help option to show the man page
git pull --help
man git-pull
- [http://progit.org/book/](Pro Git Book): Free, online book
- [http://www.kernel.org/pub/software/scm/git/docs/user-manual.html](Git User's Manual): From the git team
- [http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide](Git Guide): on stackoverflow
- [http://www-cs-students.stanford.edu/~blynn/gitmagic/](Git Magic): A nice introduction