Contents
Fetching The Repository
Current upstream maintenance all takes place in git in the master branch.
You can use git to check out the sources, including all revision history, with this command:
git clone git://sourceware.org/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.
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
This repository is also accessible via gitweb at http://sourceware.org/git/?p=glibc.git. The mirror http://repo.or.cz/w/glibc.git provides some extra 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://USER@sourceware.org/git/glibc.git
Where USER is your sourceware username. 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.
If you already have an anonymous clone you don't have to clone it all over again for developer use. You convert an anonymous repository to a developer use repository by changing the URL like this:
git config remote.origin.url ssh://USER@sourceware.org/git/glibc.git
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 |
Community consensus |
|
release/* |
release managers |
See Release Management below. |
fedora/* |
aoliva, codonell, law, patsy, siddhesh |
|
username/* |
<username> |
No second-tier conventions required. |
name_space/* (not a username) |
<owner>,<commiter(s)> |
See Requesting a Name Space below. |
ibm/* |
cseo, gftg, pmur, raji, sjmunroe, tuliom |
Second-Tier conventions described in GlibcGit/ibm_namespace. |
google/* |
bmoses, ppluzhnikov, roland, shebs, sivachandra, vapier |
Second-Tier conventions described in GlibcGit/google_namespace. |
arm/* |
mshawcroft, nsz |
Second-Tier conventions described in GlibcGit/arm_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.
If you are creating a <username>/ you don't need to do anything beyond becoming a maintainer (developer).
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.
- All owner(s) and committer(s) should immediately do one of the following:
Minimally use these instructions for individual contributors.
The best would be to follow these instructions, and become full glibc maintainers.
Update the name space table to reflect the new name_space/* and owner/commiter(s) (use their sourceware.org username).
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://sourceware.org/ml/libc-alpha/2009-06/msg00166.html.
Tag Conventions
Tags will only be used to mark snapshots or full releases to external parties.
Snapshot tags are used to mark releases being delivered to the translation team. Snapshot tags are of the form glibc-X.Y.Z.DATE where DATE is YYYYMMDD e.g. 20180801. Snapshots of trunk always start with 9000 for the value of Z e.g. glibc-2.28.9000.20180801.
Release tags are used to mark a release and must be signed tags. Release tags are of the form glibc-X.Y or glibx-X.Y.Z.
Release Management
Policies of release branches for main glibc repository are discussed at length on the Release page - refer there to learn about currently maintained branches and general policies.
Legacy release branches for the obsolete ports repository 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 are mostly important for approved git commiters, however, anyone can of course in principle create their own git tree, commit to it and send a pull request (git request-pull) to the mailing list - then these commits should follow the guidelines below. (However, note that for small amount of patches, it is better to send them directly, and for large-scale changes it's better to consult before starting to work on them, so pull requests are not seen very commonly.)
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://sourceware.org/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"
Commit Changes
Author Attribution
If you are not the original author of the patch, but are committing a patch on behalf of someone else you should commit using:
git commit --author="Joe Developer <joe@developer.ca>"
This will record the author correctly in git. Alternatively if you use git am this will correctly set the author using the From: line.
If you've forgotten to record the author correctly in the git commit you may amend the commit as follows:
git commit --amend --author="Joe Developer <joe@developer.ca>"
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.
To help git tools, multi-line commit messages should have single-line title on the first line and 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).
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. Tested on x86_64.
Git Branch Name Semantics
Grab the tree:
git clone git://sourceware.org/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://sourceware.org/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@sourceware.org/git/glibc.git name_space/2.8/master:refs/heads/name_space/2.8/master git push ssh://username@sourceware.org/git/glibc.git name_space/2.10/master:refs/heads/name_space/2.10/master git push ssh://username@sourceware.org/git/glibc.git name_space/2.10/foo:refs/heads/name_space/2.10/foo git push ssh://username@sourceware.org/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@sourceware.org/git/glibc.git name_space/2.8/master git push ssh://username@sourceware.org/git/glibc.git name_space/2.10/master git push ssh://username@sourceware.org/git/glibc.git name_space/2.10/foo git push ssh://username@sourceware.org/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@sourceware.org/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://sourceware.org/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://sourceware.org/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.
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@sourceware.org/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.
Developing Major Features in Tracking Branches
For larger changes, especially if those involve several architectures that the main author cannot test, the author should provide the changes in a publicly available branch that can easily be cloned and tested by platform and subsystem maintainers. The following work flow should be used:
- Create a branch and push it to the public glibc git repository as a personal branch.
- Test it on at least one architecture.
- Ask on the libc-alpha mailing list for review and testing by other parties. Give architecture maintainers enough time for this (an explicit deadline with 5 days should be ok)
- Merge the branch after getting reviews, additional tests - and no test failures.
TODO: Do we want to allow an implicit git merge or require a git pull --rebase prior to the push?
Merging Changes From A Tracked Branch
If you are a Top-Tier name space owner or committer 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://sourceware.org/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
TODO: Is a git merge better in this case than a git pull? Is a git pull --rebase more correct?
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@sourceware.org/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://sourceware.org/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
In case of a conflict, follow the instructions of the 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)
(PetrBaudis considers it good style to always have the cherry-pick line in a separate paragraph, but others might not care.)
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@sourceware.org/git/glibc.git local_2.10:refs/heads/name_space/2.10/master
Git Server Maintenance
The glibc git server is setup to garbage collect when we have >= 2000 loose objects, we do this because glibc commits are small and frequent resulting in a larger repo size, but not large enough that it triggers gc at push time (when the server runs git gc --auto) given the default gc.auto value.
git --git-dir=/git/glibc.git config gc.auto 2000
History of the repositories
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.