git
One-time setup
Further info on the web
Very complete cheatsheet http://cheat.errtheblog.com/s/git
Popular git tools
- command line!
- GitX: http://gitx.frim.nl/
- Gitnub: http://github.com/Caged/gitnub/downloads
Setup config and aliases (some are optional)
required: tell Git who you are going to commit as.
If you skip the --global, these settings will only be for the current folder
git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com
Example for jmg who has an existing setup for github:
git config user.name "Jean-Michel Garnier"
git config user.email jmg@xxx
Check out your configuration with:
cat .git/config
Global .gitignore file
git config --global core.excludesfile ~/.gitignore
Next add the exclude line for .DS_Store to the .gitignore file either with your favourite editor or simply with this command which will create it if it doesn’t already exist as well.
echo .DS_Store >> ~/.gitignore
optional: colorized command-line output (useful for diff, status)
git config --global color.diff auto git config --global color.status auto git config --global color.branch auto
optional: add the following aliases to .git/config in the betterplace directory:
they let you write 'git ci' instead of 'git commit', etc.
[alias] ci = commit st = status co = checkout
optional: Showing your Git branch in your shell prompt
# http://aaroncrane.co.uk/2009/03/git_branch_prompt/ function find_git_branch { local dir=. head until [ "$dir" -ef / ]; do if [ -f "$dir/.git/HEAD" ]; then head=$(< "$dir/.git/HEAD") if \ refs/heads/* ; then git_branch=" ${head#*/*/}" elif $head != '' ; then git_branch=' (detached)' else git_branch=' (unknown)' fi return fi dir="../$dir" done git_branch='' } PROMPT_COMMAND="find_git_branch; $PROMPT_COMMAND" green=$'\e[1;32m' magenta=$'\e[1;35m' normal_colours=$'\e[m' PS1="\[$green\]\u@\h:\w\[$magenta\]\$git_branch\[$green\]\\$\[$normal_colours\] "
based on http://aaroncrane.co.uk/2009/03/git_branch_prompt/
optional: git commands auto completion
http://denis.tumblr.com/post/71390665/adding-bash-completion-for-git-on-mac-os-x-leopard
Change last commit message
git commit --amend -m "your new message"
developing a feature in a feature branch
The general idea is to make a branch for every new feature you develop. That has advantages like:
you can commit to your local repo as often as you like.
when you're done, you can do one "sqashed" commit. this applies all your changes in one commit, easy to review and undo.
when you have to do another task (bugfix), you can easily create a new branch off master and fix the bug, leaving your feature work uninfluenced.
It's described here: http://blog.hasmanythrough.com/2008/12/18/agile-git-and-the-story-branch-pattern
Revert last commit
git reset --hard HEAD^
It removes the commit from your repository and from your working tree. It’s the equivalent of a delete button on your repository with no “undo.”
Work with remote branch
From http://www.gitready.com/beginner/2009/02/02/push-and-delete-branches.html : so let’s say you have checked out a new branch, committed some awesome changes, but now you need to share this branch though with another developer. You can push the branch up to a remote very simply:
git push origin newfeature
Other developers in the team won't know about new remote branch until they run:
git fetch
remote: Generating pack...
remote: 100% (77/77) done
Unpacking objects: 100% (77/77), done.
[new branch] removing_mozilla_days -> origin/removing_mozilla_days
git checkout -t origin/removing_mozilla_days
OU
git branch --track removing_mozilla_days origin/removing_mozilla_days
Branch removing_mozilla_days set up to track remote branch removing_mozilla_days from origin.
to see which (remote) branches exist:
git branch -av
After that, to push to this remote branch:
git push origin removing_mozilla_days
squashing commits with rebase
Working on removing features (mozilla, xmas, etc), we use a remote branch so 2 developers can pair:
A -- B -- C master / D -- E -- F -- G removing_mozilla (lots of small commits)
In order to be able to reproduce what exactly is contained in the feature 'mozilla', we want to merge it into master with one commit. (squash-merge)
We want:
A -- B -- C -- H (squash D, E, F and G) master / \ D -- E -- F -- G removing_mozilla
Make sure your branch has the lastest changes from master
Rebase against the upstream frequently to prevent your branch from diverging significantly:
git fetch origin master git rebase origin/master
NB: This is often done by checking master out and pulling, but this method requires extra steps:
git checkout master git pull git checkout 3275-add-commenting git rebase master
rebase with the interactive option to squash several (or all) of your commits into a single commit
git rebase -i master
Rebase 60709da..30e0ccb onto 60709da
Commands:
p, pick = use commit
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit #
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
Basically this tells Git to combine all four commits into the the first commit in the list.
Combine commit messages
This is a combination of 4 commits.
The first commit's message is:
Adding license
This is the 2nd commit message:
Moving license into its own file
Since we’re combining so many commits, Git allows you to modify the new commit’s message based on the rest of the commits involved in the process. Edit the message as you see fit, then save and quit. Once that’s done, your commits have been successfully squashed!
Merge with master branch
git checkout master git merge removing_mozilla rake tests:run_before_commit git push
Do not forget to clean up and remove the remote branch with
git push origin :removing_mozilla_days
More info, see http://www.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
git rerere
http://pivotallabs.com/users/khicks/blog/articles/2119-git-config-rerere-enabled-true
Revert a merge
We need to be able to reproduce what exactly is contained in the xmas calendar.
So please make sure to do this change in a branch, and merge it into master with one commit. (squash-merge).
Unfortunately, I have forgotten a few files and then Fabian and Jan pushed. This is the state of my git tree is:
A (JM) -- B merge result (JM 962cf1) -- C (fdi) -- D (fdi) -- E(js) master
First, I want to create a remote branch to not to loose my work:
A(JM)-- B merge result (JM) -- C (fdi) -- D (fdi) -- E(js) master / B remove_xmas branch
git branch remove_xmas_calendar 962cf1
And then I want to revert the merge so master is clean:
git revert -n 962cf1cf0e -m 1 git commit . -m "reverted merge of remove_xmas_calendar as I have forgotten the js and want to ask Fabian to review my changes. I have do$ git commit . -m "reverted merge of remove_xmas_calendar as I have forgotten the js and want to ask Fabian to review my changes." git push
Have a look to http://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.txt for more explanations
deleting old remote branches
1) remove tracking of remote branches that don't exist anymore
git remote prune origin
2) list all remote branches
git br -r
3) delete remote branches you don't need anymore
git push origin :search_indexer_refactorings
cherry-pick
hen, for each commit I want to cherry pick, I simply do:
$ git cherry-pick -x sha1_of_the_commit
Tricks
Gitx to display all commits for a given folder
gitx master -- features/
github open source projects guide
USE github-gem ???!!
$ git clone git@github.com:21croissants/caprese.git
Once the clone is complete your repo will have a remote named “origin” that points to your fork on github. Don’t let the name confuse you, this does not point to the original repo you forked from. To help you keep track of that repo we will add another remote named “upstream”:
$ cd github-services $ git remote add upstream git@github.com:timcharper/caprese.git $ git fetch upstream
Note that we used the public clone URL for upstream, so we can’t push changes directly to it. We probably don’t have permission to do that anyway, which is why we’re creating a fork in the first place. If the upstream repo is private, you must use its private URL.
Some time has passed, the upstream repo has changed and you want to update your fork before you submit a new patch. There are two ways to do this:
$ git fetch upstream $ git merge upstream/master
$ git pull upstream master
git pull is a more direct way, but the merge it performs can be confusing if the user doesn’t expect it and a merge conflict results. git fetch will also grab all branches, where git pull grabs only the one specified.
If you have local commits that are not in the upstream branch, a normal merge will occur. If your local commits are in the upstream branch, a fast-forward merge will be done, moving your local branch to the same commit as upstream/master. If both repos have edits to the same location in the same file, you may run into a merge conflict. Conflicts must be resolved by hand and a commit made to complete the merge.
Now that your local branch has been updated, commit your changes, push, and send a pull request.
You may wish to do the fetch and merge manually, instead of letting git-pull do it for you. This can help avoid headaches caused by mysterious merge conflicts.