http://git.or.cz/gitwiki/GitTips

Table of contents:

Contents

  1. General
    1. How to fix the most recent commit
    2. How to change commits deeper in history
    3. How to get only merges in gitk?
    4. What to do if you have realized that you are on wrong branch?
    5. How to compare two local repositories
    6. How to use git to track OpenDocument (OpenOffice, Koffice) files?
    7. How to remove all files which are missing from working directory?
    8. How to ignore files which are "Untracked" now?
    9. How to unpack all branches?
  2. Configuration
    1. How to upgrade repository config to use post-1.5.0 features?
  3. StGIT
    1. How to rebase StGIT stack?
  4. Web
    1. How to generate RSS feed off-line?
    2. How to push/pull via ssh to host behind gateway?
    3. How to pass ssh options in git?
  5. Mail
    1. Using msmtp to send your patches

  • 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 :

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.