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

Changing the Current Branch of a Bare Repository

$ git symbolic-ref HEAD refs/heads/my_branch

See https://stackoverflow.com/questions/3301956/git-correct-way-to-change-active-branch-in-a-bare-repository

Tagging

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://www.fdsd.co.uk/viki

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

    $ git remote add -t master test git://www.fdsd.co.uk/viki

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

http://stackoverflow.com/questions/1519006/git-how-to-create-remote-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

or

    $ 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

Caching SSH Password

$ eval "$(ssh-agent)"
$ ssh-add

See:

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
    xterm-color)
        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) ")'
        ;;
    esac

__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
    fi

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

You may also like to set the variable GIT_PS1_SHOWDIRTYSTATE=1 to show unstaged (*) and staged (+) changes. See the comments in the git-prompt.sh 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

Show filenames:

    $ git log --name-only

Patches for specified path:

    $ git log -p <path>
    $ git log --patch <path>

Commits for a specific path:

    $ git log -c -- <path>
    $ git log --diff-merges=combined -- <path>

Patches for a specific line number range in a specific file:

    $ git log -L 45,50:<filename>

Search reflog messages for regular expression matches:

    $ git log --walk-reflogs --grep-reflog=<pattern> -- <path>

Troubleshooting

FAT32

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.

See https://stackoverflow.com/questions/39494631/gpg-failed-to-sign-the-data-fatal-failed-to-write-commit-object-git-2-10-0

fatal: transport 'file' not allowed

This may occur when updating a local submodule and is due to a restriction implemented in git to mitigate CVE-2022-39253.

The mitigation can be overridden by temporarily changing the default permission of protocol.file.allow=user to allow when running the appropriate command. E.g.

$ git -c protocol.file.allow=always submodule update

In the perhaps unusual event that the environment is always safe, you can override it globally for the current user with:

$ git config --global protocol.file.allow always

The default is:

$ git config --global protocol.file.allow user

Work Flow

Reference Documentation

References

Resources


-- Frank Dean - 22 Oct 2009

Related Topics: EGitTips, EmacsTips, EmacsCCMode, GitSvn