UsingGit
Savannah documentation
UsingGit
Using GIT at Savannah
To use Git on Savannah, you first need to enable it for your group;
then a cron job will create an empty repository,
see
VCS Intro
Clone URLs
Ecnrypted access
These are preferred and recommended protocols to
use. This is because they are encrypted to protect against possible
man-in-the-middle data corruption. This also protects against broken
site proxies and other misconfiguration. And also snooping too!
ssh://git.savannah.gnu.org/srv/git/mygroup.git
authenticated access using SSH, read-write developer for group members
and read-only for other Savannah users
read-only anonymous smart http access
As of 2025-04, the service providing the https:// access is heavily
loaded by crawlers and sometimes may be unavailable. The ssh://
URL is more stable in this respect.
Unencrypted access
These link types are available for those who can't make use of
the encrypted protocols.
git://git.savannah.gnu.org/mygroup.git
- unencrypted read-only git
lightweight protocol
- unencrypted
read-only anonymous smart http access, for use behind restrictive
firewalls
- unencrypted
read-only anonymous smart http access, for use behind excessively
restrictive firewalls
previously this was the slow dumb protocol but has since been
switched to the git smart http protocol the same as the above
/git/
path, making this URL redundant with the above)
Both
sv.gnu.org
and
savannah.gnu.org
and the same for nongnu.org
are all the same. Use whichever you prefer using. Also all of the
domain names exist in both
gnu.org
and
nongnu.org
domains.
Web browser:
If you use ssh-based access, please verify the host keys first at
SshAccess
Note: There is up to a 1/2 hour delay between Git group creation in
the web front-end, and its creation on the back-end system. The
back-end version control system hosting git creates repositories by
running a cron job every half hour.
Basic commands
Checkout (read-only):
git clone https://git.savannah.gnu.org/git/group.git
or
git clone git://git.savannah.gnu.org/group.git
For example cloning the GNU Hello package.
git clone https://git.savannah.gnu.org/git/hello
or
git clone git://git.savannah.gnu.org/hello
Firewall checkout (read-only): if you're behind a
outgoing-traffic-filtering firewall, you can use Git's "dumb
protocol" via HTTP. The difference here is the
/r/
part of the
path instead of the
/git/
path for the https and http protocols.
Note that the git dumb protocols is SLOWER, both for you and
Savannah. But this may work when both
git://
and
are
blocked. Avoid if possible, and please tell your local sysadmin
to allow https and/or git protocol on port 9418:
git clone http://git.savannah.gnu.org/r/group.git
Group member checkout: If you want to be able to push your changes
back into the repository on Savannah then members must use ssh
protocol to have write access.
git clone ssh://login@git.sv.gnu.org/srv/git/group.git
Or using the alternative scp-like format. Both are equivalent.
git clone login@git.sv.gnu.org:/srv/git/group.git
Note that the ssh transport requires an active Savannah account and
you must be a member of at least one group in order for your account
to be enabled.
Developer setup
(For git 1.5.1 or newer)
Your identity for when you push commits. (Also okay to use the
GIT_
environment variables.)
git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com
Enable colors (optional):
git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
Disabling colors [defaults on in later git versions] (optional):
git config --global color.ui false
Note: If colors are enabled and you set the
LESS
environment
variable then it must include the
-R
option or colors will be shown
as their raw escape sequences. Warning: Git knows about pagers and
less and if LESS is not set will set it to
FRSX
but if
LESS
is set
will not modify it.
Developer basic commands
Create the initial directory and change to it:
mkdir git_directory
cd git_directory
Initial push / import:
git init
touch README
# edit/add other files...
# Import everything:
git add .
git commit -m "Initial import"

# initial publication to the 'master' branch
git push --all login@git.sv.gnu.org:/srv/git/group.git
Note: at this point your repository is not setup to merge _from_
the remote branch when you type 'git pull'. You can either freshly
'clone' the repository (see "Developer checkout" below), or
configure your current repository this way:
git remote add -f origin login@git.sv.gnu.org:/srv/git/group.git
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
Developer checkout (via SSH - beware of punctuation):
git clone ssh://login@git.sv.gnu.org/srv/git/group.git
# or
git clone login@git.sv.gnu.org:/srv/git/group.git
Commit:
cd group/

#
git commit -a -m "I automatically commit modified files"

#
git add some_other_existing_file
git commit -m "I only marked some_other_existing_file for commit"

# Check your changes with the graphical tool
gitk

