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.
Contents
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
The repository is mirrored at http://repo.or.cz/w/glibc.git with some extra gitweb features and especially allowing developers to easily publish repositories with their glibc changes at the site.
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.
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.
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:
Note: This policy was defined by Roland McGrath on the libc-alpha mailing list in this thread.
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.
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.
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.
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.
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.
Each remote branch on the GLIBC git server is reflected by a local origin/ branch in your cloned repository.
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.
While you don't need Second-Tier topic branches like 'master' it is probably useful as a common topic branch for Second-Tier policies.
- Otherwise your Second-Tier name space is the branch you check out.
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
Warning: While branch deletion is disabled for the GLIBC repository for most commiters, readers should be aware that passing an empty local branch name with git push will normally result in the removal of :remote branch on the remote server. In the following example the name_space/2.10/master branch would be removed from the remote server:
git push ssh://username@sources.redhat.com/git/glibc.git :refs/heads/name_space/2.10/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
Note: The directions in this section are predicated on an understanding of the git branch name semantics regarding the origin/ branches in a cloned repository. Please reference the earlier section titled "Git Branch Name Semantics"
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:
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.
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
Note: this particular example pushes to the refs/heads/release/ Top-Tier name space which only Release maintainers are allowed to modify. Take care that you don't commit to a branch that you're not authorized to commit to or you may find your commit permissions revoked!
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:
name_space/2.10/master generally tracks refs/heads/release/2.10/master
name_space/2.10/master contains everything in refs/heads/release/2.10/master plus additional changes unique to name_space/*.
refs/heads/release/2.10/master is updated with new patches.
name_space/2.10/master will want to merge those changes so they need to be merged into the name_space/2.10/master branch.
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:
Update the origin/release/2.10/master branch to sync with the remote refs/heads/release/2.10/master branch:
git remote update
Merge the new changes to origin/release/2.10/master into local_2.10 (which is a branch of origin/name_space/2.10/master):
git merge origin/release/2.10/master
At this point local_2.10 is in sync with origin/release/2.10/master and no longer in sync with origin/name_space/2.10/master which it tracks:
Push the changes upstream into the remote refs/heads/name_space/2.10/master branch:
git push ssh://username@sources.redhat.com/git/glibc.git local_2.10:refs/heads/name_space/2.10/master
Following this another git remote update will sync branches local_2.10 and origin/name_space/2.10/master and origin/release/2.10/master.
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.:ChangeLogTo 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