GLIBC moved to the git SCM in May/June 2009.

Static GLIBC releases from the CVS days are still available in the git repository under the cvs/ name space as branches.

Current upstream maintenance all takes place in git under the master/ name space.

Fetching The Repository

You can use git to check out the sources, including all revision history, with this command:

git clone git://sources.redhat.com/git/glibc.git

That command downloads about 88MB of data which goes into the glibc/.git/ repository, and checks out the source tree, which occupies an additional ~170MB.

Similarly, for the glibc ports add-on, you can:

git clone git://sources.redhat.com/git/glibc-ports.git

To view the recent check-ins do:

git log

To revert the tree to a specific commit do:

git checkout <revision gleaned from git log>

e.g.

git checkout d849666474d7cc33521b1c54b489901289de9e63

For information on checking-out and working with branches skip ahead to Working With Branches.

Developer use of the repository

As a developer you should fetch the repository using the ssh: protocol. Your sourceware ssh keys will allow you to fetch and checkin changes via ssh.

e.g.

git clone ssh://sources.redhat.com/git/glibc.git

or

git clone ssh://sources.redhat.com/git/glibc-ports.git

For simple changes you can do work on your local tracking branch master and simply issue git push to publish the changes upstream. If a simple git push does not work, please contact the libc-help mailing list for help.


Branch Name Space Conventions

