Although Git is a truly distributed system, it is often
convenient to organize your project with an informal hierarchy of
developers. Linux kernel development is run this way. There is a
nice illustration (page 17, "Merges to Mainline") in Randy
Dunlap's presentation
[2].
It should be stressed that this hierarchy is purely informal
.
There is nothing fundamental in Git that enforces the "chain of
patch flow" this hierarchy implies. You do not have to pull from
only one remote repository.
A recommended workflow for a "project lead" goes like this:
1. Prepare your primary repository on your local machine. Your
work is done there.
2. Prepare a public repository accessible to others.
If other people are pulling from your repository over dumb
transport protocols (HTTP), you need to keep this repository
dumb transport friendly. After git init
,
$GIT_DIR/hooks/post-update.sample
copied from the standard
templates would contain a call to git update-server-info but
you need to manually enable the hook with mv
post-update.sample post-update
. This makes sure git
update-server-info keeps the necessary files up to date.
3. Push into the public repository from your primary repository.
4. git repack the public repository. This establishes a big pack
that contains the initial set of objects as the baseline, and
possibly git prune if the transport used for pulling from
your repository supports packed repositories.
5. Keep working in your primary repository. Your changes include
modifications of your own, patches you receive via e-mails,
and merges resulting from pulling the "public" repositories
of your "subsystem maintainers".
You can repack this private repository whenever you feel
like.
6. Push your changes to the public repository, and announce it
to the public.
7. Every once in a while, git repack the public repository. Go
back to step 5. and continue working.
A recommended work cycle for a "subsystem maintainer" who works
on that project and has an own "public repository" goes like
this:
1. Prepare your work repository, by running git clone on the
public repository of the "project lead". The URL used for the
initial cloning is stored in the remote.origin.url
configuration variable.
2. Prepare a public repository accessible to others, just like
the "project lead" person does.
3. Copy over the packed files from "project lead" public
repository to your public repository, unless the "project
lead" repository lives on the same machine as yours. In the
latter case, you can use objects/info/alternates
file to
point at the repository you are borrowing from.
4. Push into the public repository from your primary repository.
Run git repack, and possibly git prune if the transport used
for pulling from your repository supports packed
repositories.
5. Keep working in your primary repository. Your changes include
modifications of your own, patches you receive via e-mails,
and merges resulting from pulling the "public" repositories
of your "project lead" and possibly your "sub-subsystem
maintainers".
You can repack this private repository whenever you feel
like.
6. Push your changes to your public repository, and ask your
"project lead" and possibly your "sub-subsystem maintainers"
to pull from it.
7. Every once in a while, git repack the public repository. Go
back to step 5. and continue working.
A recommended work cycle for an "individual developer" who does
not have a "public" repository is somewhat different. It goes
like this:
1. Prepare your work repository, by git clone the public
repository of the "project lead" (or a "subsystem
maintainer", if you work on a subsystem). The URL used for
the initial cloning is stored in the remote.origin.url
configuration variable.
2. Do your work in your repository on master branch.
3. Run git fetch origin
from the public repository of your
upstream every once in a while. This does only the first half
of git pull
but does not merge. The head of the public
repository is stored in .git/refs/remotes/origin/master
.
4. Use git cherry origin
to see which ones of your patches were
accepted, and/or use git rebase origin
to port your unmerged
changes forward to the updated upstream.
5. Use git format-patch origin
to prepare patches for e-mail
submission to your upstream and send it out. Go back to step
2. and continue.