# Send everything to Savannah
git push
Fixing checkout from git:// to ssh://
If by mistake a developer has checked out a repository using the
public anonymous read-only git:// url this can be changed to the
authenticated ssh:// url using git remote set-url:
git remote set-url origin ssh://login@git.sv.gnu.org/srv/git/group.git
If the origin remote has been removed, or if someone wishes to remove
origin and recreate it, then it may be removed and set:
git remote rm origin
git remote add origin ssh://login@git.sv.gnu.org/srv/git/group.git
git fetch
git branch -u origin/master master
Shallow checkouts
When bandwidth is an issue, people can download the latest version of
your repository without downloading all the history, using "shallow
checkouts". Note that such a copy has limitations, see
option
--depth
for details.
Example:
$ git clone --depth 1 git://git.sv.gnu.org/gnulib.git
Initialized empty Git repository in /tmp/gnulib/.git/
remote: Counting objects: 9897, done.
remote: Compressing objects: 100% (5462/5462), done.
Indexing 9897 objects...
remote: Total 9897 (delta 7382), reused 5737 (delta 4419)
100% (9897/9897) done
Resolving 7382 deltas...
100% (7382/7382) done

$ du -sh gnulib/.git
6,3M gnulib/.git

$ du -sh full-gnulib/.git
28M full-gnulib/.git
git-cvsserver pserver compatibility
You can download a git repository using the CVS client, thanks to a
pserver-compatible server from git:
$ cvs -d:pserver:anonymous@pserver.git.sv.gnu.org:/autoconf.git co -d autoconf master
cvs checkout: Updating autoconf
U autoconf/.cvsignore
U autoconf/.gitattributes
U autoconf/.gitignore
U autoconf/.x-sc_prohibit_atoi_atof
U autoconf/.x-sc_space_tab
U autoconf/.x-sc_sun_os_names
U autoconf/.x-sc_trailing_blank
U autoconf/.x-sc_useless_cpp_parens
U autoconf/AUTHORS
U autoconf/BUGS
U autoconf/COPYING
...
Importing from CVS
First thing you may want to do is to tag the state of your CVS
repository and declare it as closed. For example:
$ cd my-checked-out-cvs-repository
$ cvs tag cvs-repository-moved-to-git
On your group page, activate git. For example the libcdio group the
URL for the group page is:
"activated" is in the second column and the "git" row is midway down the
page. If you forget to do this or git is not active, you may get a
message like this:
Pushing to rocky@git.sv.gnu.org:/srv/git/libcdio.git
fatal: '/srv/git/libcdio.git': unable to chdir or not a git archive
fatal: The remote end hung up unexpectedly
Git comes with the tool,
git-cvsimport
which will import a CVS
repository into a new git repository. You may want to use this for
converting your existing CVS repository to a new git repository.
We will use a file which maps a Savannah login name username to real
name (option
-A
) in the
git-cvsimport
command. The format of this
file like this:
rms = Richard M. Stallman
toto = Another User
...
After creating this file, run something along the lines of the following
mythical shell session:
$ # create authors.txt
$ group='mygroup' # change mygroup
$ myrepository='pserver:anonymous@cvs.savannah.nongnu.org' # Or whatever you usually use for CVS
$ mkdir $group
$ cd $group # Note: that this is new directory. It is not git yet.
$ module='mymodule' # adjust this
$ git-cvsimport -A ../authors.txt -p x -v -d:${myrepository}:/sources/$group $module
Adjust the variables
myrepostory
to be whatever you use to checkout
CVS; the
cvs.savannah.nongnu.org
address won't be correct if your
group is a GNU package. If your group is old or has lots of commits,
git-cvsimport
may take a long time because it is replaying the entire
commit history: copying down each version of each file and then
performing essentially
git-commit
for every CVS commit.
This will create a local git repository with at least two branches:
$ git show-branch -a
* [master] Moved from CVS to GIT.
! [origin] Moved from CVS to GIT.
--
*+ [master] Moved from CVS to GIT.
Before pushing this to your Savannah group page you might want to
rename or remove that "origin" branch. It has the same state and history
as the master branch so you won't lose any information. (Footnote:
Normally the origin branch is used by developers who prefer to use git
while working on groups that only run a central CVS repository. They
do their work on "master" but track the changes in the CVS repository in
the "origin" branch.) This is not what you are going to do anyway and
unfortunately "origin" is also the default alias name for remote git
repositories and thus it may lead to unnecessary confusion. You can
remove the branch like this:
$ git branch -d origin
Don't worry! If you ever need to recreate that branch you can always do
so by branching off at that last CVS commit and call the branch
"origin", "cvs" or "back-in-the-dark-ages".
Now you are ready to push this git repository to your Savannah group
page using the instructions under
Pushing a Newly-Created, Existing, or Converted Git Repository
If you have converted from a different version control repository to
git then consider disabling commits to the previous location so as to
prevent confusing history creation.
CvsDisabling
Importing from SVN
Git comes with 2 SVN-related tools:
git-svnimport
and
git-svn
git-svnimport
is for importing revisions (a one-shot import, or
incrementally);
git-svn
is a 2-way gateway to a SVN repository,
similar to SVK, more useful for maintaining a local branch than for
importing a repository (IMHO). We'll use
git-svnimport
We will use a file which maps a Savannah login name to real name
(option
-A
). It looks like this:
rms = Richard M. Stallman
toto = Another User
...
Common invocation:
git-svnimport -v -I .gitignore -A ../authors.txt file:///home/me/svn_repo
To ignore branches:
git-svnimport -v -I .gitignore -A ../authors.txt -b idontexist file:///home/me/svn_repo
git-svnimport
assumes there is a trunk, a branches, and a tags
directory (names are configurable) and ignores other directories. You
may run into troubles if your layout changed during your former SVN
life.
You'll usually perform the import several times before getting what you
want. For this reason it's preferable to rsync the SVN repository
locally:
rsync -av rsync://svn.sv.gnu.org/svn/mygroup svn_repo
or create it from a dump:
wget http://svn.gna.org/daily/mygroup.dump.gz
svnadmin create svn_repo
zcat mygroup.dump.gz | svnadmin load svn_repo/
To access a local copy of the repository, use svnserve:
svnserve -d -r svn_repo
Then access it with git svn with something like:
git svn clone svn://127.0.0.1/mygroup -A authors-transform.txt --stdlayout ./temp.checkout
where mygroup is the subdirectory under svn_repo.
Importing from GNU Arch
Use
git-archimport
Example importing a repository with a
group--main--1.0
main archive and
group--release--1.7
tag, converting the Arch-style names into
Git-style names:
git-archimport me@domain.tld--2007/group--main--1.0:master group--release--1.7:v1.7
Pushing a Newly-Created, Existing, or Converted Git Repository
If you are importing a repository with tags, e.g. for past releases, use
the --tags option to send them with the initial import:
$ login='mylogin'
$ group='mygroup'
$ git push --tags -v ${login}@git.sv.gnu.org:/srv/git/${group}.git
Similarly remember to use the '--all' flags to push all branches, not
just the 'master' one:
$ git push --all -v ${login}@git.sv.gnu.org:/srv/git/${group}.git
If you have branches and you don't push all branches when you do a
git-clone
you may get error messages like the one below:
$ git clone git://git.savannah.gnu.org/libcdio.git
Initialized empty Git repository in /src/external-vcs/libcdio/.git/
remote: Counting objects: 15471, done.
remote: Compressing objects: 100% (3223/3223), done.
....
Receiving objects: 100% (15471/15471), 16.56 MiB | 231 KiB/s, done.
Resolving deltas: 99% (12089/12208) Resolving deltas: 100% (12208/12208) Resolving deltas: 100% (12208/12208), done.
cd: 491: can't cd to /src/external-vcs/libcdio/.git/refs/remotes/origin
Warning: Remote HEAD refers to nonexistent ref, unable to checkout.
Removing a branch
We don't really like this, but there's a way to remove remote branches.
We don't like it because this allow group members to potentially
remove free software from Savannah, willingly or by mistake. This is
mitigated by the fact it is very easy to push back changes.
When removing a branch, only its reference is removed, and the commit
are still reachable by their identifiers. However, Savannah may prune
unreachable commits (
git gc
), so don't count on this.
To remove a branch:
git push origin :mybranch
Git still will refuse to delete the default branch this way.
Non-Fast-Forward commits
'non-fast-forward' commits are commits which result in
rewriting the commit history, leading to lost commits (see
for a technical
explanation).
In Savannah, non-fast-forward commits are disallowed, for the same reason that
RemovingProject
is disallowed: to prevent removal of published code.
Another reason to avoid non-fast-forward commits is to prevent troubles for
users who already cloned a public repository - as a simple 'pull' will fail
in their local repository.
Under special circumstances, Savannah administrators can temporarily enable
non-fast-forward commits in a specific repository. Such cases include:
Newly created group, where there is no existing code, and it is clear
the new group administrator accidentally commited wrong code (e.g.
).
Accidental commits when it is clear no code will be lost due to enabling
non-fast-forwards commits (e.g.
).
These are done on a case-by-case basis, and enabled only for a short
period (usually 24 hours). Please submit a support request
or email savannah-hackers-public@gnu.org if you need to temporarily
enable non-fast-forward commits.
An advanced configuration option where non-fast-forward commits are enabled
for all branches except the
master
branch as been discussed but is not
currently implemented (see
).
Links
- Latest up-to-date information on git.
repo.or.cz: hosting system similar to Savannah. Offers a public
''mob'' branch. The internals look a bit ad-hoc (lots of cron jobs
that changes all permissions, privileges to Apache instead of a
cron'd backend).
- Older no longer maintained
documentation but still quite useful such as
"Git for SVN users".
Tutorial
Everyday GIT With 20 Commands Or So
Git Cheat Sheet (original site offline now but available from archive.org)
A more complete user manual
FAQ
How does a group admin update the "description" file for the web
interface?
Please visit the 'Administer' link in the Git submenu, either
in the 'Source code' top menu or in 'Development Tools' section
of the main page.
Similarly, how can a group admin update the "HEAD" file to point
to another branch?
Unusual branching strategies are strongly discouraged. "Standard is
better than better." You are encouraged to use typical branching
strategies. If you need something custom for your group please
file a
support request
and a Savannah Admin will discuss this with you and take any actions
that are needed.
Links:
FrontPage
Git
SavannahInternals
WhyChooseSavannah
back-page
Last edited
Sun May 25 13:14:27 2025