Differences between revisions 24 and 25
Revision 24 as of 2009-06-12 05:17:28
Size: 10049
Editor: JasonMerrill
Comment: more fixes
Revision 25 as of 2009-06-14 18:44:23
Size: 10051
Comment: prefix gnulib-tool with ./
Deletions are marked like this. Additions are marked like this.
Line 185: Line 185:
gnulib-tool --create-testdir --dir=/tmp/testdir123 git-merge-changelog ./gnulib-tool --create-testdir --dir=/tmp/testdir123 git-merge-changelog

GCC GIT mirror

For the gcc svn repository exists also an read only git mirror. So you can use git for your daily gcc development.

The git repository is available at:


Get the source code of trunk

% mkdir gcc
% cd gcc
% git init
Initialized empty Git repository in /usr/home/Alice/gcc/.git/
% git remote add origin git+ssh://alice@gcc.gnu.org/git/gcc.git
% git fetch
remote: Counting objects: 870677, done.
% git branch -a

remote: Compressing objects: 100% (201036/201036), done.
Receiving objects: 100% (870677/870677), 296.70 MiB | 808 KiB/s, done.
Resolving deltas: 100% (706094/706094), done.
From git+ssh://alice@gcc.gnu.org/git/gcc
 * [new branch]      master     -> origin/master
 * [new branch]      pre-globals-git -> origin/pre-globals-git
 * [new branch]      restrict-git -> origin/restrict-git

Get svn branches

The git repository we cloned does not contain all branches. To do e.g. some graphite development we have to get the graphite branch.

% git config --add remote.origin.fetch '+refs/remotes/graphite:refs/remotes/origin/graphite'
% git fetch
remote: Counting objects: 86896, done.
remote: Compressing objects: 100% (41232/41232), done.
remote: Total 76919 (delta 49977), reused 59333 (delta 34708)
Receiving objects: 100% (76919/76919), 72.07 MiB | 695 KiB/s, done.
Resolving deltas: 100% (49977/49977), completed with 5347 local objects.
From git+ssh://alice@gcc.gnu.org/git/gcc
 * [new branch]      graphite   -> origin/graphite
% git branch -a

To get all branches use:

% git config --add remote.origin.fetch '+refs/remotes/*:refs/remotes/origin/*'
% git fetch

Update repository from git

To get new commits just use "git fetch" or "git pull". The git mirror is updated at least every 30 minutes so you should get new code really fast.

Using git-svn

Until now we did git only development. But there are two reasons to get git-svn in the game:

  • get new commits directly from the svn repository (no delay)
  • commit from our git repository (forget about svn completely)

!! I just figured out how to make it work for one branch

Initialize git svn

If you have cloned a repos from other developers, there is a quick way for you to rebuilding the git-svn metadata. For a detailed description of git-svn, you can read this post: An introduction to git-svn for Subversion/SVK users and deserters

Here your working directory is your cloned repos:

# Initialize git-svn locally [1]
% git svn init svn+ssh://alice@gcc.gnu.org/svn/gcc/branches/graphite

# Pull the latest changes from Subversion [2]
% cp .git/refs/remotes/origin/graphite .git/refs/remotes/git-svn

# Update git from svn
% git svn fetch
Rebuilding .git/svn/git-svn/.rev_map.138bc75d-0d04-0410-961f-82ee72b054a4 ...
r115015 = b948ba9b92a300e4ad87fee28f9c530504b2d835
Done rebuilding .git/svn/git-svn/.rev_map.138bc75d-0d04-0410-961f-82ee72b054a4

1. IMPORTANT: If the repos you cloned from initialize using git svn init svn+ssh://alice@gcc.gnu.org/svn/gcc/branches/graphite You must use exactly the same except the username. This means you CAN'T use svn:// or http:// instead of svn+ssh://. If you want to know details, see 3 after you reading 2.

2. This line of code

cp .git/refs/remotes/origin/graphite .git/refs/remotes/git-svn

will copy your HEAD's SHA number to file git-svn. SHA is a 40 digits number which looks like b948ba9b92a300e4ad87fee28f9c530504b2d835. So you can just simple run git log and then copy the 40 digits number to the file git-svn. The simple reason in 1 is that any different thing in a commit will cause the different SHA.

3. The reason why we do this(see 1) because every commit corresponding to a SHA number, which looks like 78ad11bf2f61b35e1cb32a978ab546d198be8a2e. If two commit has the same SHA, then they are exactly the same. This will including timestamps/commiter/patch, as well as what we mentioned in 1. If you use svn+ssh://, then it will corresponding a line like

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/graphite@145404 138bc75d-0d04-0410-961f-82ee72b054a4
  • in the log, while svn:// will corresponding to

git-svn-id: svn://gcc.gnu.org/svn/gcc/branches/graphite@145404 138bc75d-0d04-0410-961f-82ee72b054a4

