Git Tips

Maintaining a Shared Bare Repository

If the repository is shared by multiple users using git-push to update it, you will need to do something to ensure all users have write access to the repository's files and directories. Create a group and add all users to that group. Set the group suid bit on all directories in the repository so that any new files and directories will be created with the same group as the parent directory. Set the core.sharedRepository config option to group, so that git-push maintains files as group writable.

    $ cd /myrepository
    $ git-config --add core.sharedRepository group
    $ chgrp -R our_group .
    $ chmod -R g+w .
    $ find . -type d -exec chmod g+ws '{}' ';'

Alternatively, create the initial repository as a bare shared repository and optionally import an existing repository. Git will automatically add group write permissions to a repository if you use the --shared option. E.g.

    $ cd /var/local/git
    $ git init --bare --shared myrepository.git
    $ chgrp -R git myrepository.git

Then from an existing repository:

    $ git push --set-upstream ssh://localhost/var/local/git/myrepository.git master


Creating a lightweight tag:

    $ git tag <TAG> [<sha1>]

Creating an annotated tag:

    $ git tag -a <TAG> [<sha1>]

To push a single tag to a remote repository, include the tag name:

    $ git push origin <TAG>

To push all tags to a remote repository, include the '--tags' argument:

    $ git push origin --tags

Fetch tags

    $ git pull --tags origin master

Remote Repositories

Add a Remote Repository

    $ git remote add test git://

add only track this new branch rather than all remote branches:

    $ git remote add -t master test git://

List remote repositories:

    $ git remote
    $ git remote show origin

Renaming Remote Repository

    $ git remote rename old_alias new_alias
    $ git remote

Removing Remote Repository

    $ git remote rm alias

Create Remote Branch

    $ git branch new_branch
    $ git push -u origin new_branch

Deleting Remote Branch

    $ git push remote_name :branch_to_delete

To remove a local reference to a remote branch that perhaps no longer exists:

    $ git branch -r -d origin/master


    $ git remote prune <remote>

Tracking Remote Branch

    $ git branch --track local_branch_name remote_name/remote_branch_name

Add Remote Tracking for Push

    $ git branch --set-upstream master origin/master

Setting Tracked List of Remote Branches

    $ git remote set-branches origin master
    $ git remote set-branches origin master other_branch another_branch

append to existing list instead of replacing list:

    $ git remote set-branches --add origin master

Repository Management

Single Shared User

Create a single 'git' user on the server. Have each user who requires write access to supply an SSH public key. Add those public keys to the ~/.ssh/authorized_keys file of the 'git' user. Now each user can use the 'git' user to access the repository via SSH.

See the ProGit book (Chapter 4.2 "Git on the Server—Getting Git on a Server") for more details.

Moving a Local Git Repository

You can copy or move a local Git repository with ordinary Unix commands like 'mv' and 'cp -a'. Afterwards, you need to update the indexes with:

   $ git update-index --refresh

See Copying Repositories in gitcore-tutorial(7).

Cleaning Working Branch

The following command will list un-tracked files:

    $ git-ls-files -o

You can use git-clean to remove untracked files and directories. The following command will remove all untracked files and directories including files which are ignored (remove the --dry-run flag to actually delete the files and directories):

    $ git-clean --dry-run -d -x

Removing Dangling Commits

If you really are sure you don't want to wait for the dangling commits to expire, you can clean them up now with the following:

    $ git reflog expire --expire=now --all
    $ git gc --prune=now

PS1 Prompt Showing Branch

Execute the following in your shell:

    $ export PS1='$(__git_ps1 " (%s) ")'

or include the host and working directory:

    $ export PS1='\u@\h:\w\$ $(__git_ps1 "(%s) ")'

On a Debian system, modify the existing PS1 definitions in .bashrc:

    # set a fancy prompt (non-color, unless we know we "want" color)
    case "$TERM" in
        PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ $(__git_ps1 "(%s) ")'
        PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ $(__git_ps1 "(%s) ")'

__git_ps1 is a bash function. In Debian 7 (Wheezy) it is located in the /etc/bash_completion.d/git script which belongs to the git package. You need to source the bash completion script (which in turn sources all scripts under /etc/bash_completion.d/) for the function to be found. This may need enabling in your .bashrc as follows:

    # enable programmable completion features (you don't need to enable
    # this, if it's already enabled in /etc/bash.bashrc and /etc/profiles
    # sources /etc/bash.bashrc).
    if [ -f /etc/bash_completion ]; then
        . /etc/bash_completion

For other distributions, the bash completion script is in the Git source under ./contrib/completion/

You may also like to set the variable GIT_PS1_SHOWDIRTYSTATE=1 to show unstaged (*) and staged (+) changes. See the comments in the script for more information, including other useful variables that can be set.

See also:

Git Diff

To see changes between the current working directory and what has been staged or committed:

    $ git diff

To see changes between what has been committed and staged use:

    $ git diff --cached

Git Log

Nice decorated output showing all branches:

    $ git log --decorate=full --oneline --graph --all

Patches for specified path:

    $ git log -p <path>



If you get an error message along the lines of fatal: Not a git repository it may have been caused by copying the files to a USB stick or similar using a FAT32 file system. HEAD then appears as head.

You'll need to copy it back to another partition type and rename head.

It's also a good idea to set the following properties:

    $ git config --add core.filemode false
    $ git config --add core.symlinks false
    $ git config --add core.ignorecase true

error:gpg failed to sign the data

Run git with tracing enabled to debug:

    $ GIT_TRACE=1 git tag -a -s -m 'Tagging release' v0.0.1

It may be that you're trying to sign the commit with a different key id than the default e-mail address for the repository. Fix by using the '-u' option to specify the key ID.


Reference Documentation


-- Frank Dean - 22 Oct 2009

Related Topics: EGitTips, EmacsTips, EmacsCCMode, GitSvn