Git Reference
Initial setup
git config --global user.name "John Doe"
git config --global user.email john.doe@example.com
git config --global color.ui auto
# git config --global color.status auto
# git config --global color.branch auto
git config --global push.default matching
Committing
Adding partial modifications to index:
git add --patch [foo/bar]
Committing with showing patches:
git commit -v
Committing with auto-adding all unstaged changes:
git commit -a
Committing in the past:
GIT_AUTHOR_DATE='Fri Jul 26 19:32:10 2013 +0200' GIT_COMMITTER_DATE='Fri Jul 26 19:32:10 2013 +0200' git commit
Undoing
Reset working directory and index to last committed state (last head):
git reset --hard
Reset a single file to the version in the index:
git checkout -- foo/bar.rb
Reset a single file to the last committed version:
git checkout HEAD foo/bar.rb
Remove a change from the index (undoing a previous git add
):
git rm --cached foo/bar.rb
Undo a commit (e.g. HEAD^, i.e. the one before HEAD) by committing an undoing changeset:
git revert HEAD^
Rewriting unpublished history
Amending the last commit (HEAD):
git commit --amend
Interactive editing of last 10 commits:
git rebase -i HEAD~10
Merging using rebase – move history to different branch:
git checkout featurex
git rebase master
vim foo/conflicted.rb
git add foo/conflicted.rb
git rebase --continue
Removing subtrees from the history, removing empty commits:
git filter-branch -f --tree-filter 'rm -rf foo/bar baz/bat' --prune-empty -- --all
git filter-branch -f --tree-filter 'find . -type f \( ! -name "foo*" \) -exec rm {} \;' --prune-empty -- --all
git filter-branch -f --tag-name-filter cat --prune-empty -- --all
Fixing things
Force current branch to point to specific commit:
git reset --hard <commit>
Force other branch to point to specific commit:
git branch -f <branch> <commit>
Force push branch with safety belt:
git push --force-with-lease
Patching
Generate file-based patch-set:
git format-patch <base-ref>
Apply file-based patch-set with 3-way merging:
cat *.patch | git am -3
Stashing
Stash away working directory changes and index state:
git stash
List stashes:
git stash list
Restore from stash:
git stash apply
Branching
List local/remote branches:
git branch
git branch -r
Show branches in relation to each other:
git show-branch
Switch to branch:
git checkout featurex
Create and switch to branch:
git checkout -b featurey
Delete branch after merging it to master or some other branch:
git branch -D featurey
Branching Workflow
Create new topic branch based on master or commit sha1:
git checkout -b topic/foo master|<commit>
Push to somewhere:
git push origin topic/foo
Alternatively, merge back into master:
git checkout master
git merge topic/foo
Alternatively, for private branches containing checkpoint commits, merge as a single changeset back into master:
git checkout master
git merge --squash topic/foo
git commit -v
Replace master with other branch based on commit sha1:
git branch -m master oldmaster
git checkout -b master <commit>
git push -f origin master
Merging
Merge featurex into master:
git checkout master
git merge featurex
vim foo/conflicted.rb
git add foo/conflicted.rb
git commit
Remote repositories
Clone existing remote repository:
git clone git://whatever/foo.git [foo-bar]
Clone only a single branch (master):
git clone git://whatever/foo.git --branch master --single-branch [foo-bar]
List remotes:
git remote [-v]
Add new remote:
git remote add otherdev http://example.com/~otherdev/foo.git
Set remote branch of local master to remote origin
, allowing git pull
to know what to fetch and merge without explicitly specifying:
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
Fetch from remote without merging:
git fetch otherdev
Fetch from remote and merge:
git pull otherdev
Merge changes from remote fork, complete workflow (using detached HEAD mode):
git remote add otherdev http://example.com/~otherdev/foo.git
git fetch otherdev
git checkout otherdev/master
# test fork before merge
git checkout master
git merge otherdev/master
# test merged result
git push origin master
Creating new repositories
Creating an empty group-shared SSH-based repository:
mkdir foo
chmod 2775 foo
cd foo
git init --bare --shared=group
Creating a HTTP repository
mkdir webroot/foo.git
cd webroot/foo.git
git init --bare
git --bare update-server-info
cp hooks/post-update.sample hooks/post-update
chmod a+x hooks/post-update
Importing from Subversion to GitHub
With standard Subversion layout (trunk
, branches
, tags
directories):
echo 'jdoe = John Doe <john.doe@example.com>' >> /tmp/foo.authors
svn2git https://svn.example.com/foo --authors /tmp/foo.authors
git remote add origin git@github.com:jdoe/foo.git
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
git push
Tagging
List tags:
git tag -l
Add tag and push tags to origin:
git tag -a foo-1.6.234
git push origin --tags
Remove tag and remove from origin:
git tag -d foo-1.6.234
git push :foo-1.6.234
Vendor branch pattern
Updating the vendor branch to a new snapshot:
git checkout vendor
rm -r *
# unpack new snapshot of foobar-1.2.3 into $PWD
git add .
git commit -m 'Import foobar-1.2.3'
git tag foobar-1.2.3
git push --tags
Updating modified master to new vendor snapshot:
git checkout master
git merge vendor
git push
Switching master to non-descendent branch
git checkout better_branch
git merge --strategy=ours master
git checkout master
git merge better_branch
Back to Knowledge Base.