Andreas K. Huettel: >> >> However, rebasing changes *on* master, before they are pushed, is a good >> thing, because that kills non-fast-forward merges. >> > > Nontrivial rebases *on* master can be problematic because you're changing > history. > > Imagine you pull some nice commits from a user. Then at some point you will > have to rebase them before you push them. If this fails and requires manual > interaction, the original version of the commits is lost (including > signatures) and errors are not traceable. > > With a merge instead any manual intervention is clearly located in the merge > commit and the authors of each change are uniquely identifiable. >
So, I've tried to come up with a more detailed approach. Some people mentioned that we maybe shouldn't do rebases at all, because git already does trivial rebases automatically, but I'd try with them first. == commit policy == * atomic commits (one logical change) * commits may span across multiple ebuilds/directories if it's one logical change * every commit on the first parent of the history must be gpg signed by a gentoo dev * repoman must be run from all related directories (or the top-level directory) on the latest commit that is being pushed === commit message format === * all lines max 70-75 chars * first line brief explanation * second line always empty * optional detailed multiline explanation must start at the third line * for commits that affect only a single package, prepend "CATEGORY/PN: " to the first line * for commits that affect only the profile directory, prepend "profiles: " to the first line * for commits that affect only the eclass directory, prepend "ECLASSNAME.eclass: " to the first line * for commits that affect only licenses directory, prepend "licenses: " to the first line * for commits that affect only metadata directory, prepend "metadata: " to the first line == branching model == * the primary production-ready branch is master (users will pull from here), there are no non-fast-forward pushes allowed * there may be developer-specific, task-specific, project-specific branches etc (there are currently no specific rules about them) === when/how to rebase === * in case of a non-fast-forward push conflict to remote master, try 'git pull --rebase=preserve' first, if that yields complicated conflicts, abort the rebase and continue with a regular merge * use --preserve to preserve merges during a rebase (if appropriate, e.g. for user branches) * don't use --preserve if you do an interactive rebase (see BUGS in git-rebase manpage) * commits that are not on the remote master branch yet may be rewritten/squashed/splitted etc via interactive rebase, however the rebase must never span beyond those commits * never rebase on already pushed commits * there are no particular rules for rebasing on non-master remote branches, but be aware that others might base their work on them * there are no particular rules for rebasing non-remote branches, as long as they don't clutter the history when merged back into master * don't do complicated rebases to avoid a merge commit at all cost (it may even cause losing information, e.g. user signatures) === when/how to merge === * if a rebase fails or is too complicated, do a regular merge instead * if the information is useful (e.g. pulled from a foreign remote user branch or merged a non-trivial eclass conversion back into master) force a merge commit (non-fast-forward merge via '--no-ff') * to avoid a merge commit (e.g. information is not useful), you may try to force a fast-forward merge by first rebasing the feature branch (or similar) against master and then merging it into master * extend merge commit messages with useful information, e.g. how conflicts were solved * keep in mind that all commits of the first parent of the history must be gpg signed by a gentoo dev, so you may want to force merge commits especially for user branches == remote model == We have a main developer repo where developers work & commit (every developer has direct push access). For every push into developer repo, automated magic thingie merges stuff into user sync repo and updates the metadata cache there. User sync repo is for power users than want to fetch via git. It's quite fast and efficient for frequent updates, and also saves space by being free of ChangeLogs. On top of user sync repo rsync is propagated. The rsync tree is populated with all old ChangeLogs copied from CVS (stored in 30M git repo), new ChangeLogs are generated from git logs and Manifests are expanded.
