summaryrefslogtreecommitdiff
path: root/doc/branching-merging-systems.mdwn
diff options
context:
space:
mode:
Diffstat (limited to 'doc/branching-merging-systems.mdwn')
-rw-r--r--doc/branching-merging-systems.mdwn316
1 files changed, 0 insertions, 316 deletions
diff --git a/doc/branching-merging-systems.mdwn b/doc/branching-merging-systems.mdwn
deleted file mode 100644
index 3bc19aab..00000000
--- a/doc/branching-merging-systems.mdwn
+++ /dev/null
@@ -1,316 +0,0 @@
-Branching and merging at the system level in Baserock
-=====================================================
-
-NOTE: This is a spec. The code does not yet match it.
-
-As I write this, Baserock consists of just under 70 upstream projects,
-each of which we keep in their own git repository. We need a way to
-manage changes to them in a sensible manner, particularly when things
-touch more than one repository. What we need is a way to do branch
-and merge the whole system, across all our git repositories, with
-similar ease and efficiency as what git provides for an individual
-project. Where possible we need to allow the use of raw git so that
-we do not constrain our developers unnecessarily.
-
-There are other things we will want to do across all the Baserock git
-repositories, but that is outside the scope of this document, and will
-be dealt with later.
-
-A couple of use cases:
-
-* I have a problem on a particular device, and want to make changes to
- analyze and fix it. I need to branch the specific version of everything
- that was using the system image version that the device was running.
- I then want to be able to make changes to selected components and build
- the system with those changes. Everything I do not explicitly touch should
- stay at the same version.
-* I am developing Baserock and I want to fix something, or add a new
- feature, or other such change. I want to take the current newest
- version of everything (the mainline development branch, whatever it
- might be named), and make changes to some components, and build and
- test those changes. While I'm doing that, I don't want to get random
- other changes by other people, except when I explicitly ask for them
- (e.g. "git pull" on an individual repository.), to avoid unnecessary
- conflicts and building changes that don't affect my changes.
-
-In both users cases, when I'm done, I want to get my changes into the
-relevant branches. This might happen by merging my changes directly,
-by generating a pull request on a git server, or by generating a patch
-series for each affected repository to be mailed to people who can do
-the merging.
-
-Overview
---------
-
-We want a clear, convenient, and efficient way of working with multiple
-repositories and multiple projects at the same time. To manage this,
-we introduce the following concepts (FIXME: naming needs attention):
-
-* **git repository** is exactly the same as usually with git, as are
- all other concepts related to git
-* **system branch** is a collection of branches in individual git
- repositories that together form a particular line of development of
- the whole system; in other words, given all the git repositories
- that are part of Baserock, system branch `foo` consists of branch
- `foo` in each git repository that has a branch with that name
-* **system branch directory** contains git repositories relevant to
- a system branch; it need not contain all the repositories, just the
- ones that are being worked on by the user, or that the user for
- other reasons have checked out
-* **morph workspace** is where all Morph keeps global
- state and shared caches, so that creating a system branch directory
- is a fairly cheap operation; all the system branch directories are
- inside the morph workspace directory
-
-As a picture:
-
- /home/liw/ -- user's home directory
- baserock/ -- morph workspace
- .morph/ -- morph shared state, cache, etc
- unstable/ -- system branch directory: mainline devel
- morphs/ -- git repository for system, stratum morphs
- magnetic-frobbles/ -- system branch directory: new feature
- morphs/ -- system branch specific changes to morphs
- linux/ -- ditto for linux
-
-To use the system branching and merging, you do the following (which we'll
-cover in more detail later):
-
-1. Initialize the morph workspace. This creates the `.morph` directory and
- populates it with some initial stuff. You can have as many workspaces as
- you want, but you don't have to have more than one, and you only
- need to initialize it once.
-2. Branch the system from some version of it (e.g., `master`) to work
- on a new feature or bug fix.
- This creates a system branch directory under the workspace directory.
- The system branch directory initially contains a clone of the `morphs`
- git repository, with some changes specific to this system branch.
- (See petrification, below.)
-3. Edit one or more components (chunks) in the project. This typically
- requires adding more clones of git repositories inside the system
- branch directory.
-4. Build, test, and fix, repeating as necessary. This requires using
- git directly (not via morph) in the git repositories inside the
- system branch directory.
-5. Merge the changes to relevant target branches. Depending on what the
- change was, it may be necessary ot merge into many branches, e.g.,
- for each stable release branch.
-
-Walkthrough
------------
-
-Let's walk through what happens, making things more concrete. This is
-still fairly high level, and implementation details will come later.
-
- morph init ~/baserock
-
-This creates the `~/baserock` directory if it does not exist, and then
-initializes it as a "morph workspace" directory, by creating a `.morph`
-subdirectory. `.morph` will contain the Morph cache directory, and
-other shared state between the various branches. As part of the cache,
-any git repositories that Morph clones get put into the cache first,
-and cloned into the system branch directories from there (probably
-using hard-linking for speed), so that if there's a need for another
-clone of the repository, it does not need to be cloned from a server
-a second time.
-
- cd ~/baserock
- morph branch liw/foo
- morph branch liw/foo baserock/stable-1.0
- morph branch liw/foo --branch-off-system=/home/liw/system.img
-
-Create a new system branch, and the corresponding system branch
-directory. The three versions shown differ in the starting point
-of the branch: the first one uses the `master` branch in `morphs`,
-the second one uses the named branch instead, and the third one
-gets the SHA-1s from a system image file.
-
-Also, clone the `morphs` git repository inside the system branch
-directory.
-
- cd ~/baserock/liw/foo/morphs
- edit base-system.morph devel-system.morph
- git commit -a
-
-Modify the specified morphologies (or the stratum morphologies they
-refer to) to nail down the references to chunk repositories to use SHA-1s
-instead of branch names or whatever. The changes need to be committed
-to git manually, so that the user has a chance to give a good commit
-message.
-
-Petrification is useful to prevent the set of changes including changes
-by other team members. When a chunk is edited it will be made to refer
-to that ref instead of the SHA-1 that it is petrified to.
-
-Petrification can be done by resolving the chunk references against
-the current state of the git repositories, or it can be done by getting
-the SHA-1s directly from a system image, or a data file.
-
- cd ~/baserock/liw/foo
- morph edit linux
-
-Tell Morph that you want to edit a particular component (chunk).
-This will clone the repository into the system branch directory,
-at the point in history indicated by the morphologies in the
-local version of `morphs`.
-
- cd ~/baserock/liw/foo
- morph git -- log -p master..HEAD
-
-This allows running a git command in each git repository in a
-system branch directory. Morph may offer short forms ("morph status")
-as well, for things that are needed very commonly.
-
- cd ~/baserock/baserock/mainline
- morph merge liw/foo
-
-This merges the changes made in the `liw/foo` branch into the
-`baserock/mainline` branch. The petrification changes are automatically
-undone, since they're not going to be wanted in the merge.
-
- cd ~/baserock
- morph mass-merge liw/foo baserock/stable*
-
-Do the merge from `liw/foo` to every branch matching `baserock/stable*`
-(as expanded by the shell). This is a wrapper around the simpler
-`morph merge` command to make it easier to push a change into many
-branches (e.g., a security fix to all stable branches).
-
-
-Implementation: `morph init`
---------------
-
-Usage:
-
- morph init [DIR]
-
-DIR defaults to the current working directory. If DIR is given,
-but does not exist, it is created.
-
-* Create `DIR/.morph`.
-
-
-Implementation: `morph branch`
---------------
-
-Usage:
-
- morph branch BRANCH [COMMIT]
-
-This needs to be run in the morph workspace directory (the one initialized
-with `morph init`).
-
-* If `./BRANCH` as a directory exists, abort.
-* Create `./BRANCH` directory.
-* Clone the `morphs` repository to `BRANCH/morphs`.
-* Create a new branch called `BRANCH` in morphs, based either the tip of
- `master` or from `COMMIT` if given. Store the SHA-1 of the branch origin
- in some way so we get at it later.
-
-
-Implementation: `morph checkout`
---------------
-
-Usage:
-
- morph checkout BRANCH
-
-This needs to be run in the morph workspace directory. It works like
-`morph branch`, except it does not create the new branch and requires
-it to exist instead.
-
-* If `./BRANCH` as a directory exists, abort.
-* Create `./BRANCH` directory.
-* Clone the `morphs` repository to `BRANCH/morphs`.
-* Run `git checkout BRANCH` in the `morphs` repository.
-
-
-Implementation: `morph edit`
---------------
-
-Usage:
-
- morph edit REPO MORPH...
-
-where `REPO` is a chunk repository (absolute URL or one relative to one of
-the `git-base-url` values). The command must be run in the `morphs`
-directory of the system branch.
-
-* `git clone REPOURL` where the URL is constructed with `git-base-url`
- if necessary.
-* `git branch BRANCH REF` where `BRANCH` is the branch name given to
- `morph branch` and `REF` is the reference to the chunk we want to edit,
- as specified in morphologies.
-* Modify the affected morphologies to refer to the repository using
- the `BRANCH` name, and commit those changes.
-
-If the specified morphology is not a stratum morphology (that is, it is
-a system one), we check all the stratum morphologies mentioned and find
-the one that refers to the specified repository.
-
-Multiple morphologies can be specified. They must have the same original
-reference to the repository. However, they will all be modified.
-
-
-Implementation: `morph git`
---------------
-
-Usage:
-
- morph git -- log -p master..HEAD
-
-This is to be run in the morph workspace. It runs git with the arguments on
-the command line in each local git repository in the workspace. (The `--` is
-only necessary if the git arguments are to contain options.)
-
-
-Implementation: `morph merge`
---------------
-
-Usage:
-
- morph merge BRANCH
-
-This needs to be run inside a system branch directory's `morphs`
-repository, and `BRANCH` must be another system branch checked out
-in the morph workspace.
-
-* In each git repository modified by the `BRANCH` system branch,
- run `git merge --no-commit BRANCH`, then undo any changes to
- stratum morphologies made by `morph edit`, and finally commit
- the changes.
-
-
-Implementation: `morph mass-merge`
---------------
-
-Usage:
-
- morph mass-merge BRANCH [TARGET]...
-
-To be run in the morph workspace directory.
-
-This just runs `morph merge BRANCH` in each `TARGET` system branch.
-
-
-Implementation: `morph cherry-pick`
---------------
-
-Usage:
-
- morph cherry-pick BRANCH [COMMIT]...
- morph cherry-pick BRANCH --since-branch-point
-
-To be run in the system branch directory.
-
-In the first form:
-
-* For each git repository modified by the `BRANCH` system branch,
- run `git cherry-pick COMMIT` for each `COMMIT`.
-
-In the second form:
-
-* For each git repository modified by the `BRANCH` system branch,
- run `git cherry-pick` giving it a list of all commits made after
- the system branch was created.
-