http://git.or.cz/gitwiki/GitTips
Table of contents:
Contents
- General
- How to fix the most recent commit
- How to change commits deeper in history
- How to get only merges in gitk?
- What to do if you have realized that you are on wrong branch?
- How to compare two local repositories
- How to use git to track OpenDocument (OpenOffice, Koffice) files?
- How to remove all files which are missing from working directory?
- How to ignore files which are "Untracked" now?
- How to unpack all branches?
- Configuration
- StGIT
- Web
-
See also:
-
GitFaq (Frequently Asked Questions) page.
-
GitWorkflows which attempts to decribe actual, useful, real-world things that people do with git, step by step.
-
ExampleScripts - You can do a lot by writing a simple script.
-
Aliases are very powerful ways to avoid writing a script.
General
How to fix the most recent commit
Git allows you to easily fix up the most recent commit you've made on a branch with the --amend option:
For example the following command will allow you to alter the commit message at the top of current head:
$ git commit --amend
while
$ git commit -s --amend
will let you alter the commit message and will also automatically add a sign-off message for you.
How to change commits deeper in history
Since history in Git is immutable, fixing anything but the most recent commit (commit which is not branch head) requires that the history is rewritten from the changed commit and forward.
You can use StGIT for that, initialize branch if necessary, uncommitting up to the commit you want to change, pop to it if necessary, make a change then refresh patch (with -e option if you want to correct commit message), then push everything and stg commit.
Or you can use rebase to do that. Create new temporary branch, rewind it to the commit you want to change using git reset --hard, change that commit (it would be top of current head), then rebase branch on top of changed commit, using git rebase --onto <tmp branch> <commit after changed> <branch>.
Or you can use git rebase --interactive, which allows various modifications like patch re-ordering, collapsing, ...
git filter-branch can also be usefull. It has been ported from the obsoleted Cogito's .
How to get only merges in gitk?
With recent version of git you can use
gitk --full-history -- a//b
which will give you each commit that changes that nonexistent file (because there can't be file with double slash in name in git repository), and the full commit history for those (i.e. all the merges).
If you use "git log", you also need to add "--parents" while gitk will do it for you.
What to do if you have realized that you are on wrong branch?
If you have not commited your changes yet, it is enough to
git checkout -m <correct-branch>
(if you use core Git at leastv1.4.1-rc2).
(Cogito users will do 'cg switch <correct-branch>')
Let's assume that you wanted your changes to go on top of <current>, but by accident you committed your changes on top of <master> for example, and that the commit before your commits (the tip of <master> branch should be) is <before>. Let as assume that all changes are committed, and the working dir is clean.
First, create temporary branch (just in case), e.g.
git branch <tmpBranch>
Then you can reset <master> branch to correct commit
git reset <before>
Move temporary branch to correct branch, i.e. <current>, using
git rebase --onto <current> <master> <tmpBranch>
After resolving all conflict what is left is to fast-forward <current> to correct commit, and remove temporary branch
git checkout <current>
git reset --hard <tmpBranch>
git branch -d <tmpBranch>
I'm not sure if --hard option is really needed.
How to compare two local repositories
In Git you can use, being in one of repositories
GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects git-diff-tree $(GIT_DIR=../repo/.git git rev-parse --verify HEAD) HEAD
if you want to compare current repository with ../repo/ repository.
In the obsoleted Cogito you would nearly exactly the same
GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects cg-diff -r `GIT_DIR=../repo/.git cg-object-id -c HEAD`..HEAD
How to use git to track OpenDocument (OpenOffice, Koffice) files?
To view plaintext diff of OpenDocument files in Git, you can use the GIT_EXTERNAL_DIFF environment variable. First, install :
-
odt2txt: A simple (and stupid) converter from OpenDocument to plain text
-
git-oodiff: Wrapper script for odt2txt and diff.
You can now, for example, do
$ GIT_EXTERNAL_DIFF=git-oodiff git diff
git-oodiff presentation-expl.odp presentation-expl.odp
--- a/presentation-expl.odp
+++ b/presentation-expl.odp
@@ -3,7 +3,7 @@
First item
- First version of second item
+ Second version of second item
Last item
Now, let's automate this a bit more. Add this to your ~/.gitconfig (or .git/config):
[diff "oodiff"]
command=git-oodiff
This defines a "oodiff" diff driver, that you can now use in .gitattributes (at the root of your working tree, or in $GIT_DIR/info/attributes)
*.odp diff=oodiff
*.odt diff=oodiff
*.ods diff=oodiff
Now, git will use this oodiff driver for any file whose name ends with .odp, .odt, or .ods.
(this is also documented here).
How to remove all files which are missing from working directory?
git ls-files -z --deleted | git update-index -z --remove --stdin
How to ignore files which are "Untracked" now?
$ git ls-files -o --exclude-standard >> .gitignore
$ $EDITOR .gitignore
(note : --exclude-standard is not yet in a released version of git as of november 2007, you'll have to use --exclude-from=.gitignore --exclude-from=.git/info/exclude ... if you don't have it).
How to unpack all branches?
For example if you have realized that you repository must be accessible by older dumb clients, or some script you use doesn't understand packed refs.
git for-each-ref refs/heads | \( x=`git rev-parse --git-dir`; \
while read id junk ref; do \
echo $id > "$x/$ref"; \
done )
Configuration
How to upgrade repository config to use post-1.5.0 features?Updating a pre-1.5.0 Git repository to be like a 1.5.0 (and later) style repository basically means rewriting the remotes (.git/info/remotes/) into .git/config, setting up wildcard tracking branches under refs/remotes and deleting the old tracking branches from the refs/heads namespace.