Conventions for GLIBC git name space branches come in two tiers.

  1. Top-tier name space branch conventions for the whole repository are owned and administered by the GLIBC maintainers and cover the copyright requirements and assignment of unique name_space/* branches to an individual owner.

    • The community at-large may make suggestions for top-tier convention proposals.
  2. Second-tier branch conventions are described per name space and are defined by the name space owner and detailed in a unique wiki page linked to via a cell in the name space table's 'Details on Second-Tier Conventions' column.

The currently approved Top-Tier name space branch conventions are:

Top-Tier Name Space

Policy Owner and Commiters (by sourceware.org username)

Details on Second-Tier Conventions

cvs/*

n/a

read-only name space

master

drepper, roland

release/*

release managers

See Release Management below.

fedora/*

jakub, roland, schwab

username/*

<username>

No second-tier conventions required. Perform step 3. of Requesting a Name Space below.

name_space/* (not a username)

<owner>,<commiter(s)>

See Requesting a Name Space below.

ibm/*

rsa, sjmunroe, cseo

Second-Tier conventions described in GlibcGit/ibm_namespace.


Requesting a Name Space

The generic policy for requesting a Top-Tier name_space/* branch in the GLIBC git repository is as follows:

  1. Propose a name for the name_space/* branch, owner, intended commit policy, and intended commiter(s) on the libc-alpha mailing list (if nobody calls you rude names, then consider it approved).

    • The proposed owner(s) and commiter(s) must have existing FSF copyright assignment on file with the FSF.
    • The community might have some suggestions on the top-tier policies but it's your playpen.
  2. Update the name space table to reflect the new name_space/* and owner/commiter(s) (use their sourceware.org username).

    • To request a sourceware.org username use the following handy dandy little form.

    • While each owner is free to set branch policies and commit approval in their name space as they like; all people authorized to push (i.e. commit) will need sourceware accounts authorized for the glibc group.

  3. Email overseers@sourceware.org (and CC Roland McGrath roland@redhat.com) and request that the proposed commiters be added to the glibc group.

    • See this email template for information that should be relayed to the sourceware.org overseers.

    • Adding each person to the group goes through the normal overseers process with explicit approval from Roland or another GLIBC maintainer required.
    • The GLIBC maintainers and the Overseers will expect a vouching for sanity and competence, that the person both really, truly understands FSF copyright protocols, and always carefully respects per-branch policies on what they are allowed to touch and how.
  4. Create a unique wiki page as a child of the GlibcGit/ page (e.g. GlibcGit/ibm_namespace) describing the second-tier policies, mission, and branches for the name space.

  5. Update the table cell that is the intersection of the Details on Second-Tier Conventions column and the proposed name space/* row of the name space table to show the intra-wiki link to the newly created unique wiki page for the name space.

A previous request to follow as an example can be found for the ibm/* name space in the following libc-alpha mailing list email http://sources.redhat.com/ml/libc-alpha/2009-06/msg00166.html.


Release Management

1. Don't talk about recommended guidelines for all release branch managers. No, wait, do talk about them. Don't suspect your neighbor. Discuss him on libc-alpha.

2. Remember GNU copyright discipline, even for private branches.

3. Use git branch "release/x.y/master" as "the usual place to look" (whatever that means in your process). The x.y release manager should choose and specify conventions for "release/x.y/*" branches.

4. When a commit backports a change from the trunk (or another proper release branch), use "git cherry-pick -x" or otherwise clearly indicate the original commit id in the backport commit's log entry, and always aim for one separate backport commit per corresponding trunk commit.

5. When a commit is not a backport of a clearly identifiable single commit from the trunk or another release branch, then there should be some voluminous controversy or communal agonized consternation on the mailing lists about whatever it is. i.e., this should always be an automatic red flag for a release manager and all participants, so that it merits explicit discussion more than the usual routine.

6. Try to pay attention to what your past (or concurrent) predecessor release managers have done, and learn from their examples and mistakes.

7. Do not taunt Happy Fun Drepper.

8. The release manager has veto.

Release Management for Ports

Release branches for ports should be named the same as the corresponding libc branches.

Cherry-picked commits may be pushed by the maintainers of the individual ports, in the absence of a specific release manager with a different policy for a given release branch.

In case of doubt, follow the libc procedures but use libc-ports for discussion.

Git Help For Commiters

The following sections should only be necessary for approved git commiters.

ChangeLogs

With the move to git the ChangeLog entry policy has not changed.

This policy is described by the page "Contribution Checklist" under the section heading "GNU ChangeLog".

Commit Messages

Each source change should have an accompanying git commit message. The default rule is one commit per group of related changes though one may find multiple unrelated changes in a single commit at times.

The git commit message can be a single line or a more extensive text, depending on the problem. The git commit messages should be descriptive and not just repeat the ChangeLog entry though it may be wise to include the ChangeLog text for important changes. See the section of this document titled "Updating The Commit Log From a Cherry-Pick Commit" for an example.

To help git tools, multi-line commit messages should have the second line empty.

Example Commit Message: <note the empty second line>

Fix endless loop in localedef.

localedef got into an endless loop in case order_start was used for
the unnamed_section twice and the first use didn't actually result
into any definition.

If there is an associated bugzilla number that BZ number should be in the commit message too, but not as the sole content of the first line (as the automatic converter arranged it) nor solely as the content of the ChangeLog.

Example Commit Message with Bugzilla: <note the empty second line>

Fix to pass -mcpu=CPU to ASFLAGS when building assembler files.

[BZ #10118] When building .S targets the make framework doesn't add
-mcpu=CPU to ASFLAGS.  The commited patch fixes this problem.

Git Settings

Set your full name and email address globally:

git config --global user.name "Full Name"
git config --global user.email "username@host"

This can be overridden on a per-repo basis. First, check out the tree:

Grab the tree:

git clone git://sources.redhat.com/git/glibc.git

Then cd into the tree and set the user.name and user.email locally:

cd glibc
git config user.name "Full Name"
git config user.email "username@host"

For colors in diffs, etc. use the following:

git config --global color.status "auto"
git config --global color.branch "auto"
git config --global color.diff "auto"

Git Branch Name Semantics

Grab the tree:

git clone git://sources.redhat.com/git/glibc.git

Performing git branch -a will result in the following:

* master
  origin/HEAD
  origin/cvs/fedora-2_3-branch
  origin/cvs/fedora-2_5-branch
  origin/cvs/fedora-branch
  origin/cvs/glibc-2-1-branch
  origin/cvs/glibc-2-2-branch
  origin/cvs/glibc-2_0_x
  origin/cvs/glibc-2_10-branch
  origin/cvs/glibc-2_3-branch
  origin/cvs/glibc-2_5-branch
  origin/cvs/glibc-2_6-branch
  origin/cvs/glibc-2_7-branch
  origin/cvs/glibc-2_8-branch
  origin/cvs/glibc-2_9-branch
  origin/cvs/master
  origin/cvs/sparc-2_0_x-branch
  origin/cvs/thomas-posix1996
  origin/fedora/2.10/master
  origin/fedora/master
  origin/master
  origin/release/2.10/master

Notice the usage of the word "origin" on most of the branch paths. The presentation style of git branch -a may lead one to believe that "origin" is part of a branch name. This is incorrect.

The word "origin" on branch names simply indicates that this particular branch tracks a remote branch of a similar name.

All of the branch listed by git branch -a are local branches.

The actual remote branches that the origin/name_space branches track are referenced on the server by refs/heads/name_space. We can use the local:remote syntax to indicate this relationship: e.g.

origin/fedora/2.10/master:refs/heads/fedora/2.10/master branch

When working with local branches it is best to avoid modifying the origin branches directly and in-fact newer versions of git will complain if you do so.

The soundest policy is to branch a local name_space from the local origin/name_space branch as follows:

git checkout -b local_fedora_2.10 origin/fedora/2.10/master

This creates the following relationship:

   local branch     local origin tracked branch        remote tracked branch
----------------------------------------------------------------------------------
local_fedora_2.10 --> origin/fedora/2.10/master --> :refs/heads/fedora/2.10/master

Since origin/fedora/2.10/master follows :refs/heads/fedora/2.10/master, likewise local_fedora_2.10 tracks :refs/heads/fedora/2.10/master.

Due to this relationship one can push changes directory from local_fedora_2.10:refs/heads/fedora/2.10/master

Creating A New Top-Tier Name Space

Once you have approval to create a Top-Tier name_space/* branch you'll need to think about some Second-Tier name space branches and related Second-Tier topic branches.

In general you probably want a Second-Tier 'master' topic branch which is branched from an official release branch.

Any further Second-Tier topic branches should probably branch from that Second-Tier 'master' topic branch, e.g.:

Name Space

Branched From

Description

name_space/

n/a

Top-Tier Name Space

name_space/2.10

n/a/

Second-Tier Name Space

name_space/2.10/master

release/2.10/master

Second-Tier Topic Name Space Branch master branch.

name_space/2.10/foo

name_space/2.10/master

Second-Tier Topic Name Space Branch focused on foo and branched from name_space/2.10/master.

Grab the tree:

git clone git://sources.redhat.com/git/glibc.git

Create the Second-Tier master topic branches in the name_space/* name space:

cd glibc
git branch name_space/2.8/master origin/cvs/glibc-2_8-branch
git branch name_space/2.10/master origin/release/2.10/master
git branch name_space/master master

Create additional Second-Tier topic branches based on the newly created name_space/2.10/master branch:

git branch name_space/2.10/foo name_space/2.10/master

Misnamed a branch?

git branch name_space/2.10/bar name_space/2.10/master

Simply delete it from your local repository and fix it before you git push, but be careful, -D is unforgiving.

git branch -D name_space/2.10/bar
git branch name_space/2.10/foo name_space/2.10/master

Before you git push you should examine the branch structure you've created and you'll see something like this:

  name_space/2.10/foo
  name_space/2.10/master
  name_space/2.8/master
  name_space/master
* master
  origin/HEAD
  ... et al ...

If you need to make some changes in a branch before you commit it you need to switch to the local branch, i.e. sans origin/ in the path since it hasn't been pushed upstream yet:

git checkout name_space/2.10/master

Git push the name_space/* name space branches upstream to add the name_space/* name space branches to the official GLIBC git repo:

git push ssh://username@sources.redhat.com/git/glibc.git name_space/2.8/master:refs/heades/name_space/2.8/master
git push ssh://username@sources.redhat.com/git/glibc.git name_space/2.10/master:refs/heads/name_space/2.10/master
git push ssh://username@sources.redhat.com/git/glibc.git name_space/2.10/foo:refs/heads/name_space/2.10/foo
git push ssh://username@sources.redhat.com/git/glibc.git name_space/master:refs/heads/name_space/master

Older versions of git may not allow the local:remote syntax. In that case leave off the :remote part and it should push to the implicitly tracked branch.

git push ssh://username@sources.redhat.com/git/glibc.git name_space/2.8/master
git push ssh://username@sources.redhat.com/git/glibc.git name_space/2.10/master
git push ssh://username@sources.redhat.com/git/glibc.git name_space/2.10/foo
git push ssh://username@sources.redhat.com/git/glibc.git name_space/master

Update your local repository to reflect the git push:

git remote update

Examine the structure and you should see something like this:

  name_space/2.10/foo
  name_space/2.10/master
  name_space/2.8/master
  name_space/master
* master
  origin/HEAD
  origin/cvs/fedora-2_3-branch
  origin/cvs/fedora-2_5-branch
  origin/cvs/fedora-branch
  origin/cvs/glibc-2-1-branch
  origin/cvs/glibc-2-2-branch
  origin/cvs/glibc-2_0_x
  origin/cvs/glibc-2_10-branch
  origin/cvs/glibc-2_3-branch
  origin/cvs/glibc-2_5-branch
  origin/cvs/glibc-2_6-branch
  origin/cvs/glibc-2_7-branch
  origin/cvs/glibc-2_8-branch
  origin/cvs/glibc-2_9-branch
  origin/cvs/master
  origin/cvs/sparc-2_0_x-branch
  origin/cvs/thomas-posix1996
  origin/fedora/2.10/master
  origin/fedora/master
  origin/master
  origin/name_space/2.10/foo
  origin/name_space/2.10/master
  origin/name_space/2.8/master
  origin/name_space/master
  origin/release/2.10/master

At this point you may remove the local branches if you're done with them:

git branch -D name_space/2.10/foo
git branch -D name_space/2.10/master
git branch -D name_space/2.8/master
git branch -D name_space/master

Removing a Remote Name Space Branch

Removal of branches has been disabled for safety purposes. If a commiter accidentally creates a branch the repository owner should be contacted and they can remove the branch.

Working With Branches

You can switch to a specific branch that the official GLIBC git repository provides. First, check out the tree:

git clone git://sources.redhat.com/git/glibc.git

To view current branch availability use git branch -a:

cd glibc
git branch -a

You will see something like the following:

* master
  origin/HEAD
  origin/cvs/fedora-2_3-branch
  origin/cvs/fedora-2_5-branch
  origin/cvs/fedora-branch
  origin/cvs/glibc-2-1-branch
  origin/cvs/glibc-2-2-branch
  origin/cvs/glibc-2_0_x
  origin/cvs/glibc-2_10-branch
  origin/cvs/glibc-2_3-branch
  origin/cvs/glibc-2_5-branch
  origin/cvs/glibc-2_6-branch
  origin/cvs/glibc-2_7-branch
  origin/cvs/glibc-2_8-branch
  origin/cvs/glibc-2_9-branch
  origin/cvs/master
  origin/cvs/sparc-2_0_x-branch
  origin/cvs/thomas-posix1996
  origin/fedora/2.10/master
  origin/fedora/master
  origin/ibm/2.10/master
  origin/ibm/2.8/master
  origin/ibm/master
  origin/master
  origin/release/2.10/master

The origin/name_space/foo branches are local versions of the remote branches refs/heads/name_space/foo on the GLIBC git server.

To do development there are two options:

  1. Create a new local development branch that is branched from (and tracks) an origin/name_space/foo branch.

    • This is the recommended method that this document will describe.
  2. Work directly in the origin/name_space/ branch.

    • This is discouraged since you now have no easy way to diff against the original release branch code since you polluted it. This method will not be covered here. Newer versions of git may not allow pushes from the origin/name_space branches to the remote refs/heads/name_space branches.

Working From a New Branch

When you perform a git clone you get a copy of the remote source repository with local copies of the refs/heads/name_space branches referenced as origin/name_space branches.

You want to create a new working branch based on a specific origin/ branch and switch the cloned repository's source code state to that new branch.

The following example will create a local branch called foo_2.10 which tracks the remote refs/heads/release/2.10/master branch on the GLIBC server by branching from the local origin/release/2.10/master branch. The origin/ branch from which foo_2.10 is branched implicitly tracks the remote branch on the GLIBC server:

git clone git://sources.redhat.com/git/glibc.git
cd glibc
git checkout -b foo_2.10 origin/release/2.10/master

You can verify that you've switched to this branch with:

git branch -a | grep "foo"

Which should show:

* foo_2.10

At this point you can make your changes.

Making and Committing Changes

Pushing Changes Upstream

To push the changes in this local branch upstream you need to tell git which remote branch it's intended to update (though this may be implicitly understood by git if there is no name_space ambiguity or redundancy):

git push ssh://username@sources.redhat.com/git/glibc.git foo_2.10:refs/heads/release/2.10/master

At this point foo_2.10 is in sync with the remote branch refs/heads/release/2.10/master but origin/release/2.10/master is out of sync with both. This can be rectified with:

git remote update

Now foo_2.10, origin/release/2.10/master, and refs/heads/release/2.10/master should all by in sync, unless refs/heads/release/2.10/master changed due to commits from elsewhere.

Merging Changes From A Tracked Branch

If you are a Top-Tier name space owner or commiter you may need to update your name_space/* branches with the latest version of code from the branches from which they were originally branched.

As an example, let's say:

Assume you've checked out to the name_space/2.10/master topic branch:

git clone git://sources.redhat.com/git/glibc.git
cd glibc
git checkout -b local_2.10 origin/name_space/2.10/master

If there are no local changes just merge from the remote refs/heads/release/2.10/master branch into our remote refs/heads/name_space/2.10/master branch using the following sequence:

If there are local changes git rebase will need to be used. <TODO> Elaborate on this.

Cherry Pick Changes From Another Branch

If you want to pick a particular commit out of one branch and apply it to the local branch you can use git cherry-pick.

First clone the git repository and check out a local branch:

git clone git://sources.redhat.com/git/glibc.git
cd glibc
git checkout -b local_2.10 origin/name_space/2.10/master

Then use git cherry-pick with a commit hash:

git cherry-pick <commit hash>

It is also usually good idea to use the -x option, which will insert the id of the source commit in the new commit's log message - thus, later it can be traced where does this commit come from. E.g.

git cherry-pick -x d849666474d7cc33521b1c54b489901289de9e63

Resolving Cherry-pick Commit Errors

When cherry-picking commits from one branch into another one will almost always encounter merge errors with the src/ChangeLog and src/nptl/ChangeLog files as in the following example.

$ git cherry-pick -x 7a7e49c020125d444fec7fded51bd5f82bfc8c49

Auto-merged ChangeLog
CONFLICT (content): Merge conflict in ChangeLog
Auto-merged locale/programs/ld-collate.c
Automatic cherry-pick failed.  After resolving the conflicts,
mark the corrected paths with 'git-add <paths>'
and commit the result.
When commiting, use the option '-c 7a7e49c' to retain authorship and message.

These can easily be resolved. In the ChangeLog file the merge conflict tags will be readily obvious, as in the following example:

src/ChangeLog:

<<<<<<< HEAD:ChangeLog
=======
2009-09-07  Ulrich Drepper  <drepper@redhat.com>

        * locale/programs/ld-collate.c (struct locale_collate_t): Add
        unnamed_section_defined field.
        (collate_read): Test and set unnamed_section_defined.

        * posix/getconf.c (vars): Handle POSIX2_LINE_MAX in addition to
        _POSIX2_LINE_MAX.

2009-09-04  H.J. Lu  <hongjiu.lu@intel.com>
...
        * sysdeps/x86_64/cacheinfo.c (intel_02_cache_info): Add missing entries
        for recent processor.
        * sysdeps/unix/sysv/linux/i386/sysconf.c (intel_02_cache_info):
        Likewise.

>>>>>>> 7a7e49c... Fix endless loop in localedef.:ChangeLog

To resolve this, extract the portion in the merge conflict that is relevant to the cherry-picked commit. In this case it will be the ChangeLog entry from 2009-09-07. Place this into the ChangeLog in the correctly dated position. In the example case this will be after the merge conflict text:

src/ChangeLog:

>>>>>>> 7a7e49c... Fix endless loop in localedef.:ChangeLog
2009-09-07  Ulrich Drepper  <drepper@redhat.com>

        * locale/programs/ld-collate.c (struct locale_collate_t): Add
        unnamed_section_defined field.
        (collate_read): Test and set unnamed_section_defined.

        * posix/getconf.c (vars): Handle POSIX2_LINE_MAX in addition to
        _POSIX2_LINE_MAX.

2009-05-06  Ryan S. Arnold  <rsa@us.ibm.com>

        [BZ #10118]
        * Makeconfig (+asflags): New variable based upon ASFLAG or
        asflags-cpu.
...

Finally remove all of the merge conflict text, i.e. remove all lines between <<<<<<< and >>>>>>> inclusive. In the example this will put the cherry-picked commit's ChangeLog entry at the top of the ChangeLog file.

Follow the directions of the original cherry-pick command and "After resolving the conflicts, mark the corrected paths with 'git-add <paths>'".

git add ChangeLog

Continue to follow the instructions of the original cherry-pick command and recommit after the new add, whereby "When commiting, use the option '-c 7a7e49c' to retain authorship and message."

git commit -c 7a7e49c

The -c option to git-commit will open the commit log for additional comments with the original git commit message intact. If you invoked the cherry-pick with -x, you will want to manually add the cherry-pick notice at the bottom of the log message:

Commit Message:

Fix endless loop in localedef.

localedef got into an endless loop in case order_start was used for
the unnamed_section twice and the first use didn't actually result
into any definition.

(cherry picked from commit 7a7e49c020125d444fec7fded51bd5f82bfc8c49)

Pushing Git Cherry-pick Commits Upstream

If all conflicts have been resolved the use 'git push' to push the cherry-pick upstream:

git push ssh://username@sources.redhat.com/git/glibc.git local_2.10:refs/heads/name_space/2.10/master

None: GlibcGit (last edited 2009-11-10 15:56:48 by PetrBaudis)