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.
URL list summary:
git://git.savannah.gnu.org/mygroup.git
- unencrypted read-only git lightweight protocolssh://git.savannah.gnu.org/srv/git/mygroup.git
- encrypted member read-write developer access using SSHhttps://git.savannah.gnu.org/git/mygroup.git
- encrypted read-only anonymous smart http accesshttp://git.savannah.gnu.org/git/mygroup.git
- unencrypted read-only anonymous smart http access, for use behind restrictive firewallshttp://git.savannah.gnu.org/r/mygroup.git
- 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)
The links in bold are the preferred and recommended protocols to use. This 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! The other link types are also available for those that can't make use of the encryption protected protocols.
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: http://git.savannah.gnu.org/gitweb/ http://git.savannah.gnu.org/cgit/
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 bothgit://
andhttps://
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/ # <edit some_existing_file> git commit -a -m "I automatically commit modified files" # <edit some_other_existing_file and something_else> 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
http://www.kernel.org/pub/software/scm/git/docs/git-clone.html,
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:
https://savannah.gnu.org/project/admin/editgroupfeatures.php?group=libcdio
"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 <rms@gnu.org>
toto = Another User <me@mydomain.com>
...
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.
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 <rms@gnu.org>
toto = Another User <me@mydomain.com>
...
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
a 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 http://git-scm.com/docs/git-push#_note_about_fast_forwards 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. http://savannah.gnu.org/support/?108709).
- Accidental commits when it is clear no code will be lost due to enabling non-fast-forwards commits (e.g. http://lists.gnu.org/archive/html/savannah-users/2015-01/msg00010.html).
These are done on a case-by-case basis, and enabled only for a short period (usually 24 hours). Please submit a support request (https://savannah.gnu.org/support/?func=additem&group=administration 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
http://lists.gnu.org/archive/html/savannah-hackers-public/2015-01/msg00011.html).
Links
- https://git-scm.com/doc - 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).
- http://git.or.cz/course/ - Older no longer maintained documentation but still quite useful such as http://git.or.cz/course/svn.html "Git for SVN users".
- http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html
- Tutorial
- https://www.kernel.org/pub/software/scm/git/docs/giteveryday.html
- Everyday GIT With 20 Commands Or So
- https://web.archive.org/web/20160321083320/http://ktown.kde.org/~zrusin/git/git-cheat-sheet-medium.png
- Git Cheat Sheet (original site offline now but available from archive.org)
- http://www.kernel.org/pub/software/scm/git/docs/user-manual.html 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.