4. If you didn't clone a git repos from a developer, you can rebuild your own with the following instructions , feel free to use http:// svn:// or svn+ssh:// that

anything you can easily access. But this might cause you about 50 hours(for me) to rebuild the metadata.

% git svn init svn+ssh://alice@gcc.gnu.org/svn/gcc/branches/graphite
% git svn fetch

For a detailed workflow of this usage, you can refer to this post:

git-svn workflow

Update git svn

% git svn fetch

Commit to svn branch

% git svn dcommit

!! Check documentation to not commit a lot of strange stuff to the gcc repository.

Alternative git-svn procedure (Jason Merrill)

Here's what seems to me to be the optimal way of using git-svn with the GCC repository:

mkdir gcc-git
cd gcc-git
git init
git remote add origin git://gcc.gnu.org/git/gcc.git
# Need to use this exact SVN url for gcc.git and git-svn to work together.
git svn init -s svn+ssh://gcc.gnu.org/svn/gcc
git config remote.origin.fetch refs/remotes/trunk:refs/remotes/trunk
# Setup 'git pull'.
git config branch.master.remote origin
git config branch.master.merge refs/remotes/trunk
git pull
# Tell future pulls to rebase in order to work better with SVN.
git config branch.master.rebase true
git svn show-ignore >> .git/info/exclude

and you're all set to start hacking. Note that the first remote.origin.fetch line doesn't use --add because we aren't interested in origin's heads, just its remotes that track SVN.

Note also that the commands above only pulls down the SVN trunk, because I like to have different branches in different directories, as described below. If you want more branches in this directory, you can add lines like

git config --add remote.origin.fetch refs/remotes/gcc-4_4-branch:refs/remotes/gcc-4_4-branch

before the pull. If you want all branches, use "remote/refs/*:remote/refs/*". But you probably don't want all branches; they double the size of the repository.

If you want a branch that lives in a subdirectory of branches, such as redhat/gcc-4_4-branch, you can't get it from the gcc.git mirror for some reason, so leave out the remote.origin.fetch line for that branch, and do a git svn fetch to fetch all our branches from SVN. If you're going to do that, instead of svn init -s, you probably want to do

git svn init svn+ssh://gcc.gnu.org/svn/gcc -T trunk
git config --add svn-remote.svn.fetch branches/redhat/gcc-4_4-branch:refs/remotes/redhat/gcc-4_4-branch
git svn fetch

so you don't pull the whole world down from SVN.

Pull changes from the git mirror as desired using

git pull

or from the SVN repository (e.g. if you need a change that isn't in the git mirror yet) using

git svn rebase

To push all of your local commits to the SVN server, use

git svn dcommit

Before long you'll get frustrated with git's handling of ChangeLog merges, which is just as bad as SVN's. But there's a fix for that!

git clone git://git.savannah.gnu.org/gnulib.git
cd gnulib
./gnulib-tool --create-testdir --dir=/tmp/testdir123 git-merge-changelog
cd /tmp/testdir123
make install
git config --global merge.merge-changelog.name "GNU-style ChangeLog merge driver"
git config --global merge.merge-changelog.driver "/usr/local/bin/git-merge-changelog %O %A %B"
echo "ChangeLog   merge=merge-changelog" >> ~/gcc-git/.git/info/attributes

To make a local clone for hacking on another branch at the same time, you can do

mkdir gcc44-git
cd gcc44-git
git init
# Tell git not to re-fetch shared objects in the trunk repository
echo ~/gcc-git/.git/objects >> .git/objects/info/alternates
git remote add origin git://gcc.gnu.org/git/gcc.git
git svn init -s svn+ssh://gcc.gnu.org/svn/gcc
git config remote.origin.fetch refs/remotes/gcc-4_4-branch:refs/remotes/gcc-4_4-branch
git config branch.master.remote origin
git config branch.master.merge refs/remotes/gcc-4_4-branch
git pull
git config branch.master.rebase true
cp ~/gcc-git/.git/info/{attributes,exclude} .git/info/

And then do pull/rebase/dcommit as with your main repository; this repository should be significantly smaller than the main one as it only contains the changes on the branch itself; it uses your main repository for anything on the trunk. You can use this repository without doing anything in your trunk repository as long as you don't delete the trunk repository.

Note that you shouldn't use git cherry-pick to copy changes between SVN branches, as that brings along svn metadata which could confuse git-svn into thinking you're on a different SVN branch. Better I think to use git show/git apply, or do the merge in SVN directly.

I'm also finding Stacked Git useful for hacking on GCC, since it makes it easy to pop off patches that I'm still working on so I can apply the one I've just finished testing. See the StGit webpage for information on general usage; for using it with git-svn what I find works best is to do

# Update to current git head:
stg pull

# Commit patch FOO to SVN:
stg pop -a
git svn rebase
stg push FOO
stg commit
git svn dcommit
stg push -am

None: GitMirror (last edited 2017-12-16 21:09:40 by JerryDeLisle)