On Sep 30, 2010 at 09:36, Alex Balashov <abalashov(a)evaristesys.com> wrote:
Andrei,
Thank you for your reply -- it is very informative! A few follow-up
questions below:
On 09/30/2010 07:06 AM, Andrei Pelinescu-Onciul wrote:
For the commit permission the update hook looks
into another file, in
which we have a list of:
branch_pattern user_pattern_list
(both of them are regular expressions)
If the branch_pattern and user_pattern match for a specific commit, the
commit is allowed. Besides that any commit on a "username" branch (of
the form $user/.*) is allowed as long as the username of the commiter is
the same as $user
(this can be turned off using a config option).
Do you know if this restriction mechanism also part of a standard
suite of scripts that are associated with git in one way or another,
or something completely custom that was written specifically to
manage permissions centrally on your side?
The update hook is derived from a standard example (which at least at
that time was distributed with git).
We added the "username" branch support and config options for the
default policy.
The mail script is again a modified version of
some perl script. I do
not remember were we took it from. Here is its header:
# V0.4 (mails for never seen before commits)
#
# Tool to send git commit notifications
#
# Copyright 2005 Alexandre Julliard
#
# Updated by Jan Janak<jan(a)iptel.org>
# Updated by Andrei Pelinescu-Onciul<andrei(a)iptel.org>
Oh, okay. Yeah, I am familiar with this script. I was just
wondering which one you were using, even if you have hacked it.
There is no automatic pulling or pushing.
The developer chooses the branch on which he wants to push his changes.
As long as he has write permissions on that branch it will work.
While a more restricted workflow would be theoretically better (e.g. each
developer can push only on his branches or some tmp/ branches and
then send pull/merge requests to some maintainer which would merge the
developer branch into master or stable), most people are used with the
CVS/SVN one branch-for-all model.
So, all contributions to the central repository are ultimately done
by pushing, never pulling?
Yes.
Do all validated developers have write access to the master
branches? Or do 'core', everyday developers like you have write on
the master branch, while more distant, occasional contributors only
have write to branches named after themselves, and core developers
review/merge their changes?
All developers have access to the master and release branches.
The username branches are writeable only by their creators. Apart from
that we have a few old ser and ser integration branches on which I am the
only one allowed to commit and others that are read-only for everybody.
New branches can be created only under $username or tmp/ (this helps
avoid typos in pushes, which otherwise would require constant miss-named
branches deletion).
IMHO at least the release branches permissions should be restricted
(only a group of release managers should be allowed to modify them), but
OTOH hand so far it worked perfectly.
Do you do any "cherry-picking" from time to time from smaller or
less consistent contributors?
We cherry-pick fixes from master into the release branches.
So far we did not need to cherry-pick from contributors branches (so far
we always ended up in merging the whole branch).
If so, how do you do it? The only
process with which I am familiar to do this is to 'git fetch' (not
pull) someone else's changes, 'git cherry-pick' them out of the list
of commits that appear in the range HEAD..FETCH_HEAD (or
master..eval_repo if you 'git fetch'ed those changes straight into a
new branch called 'eval_repo'), then blow the rest of the
FETCH_HEAD/eval_repo differences away (git checkout master; git
merge eval_repo -s ours). Do you do something like this?
No, so far I don't no anybody that uses its own public repo. In the best
case (when not pushing directly in master) everybody pushes his branches
in the main repo and we merge from there.
In general the maintainer of the piece of code affected will do the
merge or ack it (so far there was no need of enforcing this).
In general I try to use separate branches for
bigger features (requiring
several commits). It's easier for me (because I don't have to update the
code everyday, I can work on the old version and merge it when ready and
in the meantime I can switch between several branches with
work-in-progress), it's easier to completely revert if needed and the
history looks nicer.
How do you handle the integration of those branches into master? Do
you keep them local only while you are developing, and then, when
you are ready to push them into the master on the central
repository, do something like:
I always push to the repository the branches containing bigger features
(the one I was speaking above). This allows other developers to see
what I'm doing and acts also as a backup :-).
For example I did all the tls async stuff in andrei/tcp_tls_changes.
After some testing, when I was happy with it I merged it into master.
I used: git checkout master;
git merge --log --no-ff origin/andrei/tcp_tls_changes
I use something similar to what you describe below for local branches
(smaller features, only a few commits that I push directly into master).
1. git checkout master
2. git pull [to update the local copy of the master branch from server]
I use
either git pull --rebase origin master
or git fetch; git rebase origin/master (in case I have some un-pushed
stuff in my local master branch).
3. git checkout feature_branch
4. git rebase master [solve any conflicts between master and
feature_branch here, better to have the conflicts in the branch than
in the master]
5. git checkout master
6. git merge feature_branch
7. git push
Instead of the last 3 steps, I use directly:
git push origin HEAD:master
(less things to write)
Or do you keep even your experimental / large feature branches
pushed to the central repository commonly so that people can see
those changes and look over them and cherry pick things out of them
perhaps?
Yes (although so far nobody was cherry-picking, but somebody might test
stuff on the branches and can comment on the commits).
Also, what are your commit policies like? As you know, Git allows
much more granular management of commits so that they can be
organised to contain hunks that reflect related changes
conceptually, rather than just unavoidably being a log of files
changed over a certain period of time (like SVN or CVS). Do you
insist that developers make very clean commits, stepping through
each patch hunk with 'git add -p' and classifying it, or is this a
matter of personal custom, habit and taste? Do you go back, as a
maintainer, and compact a lot of small commits into big ones by
rebasing them often?
I do try to group commits and I use git add -i _very_ _often_ to
separate multiple changes to the same file that don't logically belong
together. I also try to commit often and make smaller commits
(easier to debug, bisect and if needed revert).
We do recommend that the commits should be small and contain only
related stuff, but so far we haven't enforced it.
We cannot rebase commits on public branches (that would break git pull
for people tracking the branches).
In general, it sounds to me like you are mainly using Git in rather
centralised, SVN/CVS-like ways, but in ways that take advantage of
Git's cheap branching more effectively. Other than being able to
branch easily -- which you don't really even do a lot of -- what do
you perceive to be the main advantage of using Git?
Yes, we do use git in a centralised way. The reason for this is that
this is what most developers are used to. In time we might gradually
change to a more distributed model.
It's very hard for me to say what is the main advantage of using git.
Now I'm so used with it, that it's like asking what is the main advantage
of breathing air :-)
I guess being distributed is the most useful feature. Apart from that I
find it extremely developer/maintainer friendly. I couldn't leave now
without rebase or add -i. Besides that there are all the little things
like git describe, git branch --contains, git format-patch, git-am,
git send-email, git grep, git log branch1 ^branch2. It's also very
fast and very flexible (it doesn't enforce a specific model).
Andrei