User documentation: UsingGit
Repositories are in
/srv/git/project_name.git for now.
git+ssh is supported in Savane's
sv_membersh (delegates to git-shell).
The git:// lightweight protocol is also available.
Creating an additional repository
NOTE: See below for an automated scripted method to add sub-repositories.
If a project wishes to have several repositories grouped together under the same project name.
make a directory to place additional repositories:
mkdir /srv/git/lwip chgrp lwip /srv/git/lwip chmod g+s /srv/git/lwip
create a new shared bare repository (supposedly named lwip-contrib hereafter) in that directory:
git init --shared=all --bare /srv/git/lwip/lwip-contrib.git
write following to: /srv/git/lwip/lwip-contrib.git/hooks/post-update:
#!/bin/sh exec git update-server-info
make it executable:
chmod a+x /srv/git/lwip/lwip-contrib.git/hooks/post-update
forbid access to hooks:
chown -R root:root /srv/git/lwip/lwip-contrib.git/hooks chattr +i /srv/git/lwip/lwip-contrib.git/hooks
Update the description file:
echo "lwIP Contrib - Contributed code for Lightweight TCP/IP stack" > /srv/git/lwip/lwip-contrib.git/description
Deprecated cvs server: If upon specific request add 'git-cvsserver' support. This is no longer desirable for a default. Only kept here now for documentation of the legacy environment.
cd /srv/git/lwip/lwip-contrib.git git config gitcvs.pserver.enabled 1 git config gitcvs.ext.enabled 0 git config gitcvs.dbname "%G/gitcvs-db/sqlite" mkdir /srv/git/lwip/lwip-contrib.git/gitcvs-db -m 755 chown nobody /srv/git/lwip/lwip-contrib.git/gitcvs-db
Creating an additional repository - automation script
A script to automate the above steps is available in
vcs:~root/bin/gnu-sv-add-git-sub-repository.sh and also in
The script takes two parameters: the existing project name (e.g.
and the new sub-repository name to create (e.g.
Example, the following request: https://savannah.gnu.org/support/?108678 has been completed using:
ssh vcs ~/bin/gnu-sv-add-git-sub-repository.sh guix artwork
The script also prints the URLs for easy copy&pasting.
Enabling Commit Notifications
Set git configurations:
cd /srv/git/auctex.git/ git config multimailhook.mailinglist firstname.lastname@example.org
The result will be this in the git config file.
[multimailhook] mailinglist = email@example.com
This can be done using the git-config utility to edit that file.
git config multimailhook.mailinglist firstname.lastname@example.org git config multimailhook.emailprefix "[emacs-elpa-diffs]"
Unprotect hooks/ directory:
chattr -i hooks/
Link git_multimail.py to the local hooks directory:
ln -s /usr/src/git-multimail/git-multimail/git_multimail.py hooks/
Copy another projects template into the hooks directory and then edit it to configure it for the new project. This can be done on the fly using sed. This sets the Mail-Followup-To: header address to the devel discussion mailing list which is separate from the commit diff mailing list. Set it to where follow-up discussion is desired.
sed email@example.comfirstname.lastname@example.org/ /srv/git/emacs/elpa.git/hooks/post-receive > hooks/post-receive chmod a+x hooks/post-receive
Protect hooks/ directory again:
chattr +i hooks/
Disabling Reference Change Notifications
Sometimes maintainers do not like the receiving reference change commits in addition to changeset commits. Optionally this may be disabled. See the groff.git config for an example. In summary change the config file from this:
mailinglist = email@example.com
mailinglist = nobody commitList = firstname.lastname@example.org
Multiple post-receive Hooks
If multiple post-receive hooks are desired then special handling is needed since oldrev newrev refname are passed in on stdin. This will need to be passed in to all hook scripts if multiple ones are desired. See auctex.git/hooks/post-receive for an example. Here is a snippet.
while read oldrev newrev refname; do echo $oldrev $newrev $refname | /usr/local/bin/git-post-receive-hook echo $oldrev $newrev $refname | hooks/post-receive-mail-local done
Renaming a branch
This needs some rationale and justification because during normal operation we never want to rewind a branch. It causes problems for anyone who has pulled from the branch. Normally branches only move forward. But sometimes renaming a branch is the best solution to a problem.
Sometimes a user has munged a commit, has pushed the desired branch onto a temporary branch (call it new-master), and wishes to have the new temporary branch become the master branch as the correction.
Verify the current and future state of the repository:
cd /srv/git/exampleproject.git git branch -l git log git log new-master
Move the current branch to master-broken as a backup save:
git branch -m master master-broken
Move the new branch into place as master:
git branch -m new-master master
At this time the "current" branch will be shown to be master-broken:
git branch -l master * master-broken
(There is likely a less heavy-handed command to do this. This is the only way I know how at this moment. I would welcome an improvement here. Normally with a working directory 'git checkout' would be used to set this.) The current branch reflog was moved when the branch was moved and is now set to master-broken and needs to be updated to point to master. Since this is a raw repository update the HEAD file directly:
echo ref: refs/heads/master > HEAD
Verify the current status us as desired:
git branch -l * master master-broken
Verify that the change is correct. Better to leave the broken branch around for a while than to remove it too soon and lose something that should not have been lost. Then clean up and discard the broken branch:
git branch -D master-broken
- We need to decide how to allow multiple repositories, or stick with a single one. repo.or.cz seems to use
project_name/forks.git, which sounds cool.
- repo.or.cz also implements the concept of "forks": http://repo.or.cz/m/regproj.cgi?name=git/ which can be used to save bandwidth.
- Implement repository instanciation in Savane - more generally git support. [Basic Git support implemented]
- Repository optimization (packing, pruning) needs to be done at some
points, probably via hooks. git:// doesn't allow this kind of
operations. At kernel.org, people usually have shell access and a
private/non-shared repository, so they don't have this kind of
issues. The doc says: "packing every 4-5MB of loose objects
accumulation may be a good rule of thumb."
Apparently it's done by git when there's a lot of objects committed
at once, but it may be necessary to do it manually (
git gc --auto) from time to time.
- Hooks management, as usual.
- xyz.git/hooks/update for a simple mail-on-commit
- CIA: http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#ciabot
- http://lists.gnu.org/archive/html/savannah-hackers/2006-05/msg00069.html, http://lists.gnu.org/archive/html/savannah-hackers/2006-06/msg00010.html: thread about implementing git at Savannah
- http://git.or.cz/gitwiki/InterfacesFrontendsAndToolsWishlist#Savane http://git.or.cz/gitwiki/GitProjects: mention Savane there :)
- http://git.or.cz/gitwiki/GitHosting http://git.or.cz/gitwiki/GitProjects: mention Savane there :)