- Maintaining a Shared Bare Repository
- Changing the Current Branch of a Bare Repository
- Tagging
- Remote Repositories
- Repository Management
- Moving a Local Git Repository
- Cleaning Working Branch
- Removing Dangling Commits
- PS1 Prompt Showing Branch
- Git Diff
- Git Log
- Troubleshooting
- Work Flow
- Reference Documentation
- References
- Resources
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
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:
- https://unix.stackexchange.com/questions/351725/why-eval-the-output-of-ssh-agent
- https://stackoverflow.com/questions/51288089/alternatives-to-eval-ssh-agent-and-exec-ssh-agent-bash
- https://wiki.debian.org/SSH#ssh-agent_and_ssh-add
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
- https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery
- http://www.tekkie.ro/news/howto-remove-all-dangling-commits-from-your-git-repository/
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.
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
- Git Quick Reference
- git(1]
- Git User's Manual
- gittutorial(7)
- gittutorial-2(7)
- gitcore-tutorial(7)
- Everyday Git
- git-svn(1)
References
- Git Home Page
- Git Community Book
- Git Wiki
- Git on Windows
- ProGit Book
- http://blog.emmanuelbernard.com/2010/05/git-how-my-life-has-improved-since-last-month-when-i-used-svn/
Resources
-- Frank Dean - 22 Oct 2009
Related Topics: EGitTips, EmacsTips, EmacsCCMode, GitSvn