diff options
46 files changed, 1432 insertions, 127 deletions
@@ -21,6 +21,7 @@ set -e python setup.py clean check cmdtest tests +cmdtest tests.branching if [ $(whoami) = root ] && command -v mkfs.btrfs > /dev/null then cmdtest tests.as-root diff --git a/doc/branching-merging-systems.mdwn b/doc/branching-merging-systems.mdwn new file mode 100644 index 00000000..3e781b5a --- /dev/null +++ b/doc/branching-merging-systems.mdwn @@ -0,0 +1,340 @@ +Branching and merging at the system level in Baserock +===================================================== + +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 mine** 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 mine directory + +As a picture: + + /home/liw/ -- user's home directory + baserock/ -- morph mine + .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 mine. This creates the `.morph` directory and + populates it with some initial stuff. You can have as many mines 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 mine 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 mine" 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 + morph petrify 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 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` and the subdirectory `cache` inside it. + + +Implementation: `morph branch` +-------------- + +Usage: + + morph branch BRANCH [COMMIT] + +This needs to be run in the morph mine 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 mine 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 petrify` +-------------- + +Usage: + + morph petrify [MORPH]... + morph petrify --petrify-from-system FILE + +This needs to be run in the `morphs` git repository in a system branch. + +In the first form: + +* read each of the given morphologies; if the morphology is a system one, + follow references to stratum morphologies and process those instead +* in each stratum morphology, replace a reference to a chunk with the + absolute SHA-1: if the original reference was, say, `baserock/morph`, + get the SHA-1 of the current tip commit in that branch and replace + the reference in the morphology + +In the second form: + +* extract the system and stratum morphologies used in the system image file; + these are in a petrified form already +* copy the morphologies to the current working directory, overwriting the + files from git + +In either case, the results need to be committed (with normal git commands) +by the user. + + +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 mine. It runs git with the arguments on +the command line in each local git repository in the mine. (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 mine. + +* 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 mine 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. + @@ -403,6 +403,172 @@ class Morph(cliapp.Application): morphlib.fsutils.undo_device_mapping(ex, paths[name]) factory.remove_staging() + def cmd_init(self, args): + '''Initialize a mine.''' + + if not args: + args = ['.'] + elif len(args) > 1: + raise cliapp.AppException('init must get at most one argument') + + dirname = args[0] + + if os.path.exists(dirname): + if os.listdir(dirname) != []: + raise cliapp.AppException('can only initialize empty ' + 'directory: %s' % dirname) + else: + raise cliapp.AppException('can only initialize an existing ' + 'empty directory: %s' % dirname) + + os.mkdir(os.path.join(dirname, '.morph')) + + def _deduce_mine_directory(self): + dirname = os.getcwd() + while dirname != '/': + dot_morph = os.path.join(dirname, '.morph') + if os.path.isdir(dot_morph): + return dirname + dirname = os.path.dirname(dirname) + return None + + def cmd_minedir(self, args): + '''Find morph mine directory from current working directory.''' + + dirname = self._deduce_mine_directory() + if dirname is None: + raise cliapp.AppException("Can't find the mine directory") + self.output.write('%s\n' % dirname) + + def _clone_to_directory(self, dirname, repo, ref): + '''Clone a repository below a directory. + + As a side effect, clone it into the morph repository. + + ''' + + # Get the repository into the cache. + tempdir = morphlib.tempdir.Tempdir(self.settings['tempdir']) + morph_loader = MorphologyLoader(self.settings) + source_manager = morphlib.sourcemanager.SourceManager(self, + update=not self.settings['no-git-update']) + treeish = source_manager.get_treeish(repo, ref) + + # Clone it from cache to target directory. + morphlib.git.clone(dirname, treeish.repo, self.msg) + + # Set the origin to point at the original repository. + morphlib.git.set_remote(dirname, 'origin', treeish.original_repo) + + # Update remotes. + self.runcmd(['git', 'remote', 'update'], cwd=dirname) + + def cmd_branch(self, args): + '''Branch the whole system.''' + + if len(args) != 1: + raise cliapp.AppException('morph branch needs name of branch ' + 'as parameter') + + new_branch = args[0] + repo = 'morphs' + commit = 'master' + + # Create the system branch directory. + os.makedirs(new_branch) + + # Clone into system branch directory. + new_repo = os.path.join(new_branch, os.path.basename(repo)) + self._clone_to_directory(new_repo, repo, commit) + + # Create a new branch in the local morphs repository. + self.runcmd(['git', 'checkout', '-b', new_branch, commit], + cwd=new_repo) + + def cmd_checkout(self, args): + '''Check out an existing system branch.''' + + if len(args) != 1: + raise cliapp.AppException('morph checkout needs name of ' + 'branch as parameter') + + system_branch = args[0] + repo = 'morphs' + + # Create the system branch directory. + os.makedirs(system_branch) + + # Clone into system branch directory. + new_repo = os.path.join(system_branch, os.path.basename(repo)) + self._clone_to_directory(new_repo, repo, system_branch) + + def _deduce_system_branch(self): + minedir = self._deduce_mine_directory() + if minedir is None: + return None + + if not minedir.endswith('/'): + minedir += '/' + + cwd = os.getcwd() + if not cwd.startswith(minedir): + return None + + return os.path.dirname(cwd[len(minedir):]) + + def cmd_show_system_branch(self, args): + '''Print name of current system branch. + + This must be run in the system branch's ``morphs`` repository. + + ''' + + system_branch = self._deduce_system_branch() + if system_branch is None: + raise cliapp.AppException("Can't determine system branch") + self.output.write('%s\n' % system_branch) + + def cmd_edit(self, args): + '''Edit a component in a system branch.''' + + if len(args) != 2: + raise cliapp.AppException('morph edit must get a repository name ' + 'and commit ref as argument') + + repo = args[0] + ref = args[1] + + mine_directory = self._deduce_mine_directory() + system_branch = self._deduce_system_branch() + new_repo = os.path.join(mine_directory, system_branch, + os.path.basename(repo)) + self._clone_to_directory(new_repo, repo, ref) + + system_branch = self._deduce_system_branch() + if system_branch == ref: + self.runcmd(['git', 'checkout', system_branch], + cwd=new_repo) + else: + self.runcmd(['git', 'checkout', '-b', system_branch, ref], + cwd=new_repo) + + def cmd_merge(self, args): + '''Merge specified repositories from another system branch.''' + + if len(args) == 0: + raise cliapp.AppException('morph merge must get a branch name ' + 'and some repo names as arguments') + + other_branch = args[0] + mine = self._deduce_mine_directory() + this_branch = self._deduce_system_branch() + + for repo in args[1:]: + basename = os.path.basename(repo) + pull_from = os.path.join(mine, other_branch, basename) + repo_dir = os.path.join(mine, this_branch, basename) + self.runcmd(['git', 'pull', pull_from, other_branch], cwd=repo_dir) + def msg(self, msg): '''Show a message to the user about what is going on.''' logging.debug(msg) @@ -429,7 +595,7 @@ class Morph(cliapp.Application): msg('# %s' % ' | '.join(commands)) # run the command line - cliapp.Application.runcmd(self, argv, *args, **kwargs) + return cliapp.Application.runcmd(self, argv, *args, **kwargs) # This is in morph so that policy is easily visible, and not embedded # deep down in the call stack. diff --git a/morphlib/sourcemanager.py b/morphlib/sourcemanager.py index 21c99fa9..2747a2c9 100644 --- a/morphlib/sourcemanager.py +++ b/morphlib/sourcemanager.py @@ -164,6 +164,7 @@ class SourceManager(object): repo_urls = [urlparse.urljoin(fixup_url(x), repo) for x in self.settings['git-base-url']] + orig_url = None cached_repo = None errors = [] @@ -172,6 +173,7 @@ class SourceManager(object): quoted_url = quote_url(repo_url) cached_repo_dirname = os.path.join(self.cache_dir, quoted_url) if os.path.exists(cached_repo_dirname): + orig_url = repo_url cached_repo = cached_repo_dirname break @@ -183,6 +185,7 @@ class SourceManager(object): cached_repo, error = self._cache_repo_from_bundle(server, repo_url) if cached_repo: + orig_url = repo_url break else: errors.append(error) @@ -193,6 +196,7 @@ class SourceManager(object): for repo_url in repo_urls: cached_repo, error = self._cache_repo_from_url(repo_url) if cached_repo: + orig_url = repo_url break else: errors.append(error) @@ -227,7 +231,7 @@ class SourceManager(object): # we should have a cached version of the repo now, return a treeish # for the repo and ref tuple - treeish = morphlib.git.Treeish(cached_repo, repo, ref, self.msg) + treeish = morphlib.git.Treeish(cached_repo, orig_url, ref, self.msg) self.indent_less() return treeish diff --git a/scripts/cmd-filter b/scripts/cmd-filter new file mode 100755 index 00000000..d2f4f784 --- /dev/null +++ b/scripts/cmd-filter @@ -0,0 +1,40 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Wrapper around morph for use by cmdtest tests. This does several things: +# +# * simpler command lines for running morph, so that each test does not +# need to add --no-default-config and other options every time +# * replace temporary filenames ($DATADIR) in the output with a known +# string ("TMP"), so that test output is deterministic + +set -eu + +if "$@" > "$DATADIR/stdout" 2> "$DATADIR/stderr" +then + exit=0 +else + exit=1 +fi + +sed -i "s,$DATADIR,TMP,g" "$DATADIR/stdout" "$DATADIR/stderr" +cat "$DATADIR/stdout" +cat "$DATADIR/stderr" 1>&2 + +rm -f "$DATADIR/stdout" "$DATADIR/stderr" + +exit "$exit" + diff --git a/scripts/list-tree b/scripts/list-tree new file mode 100755 index 00000000..2b3a6aa9 --- /dev/null +++ b/scripts/list-tree @@ -0,0 +1,25 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# List contents of a directory tree in a reproducible manner: only include +# details that we care about, and that won't be changing between test runs +# or test environments. + +set -eu + +export LC_ALL=C +cd "$1" +find -printf '%y %p\n' | sort diff --git a/scripts/run-git-in b/scripts/run-git-in new file mode 100755 index 00000000..80b87d1a --- /dev/null +++ b/scripts/run-git-in @@ -0,0 +1,25 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Run git in a given directory. + + +set -eu + +cd "$1" +shift +"$SRCDIR/scripts/cmd-filter" git "$@" diff --git a/scripts/test-morph b/scripts/test-morph new file mode 100755 index 00000000..3c9e1131 --- /dev/null +++ b/scripts/test-morph @@ -0,0 +1,28 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Wrapper around morph for use by cmdtest tests. This does several things: +# +# * simpler command lines for running morph, so that each test does not +# need to add --no-default-config and other options every time +# * replace temporary filenames ($DATADIR) in the output with a known +# string ("TMP"), so that test output is deterministic + +set -eu + +"$SRCDIR/scripts/cmd-filter" "$SRCDIR/morph" --no-default-config \ + --config="$DATADIR/morph.conf" "$@" + diff --git a/tests.branching/branch-creates-new-system-branch.script b/tests.branching/branch-creates-new-system-branch.script new file mode 100755 index 00000000..61e9daf4 --- /dev/null +++ b/tests.branching/branch-creates-new-system-branch.script @@ -0,0 +1,35 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Make sure "morph branch" creates a new system branch. + +set -eu + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init + +"$SRCDIR/scripts/test-morph" branch newbranch + +echo "File tree:" +"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' | + sed 's,/cache/gits/file_[^/]*_,/cache/gits/file_,' + +echo "Current branches:" +"$SRCDIR/scripts/run-git-in" newbranch/morphs branch + +echo "Current origin:" +"$SRCDIR/scripts/run-git-in" newbranch/morphs remote show origin | + sed 's,\(TMP/mine/\.morph/cache/gits/file_\).*_,\1,g' diff --git a/tests.branching/branch-creates-new-system-branch.stdout b/tests.branching/branch-creates-new-system-branch.stdout new file mode 100644 index 00000000..6a3a9b98 --- /dev/null +++ b/tests.branching/branch-creates-new-system-branch.stdout @@ -0,0 +1,29 @@ +File tree: +d . +d ./.morph +d ./.morph/cache +d ./.morph/cache/gits +d ./.morph/cache/gits/file_morphs +d ./.morph/cache/gits/file_morphs/.git +d ./newbranch +d ./newbranch/morphs +d ./newbranch/morphs/.git +f ./newbranch/morphs/hello-stratum.chunk +f ./newbranch/morphs/hello-system.chunk +Current branches: + master +* newbranch +Current origin: +* remote origin + Fetch URL: file://TMP/morphs + Push URL: file://TMP/morphs + HEAD branch (remote HEAD is ambiguous, may be one of the following): + alfred + master + Remote branches: + alfred tracked + master tracked + Local branch configured for 'git pull': + master merges with remote master + Local ref configured for 'git push': + master pushes to master (up to date) diff --git a/tests.branching/branch-when-branchdir-exists-locally.exit b/tests.branching/branch-when-branchdir-exists-locally.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/branch-when-branchdir-exists-locally.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/branch-when-branchdir-exists-locally.script b/tests.branching/branch-when-branchdir-exists-locally.script new file mode 100755 index 00000000..4692b5f6 --- /dev/null +++ b/tests.branching/branch-when-branchdir-exists-locally.script @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Make sure "morph branch" fails when the system branch directory already +# exists. + +set -eu + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init + +mkdir newbranch +"$SRCDIR/scripts/test-morph" branch newbranch + diff --git a/tests.branching/branch-when-branchdir-exists-locally.stderr b/tests.branching/branch-when-branchdir-exists-locally.stderr new file mode 100644 index 00000000..6c56c250 --- /dev/null +++ b/tests.branching/branch-when-branchdir-exists-locally.stderr @@ -0,0 +1 @@ +ERROR: newbranch: File exists diff --git a/tests.branching/checkout-existing-branch.script b/tests.branching/checkout-existing-branch.script new file mode 100755 index 00000000..74941e18 --- /dev/null +++ b/tests.branching/checkout-existing-branch.script @@ -0,0 +1,33 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Verify that "morph checkout master" works. + + +set -eu + + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" checkout master + +echo "File tree:" +"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' | + sed 's,/cache/gits/file_[^/]*_,/cache/gits/file_,' + +echo "Current branches:" +"$SRCDIR/scripts/run-git-in" master/morphs branch diff --git a/tests.branching/checkout-existing-branch.stdout b/tests.branching/checkout-existing-branch.stdout new file mode 100644 index 00000000..4b29db80 --- /dev/null +++ b/tests.branching/checkout-existing-branch.stdout @@ -0,0 +1,12 @@ +File tree: +d . +d ./.morph +d ./.morph/cache +d ./.morph/cache/gits +d ./.morph/cache/gits/file_morphs +d ./.morph/cache/gits/file_morphs/.git +d ./master +d ./master/morphs +d ./master/morphs/.git +Current branches: +* master diff --git a/tests.branching/edit-checkouts-existing-chunk.script b/tests.branching/edit-checkouts-existing-chunk.script new file mode 100755 index 00000000..583f19e1 --- /dev/null +++ b/tests.branching/edit-checkouts-existing-chunk.script @@ -0,0 +1,39 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Verify that "morph edit" clones a chunk repository into a system branch. + + +set -eu + +# Checkout the master system branch. +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" checkout alfred + +# Edit the hello chunk in alfred. +cd alfred/morphs +"$SRCDIR/scripts/test-morph" edit hello alfred + +echo "Current branches, morphs:" +"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/alfred/morphs" branch + +echo "Current branches, hello:" +"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/alfred/hello" branch + +echo "Files in hello:" +ls "$DATADIR/mine/alfred/hello" diff --git a/tests.branching/edit-checkouts-existing-chunk.stdout b/tests.branching/edit-checkouts-existing-chunk.stdout new file mode 100644 index 00000000..a06832c2 --- /dev/null +++ b/tests.branching/edit-checkouts-existing-chunk.stdout @@ -0,0 +1,7 @@ +Current branches, morphs: +* master +Current branches, hello: +* alfred + master +Files in hello: +hello.chunk diff --git a/tests.branching/edit-clones-chunk.script b/tests.branching/edit-clones-chunk.script new file mode 100755 index 00000000..f6f4e5e8 --- /dev/null +++ b/tests.branching/edit-clones-chunk.script @@ -0,0 +1,44 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Verify that "morph edit" clones a chunk repository into a system branch. + + +set -eu + +# Create system branch. +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch newbranch + +# Edit chunk. +cd newbranch/morphs +"$SRCDIR/scripts/test-morph" edit hello master + +echo "Current branches, morphs:" +"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/newbranch/morphs" branch + +echo "Current origin, morphs:" +"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/newbranch/morphs" \ + remote show origin | sed 's,\(TMP/mine/\.morph/cache/gits/file_\).*_,\1,g' + +echo "Current branches, hello:" +"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/newbranch/hello" branch + +echo "Current origin, hello:" +"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/newbranch/hello" \ + remote show origin | sed 's,\(TMP/mine/\.morph/cache/gits/file_\).*_,\1,g' diff --git a/tests.branching/edit-clones-chunk.stdout b/tests.branching/edit-clones-chunk.stdout new file mode 100644 index 00000000..4bbf909e --- /dev/null +++ b/tests.branching/edit-clones-chunk.stdout @@ -0,0 +1,34 @@ +Current branches, morphs: + master +* newbranch +Current origin, morphs: +* remote origin + Fetch URL: file://TMP/morphs + Push URL: file://TMP/morphs + HEAD branch (remote HEAD is ambiguous, may be one of the following): + alfred + master + Remote branches: + alfred tracked + master tracked + Local branch configured for 'git pull': + master merges with remote master + Local ref configured for 'git push': + master pushes to master (up to date) +Current branches, hello: + master +* newbranch +Current origin, hello: +* remote origin + Fetch URL: file://TMP/hello + Push URL: file://TMP/hello + HEAD branch (remote HEAD is ambiguous, may be one of the following): + alfred + master + Remote branches: + alfred tracked + master tracked + Local branch configured for 'git pull': + master merges with remote master + Local ref configured for 'git push': + master pushes to master (up to date) diff --git a/tests.branching/init-cwd.script b/tests.branching/init-cwd.script new file mode 100755 index 00000000..91c23506 --- /dev/null +++ b/tests.branching/init-cwd.script @@ -0,0 +1,25 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +set -eu + +# Test that "morph init" works for the current working directory. + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init . +"$SRCDIR/scripts/list-tree" "$DATADIR/mine" + diff --git a/tests.branching/init-cwd.stdout b/tests.branching/init-cwd.stdout new file mode 100644 index 00000000..e7922ee1 --- /dev/null +++ b/tests.branching/init-cwd.stdout @@ -0,0 +1,2 @@ +d . +d ./.morph diff --git a/tests.branching/init-default.script b/tests.branching/init-default.script new file mode 100755 index 00000000..5ec5148d --- /dev/null +++ b/tests.branching/init-default.script @@ -0,0 +1,24 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +set -eu + +# Test that "morph init" works without an explicit argument. + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/list-tree" "$DATADIR/mine" diff --git a/tests.branching/init-default.stdout b/tests.branching/init-default.stdout new file mode 100644 index 00000000..e7922ee1 --- /dev/null +++ b/tests.branching/init-default.stdout @@ -0,0 +1,2 @@ +d . +d ./.morph diff --git a/tests.branching/init-existing.script b/tests.branching/init-existing.script new file mode 100755 index 00000000..59b658aa --- /dev/null +++ b/tests.branching/init-existing.script @@ -0,0 +1,24 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +set -eu + +# Test that "morph init" works when given the name of an existing, +# empty directory. + +"$SRCDIR/scripts/test-morph" init "$DATADIR/mine" +"$SRCDIR/scripts/list-tree" "$DATADIR/mine" diff --git a/tests.branching/init-existing.stdout b/tests.branching/init-existing.stdout new file mode 100644 index 00000000..e7922ee1 --- /dev/null +++ b/tests.branching/init-existing.stdout @@ -0,0 +1,2 @@ +d . +d ./.morph diff --git a/tests.branching/init-newdir.exit b/tests.branching/init-newdir.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/init-newdir.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/init-newdir.script b/tests.branching/init-newdir.script new file mode 100755 index 00000000..3bb4a1ba --- /dev/null +++ b/tests.branching/init-newdir.script @@ -0,0 +1,24 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +set -eu + +# Test that "morph init" gives an error when given the name of a +# directory that does not exist yet. + +"$SRCDIR/scripts/test-morph" init "$DATADIR/foo" + diff --git a/tests.branching/init-newdir.stderr b/tests.branching/init-newdir.stderr new file mode 100644 index 00000000..066d69c0 --- /dev/null +++ b/tests.branching/init-newdir.stderr @@ -0,0 +1 @@ +ERROR: can only initialize an existing empty directory: TMP/foo diff --git a/tests.branching/init-nonempty.exit b/tests.branching/init-nonempty.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/init-nonempty.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/init-nonempty.script b/tests.branching/init-nonempty.script new file mode 100755 index 00000000..28762d08 --- /dev/null +++ b/tests.branching/init-nonempty.script @@ -0,0 +1,24 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +set -eu + +# Test that "morph init" fails when given the name of an existing, +# non-empty directory. + +touch "$DATADIR/mine/foo" +"$SRCDIR/scripts/test-morph" init "$DATADIR/mine" diff --git a/tests.branching/init-nonempty.stderr b/tests.branching/init-nonempty.stderr new file mode 100644 index 00000000..4ed4bba8 --- /dev/null +++ b/tests.branching/init-nonempty.stderr @@ -0,0 +1 @@ +ERROR: can only initialize empty directory: TMP/mine diff --git a/tests.branching/merge-explicitly-named-repos.script b/tests.branching/merge-explicitly-named-repos.script new file mode 100755 index 00000000..de6ecebc --- /dev/null +++ b/tests.branching/merge-explicitly-named-repos.script @@ -0,0 +1,48 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Check that "morph merge" merges explicitly named repositories. + + +set -eu + + +# Create system branch. +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch newbranch + +# Make a change to a chunk. +cd newbranch/morphs +"$SRCDIR/scripts/test-morph" edit hello master +cd ../hello +touch newfile.txt +git add newfile.txt +git commit -m foo --quiet + +# Merge changes to a new system branch. +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" branch otherbranch +cd otherbranch/morphs +"$SRCDIR/scripts/test-morph" edit hello master +"$SRCDIR/scripts/test-morph" merge newbranch hello + +# Check results. +cd ../hello +git status --short # make sure all changes are committed +ls newfile.txt # make sure the new file is there + diff --git a/tests.branching/merge-explicitly-named-repos.stdout b/tests.branching/merge-explicitly-named-repos.stdout new file mode 100644 index 00000000..cd2122c4 --- /dev/null +++ b/tests.branching/merge-explicitly-named-repos.stdout @@ -0,0 +1 @@ +newfile.txt diff --git a/tests.branching/minedir-not-found.exit b/tests.branching/minedir-not-found.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/minedir-not-found.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/minedir-not-found.script b/tests.branching/minedir-not-found.script new file mode 100755 index 00000000..eb8c9d51 --- /dev/null +++ b/tests.branching/minedir-not-found.script @@ -0,0 +1,19 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +scripts/test-morph init "$DATADIR/mine" +cd "$DATADIR" +"$SRCDIR/scripts/test-morph" minedir diff --git a/tests.branching/minedir-not-found.stderr b/tests.branching/minedir-not-found.stderr new file mode 100644 index 00000000..46dbd84b --- /dev/null +++ b/tests.branching/minedir-not-found.stderr @@ -0,0 +1 @@ +ERROR: Can't find the mine directory diff --git a/tests.branching/minedir.script b/tests.branching/minedir.script new file mode 100755 index 00000000..5f3574b7 --- /dev/null +++ b/tests.branching/minedir.script @@ -0,0 +1,20 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +scripts/test-morph init "$DATADIR/mine" +mkdir -p "$DATADIR/mine/a/b/c" +cd "$DATADIR/mine/a/b/c" +"$SRCDIR/scripts/test-morph" minedir diff --git a/tests.branching/minedir.stdout b/tests.branching/minedir.stdout new file mode 100644 index 00000000..0fc25ee9 --- /dev/null +++ b/tests.branching/minedir.stdout @@ -0,0 +1 @@ +TMP/mine diff --git a/tests.branching/setup b/tests.branching/setup new file mode 100755 index 00000000..68117fa3 --- /dev/null +++ b/tests.branching/setup @@ -0,0 +1,99 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Set up $DATADIR. +# +# - a morph.conf configuration file +# - an empty morph mine directory +# - a git repository called "morphs" for fake system, stratum morphologies +# - a git repository calle "hello" for a dummy chunk + +set -eu + + +# Create a morph configuration file +cat <<EOF > "$DATADIR/morph.conf" +[config] +git-base-url = file://$DATADIR/ +cachedir = $DATADIR/mine/.morph/cache +log = $DATADIR/morph.log +keep-path = true +no-distcc = true +EOF + + +# Create an empty directory to be used as a morph mine +mkdir "$DATADIR/mine" + + +# Create a fake morphs repository +mkdir "$DATADIR/morphs" + +cat <<EOF > "$DATADIR/morphs/hello-system.chunk" +{ + "name": "hello-system", + "kind": "system", + "disk-size": "1G", + "strata": [ + "hello-stratum" + ] +} +EOF + +cat <<EOF > "$DATADIR/morphs/hello-stratum.chunk" +{ + "name": "hello-stratum", + "kind": "stratum", + "sources": [ + { + "name": "hello", + "ref": "master" + } + ] +} +EOF + +scripts/run-git-in "$DATADIR/morphs" init +scripts/run-git-in "$DATADIR/morphs" add . +scripts/run-git-in "$DATADIR/morphs" commit -m initial + + +# Add an extra branch to the morphs repo. +scripts/run-git-in "$DATADIR/morphs" checkout -b alfred +scripts/run-git-in "$DATADIR/morphs" checkout master + + +# Create a dummy chunk repository +mkdir "$DATADIR/hello" + +cat <<EOF > "$DATADIR/hello/hello.chunk" +{ + "name": "hello", + "kind": "chunk", + "build-system": "dummy" +} +EOF + +scripts/run-git-in "$DATADIR/hello" init +scripts/run-git-in "$DATADIR/hello" add . +scripts/run-git-in "$DATADIR/hello" commit -m initial + + +# Add an extra branch to the hello repo. +scripts/run-git-in "$DATADIR/hello" checkout -b alfred +scripts/run-git-in "$DATADIR/hello" checkout master + diff --git a/tests.branching/show-system-branch-shows-name-correctly.script b/tests.branching/show-system-branch-shows-name-correctly.script new file mode 100755 index 00000000..38b2aa14 --- /dev/null +++ b/tests.branching/show-system-branch-shows-name-correctly.script @@ -0,0 +1,31 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Check that 'morph show-system-branch' shows the name of the current system +# branch correctly. + + +set -eu + +# Create system branch. +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch newbranch + +cd newbranch/morphs +"$SRCDIR/scripts/test-morph" show-system-branch + diff --git a/tests.branching/show-system-branch-shows-name-correctly.stdout b/tests.branching/show-system-branch-shows-name-correctly.stdout new file mode 100644 index 00000000..467e4889 --- /dev/null +++ b/tests.branching/show-system-branch-shows-name-correctly.stdout @@ -0,0 +1 @@ +newbranch diff --git a/tests.branching/teardown b/tests.branching/teardown new file mode 100755 index 00000000..94928416 --- /dev/null +++ b/tests.branching/teardown @@ -0,0 +1,22 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Clean up $DATADIR. + +set -eu + +find "$DATADIR" -mindepth 1 -delete diff --git a/tests.branching/workflow.script b/tests.branching/workflow.script new file mode 100755 index 00000000..d2ce374f --- /dev/null +++ b/tests.branching/workflow.script @@ -0,0 +1,39 @@ +#!/bin/sh +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +# Do a complete workflow test with Morph branching and merging. + + +set -eu + + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch me/readme-fix +cd me/readme-fix/morphs +"$SRCDIR/scripts/test-morph" edit hello master +cd ../hello +echo > README yoyoyo +git add README +git commit -m "Fix README, yo!" --quiet + +cd "$DATADIR/mine" +"$SRCDIR/scripts/test-morph" checkout master +cd master/morphs +"$SRCDIR/scripts/test-morph" edit hello master +"$SRCDIR/scripts/test-morph" merge me/readme-fix hello + diff --git a/tests/missing-ref.stderr b/tests/missing-ref.stderr index 5a1ffb2a..748a891c 100644 --- a/tests/missing-ref.stderr +++ b/tests/missing-ref.stderr @@ -1 +1 @@ -ERROR: non-existent-branch is an invalid reference for repo chunk-repo +ERROR: non-existent-branch is an invalid reference for repo file:///chunk-repo diff --git a/tests/show-dependencies.script b/tests/show-dependencies.script index 78fb186b..4b28078f 100755 --- a/tests/show-dependencies.script +++ b/tests/show-dependencies.script @@ -20,5 +20,5 @@ set -eu -tests/morph show-dependencies test-repo master xfce-core.morph - +tests/morph show-dependencies test-repo master xfce-core.morph | \ + sed "s,$DATADIR,TMP,g" diff --git a/tests/show-dependencies.stdout b/tests/show-dependencies.stdout index 5ad63c65..94ae5749 100644 --- a/tests/show-dependencies.stdout +++ b/tests/show-dependencies.stdout @@ -1,133 +1,133 @@ dependency tree: - test-repo|refs/remotes/origin/master|cairo.morph - test-repo|refs/remotes/origin/master|dbus-glib.morph - -> test-repo|refs/remotes/origin/master|dbus.morph - -> test-repo|refs/remotes/origin/master|glib.morph - test-repo|refs/remotes/origin/master|dbus.morph - test-repo|refs/remotes/origin/master|exo.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4util.morph - test-repo|refs/remotes/origin/master|fontconfig.morph - test-repo|refs/remotes/origin/master|freetype.morph - test-repo|refs/remotes/origin/master|garcon.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4util.morph - test-repo|refs/remotes/origin/master|gdk-pixbuf.morph - -> test-repo|refs/remotes/origin/master|glib.morph - test-repo|refs/remotes/origin/master|glib.morph - test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|cairo.morph - -> test-repo|refs/remotes/origin/master|dbus-glib.morph - -> test-repo|refs/remotes/origin/master|dbus.morph - -> test-repo|refs/remotes/origin/master|fontconfig.morph - -> test-repo|refs/remotes/origin/master|freetype.morph - -> test-repo|refs/remotes/origin/master|gdk-pixbuf.morph - -> test-repo|refs/remotes/origin/master|glib.morph - -> test-repo|refs/remotes/origin/master|gtk.morph - -> test-repo|refs/remotes/origin/master|pango.morph - test-repo|refs/remotes/origin/master|gtk-xfce-engine.morph - -> test-repo|refs/remotes/origin/master|garcon.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - test-repo|refs/remotes/origin/master|gtk.morph - -> test-repo|refs/remotes/origin/master|cairo.morph - -> test-repo|refs/remotes/origin/master|gdk-pixbuf.morph - -> test-repo|refs/remotes/origin/master|glib.morph - -> test-repo|refs/remotes/origin/master|pango.morph - test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - test-repo|refs/remotes/origin/master|libxfce4util.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - test-repo|refs/remotes/origin/master|pango.morph - -> test-repo|refs/remotes/origin/master|fontconfig.morph - -> test-repo|refs/remotes/origin/master|freetype.morph - test-repo|refs/remotes/origin/master|thunar.morph - -> test-repo|refs/remotes/origin/master|exo.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - test-repo|refs/remotes/origin/master|tumbler.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - test-repo|refs/remotes/origin/master|xfce-core.morph - -> test-repo|refs/remotes/origin/master|exo.morph - -> test-repo|refs/remotes/origin/master|garcon.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|gtk-xfce-engine.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|libxfce4util.morph - -> test-repo|refs/remotes/origin/master|thunar.morph - -> test-repo|refs/remotes/origin/master|tumbler.morph - -> test-repo|refs/remotes/origin/master|xfce4-appfinder.morph - -> test-repo|refs/remotes/origin/master|xfce4-panel.morph - -> test-repo|refs/remotes/origin/master|xfce4-session.morph - -> test-repo|refs/remotes/origin/master|xfce4-settings.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - -> test-repo|refs/remotes/origin/master|xfdesktop.morph - -> test-repo|refs/remotes/origin/master|xfwm4.morph - test-repo|refs/remotes/origin/master|xfce4-appfinder.morph - -> test-repo|refs/remotes/origin/master|garcon.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - test-repo|refs/remotes/origin/master|xfce4-panel.morph - -> test-repo|refs/remotes/origin/master|exo.morph - -> test-repo|refs/remotes/origin/master|garcon.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - test-repo|refs/remotes/origin/master|xfce4-session.morph - -> test-repo|refs/remotes/origin/master|exo.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - test-repo|refs/remotes/origin/master|xfce4-settings.morph - -> test-repo|refs/remotes/origin/master|exo.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - test-repo|refs/remotes/origin/master|xfconf.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4util.morph - test-repo|refs/remotes/origin/master|xfdesktop.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph - test-repo|refs/remotes/origin/master|xfwm4.morph - -> test-repo|refs/remotes/origin/master|gtk-stack.morph - -> test-repo|refs/remotes/origin/master|libxfce4ui.morph - -> test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|cairo.morph + file://TMP/test-repo|refs/remotes/origin/master|dbus-glib.morph + -> file://TMP/test-repo|refs/remotes/origin/master|dbus.morph + -> file://TMP/test-repo|refs/remotes/origin/master|glib.morph + file://TMP/test-repo|refs/remotes/origin/master|dbus.morph + file://TMP/test-repo|refs/remotes/origin/master|exo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4util.morph + file://TMP/test-repo|refs/remotes/origin/master|fontconfig.morph + file://TMP/test-repo|refs/remotes/origin/master|freetype.morph + file://TMP/test-repo|refs/remotes/origin/master|garcon.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4util.morph + file://TMP/test-repo|refs/remotes/origin/master|gdk-pixbuf.morph + -> file://TMP/test-repo|refs/remotes/origin/master|glib.morph + file://TMP/test-repo|refs/remotes/origin/master|glib.morph + file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|cairo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|dbus-glib.morph + -> file://TMP/test-repo|refs/remotes/origin/master|dbus.morph + -> file://TMP/test-repo|refs/remotes/origin/master|fontconfig.morph + -> file://TMP/test-repo|refs/remotes/origin/master|freetype.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gdk-pixbuf.morph + -> file://TMP/test-repo|refs/remotes/origin/master|glib.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk.morph + -> file://TMP/test-repo|refs/remotes/origin/master|pango.morph + file://TMP/test-repo|refs/remotes/origin/master|gtk-xfce-engine.morph + -> file://TMP/test-repo|refs/remotes/origin/master|garcon.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|gtk.morph + -> file://TMP/test-repo|refs/remotes/origin/master|cairo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gdk-pixbuf.morph + -> file://TMP/test-repo|refs/remotes/origin/master|glib.morph + -> file://TMP/test-repo|refs/remotes/origin/master|pango.morph + file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|libxfce4util.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + file://TMP/test-repo|refs/remotes/origin/master|pango.morph + -> file://TMP/test-repo|refs/remotes/origin/master|fontconfig.morph + -> file://TMP/test-repo|refs/remotes/origin/master|freetype.morph + file://TMP/test-repo|refs/remotes/origin/master|thunar.morph + -> file://TMP/test-repo|refs/remotes/origin/master|exo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + file://TMP/test-repo|refs/remotes/origin/master|tumbler.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce-core.morph + -> file://TMP/test-repo|refs/remotes/origin/master|exo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|garcon.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-xfce-engine.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4util.morph + -> file://TMP/test-repo|refs/remotes/origin/master|thunar.morph + -> file://TMP/test-repo|refs/remotes/origin/master|tumbler.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfce4-appfinder.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfce4-panel.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfce4-session.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfce4-settings.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfdesktop.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfwm4.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-appfinder.morph + -> file://TMP/test-repo|refs/remotes/origin/master|garcon.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-panel.morph + -> file://TMP/test-repo|refs/remotes/origin/master|exo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|garcon.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-session.morph + -> file://TMP/test-repo|refs/remotes/origin/master|exo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-settings.morph + -> file://TMP/test-repo|refs/remotes/origin/master|exo.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4util.morph + file://TMP/test-repo|refs/remotes/origin/master|xfdesktop.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|xfwm4.morph + -> file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph + -> file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph + -> file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph build order: group: - test-repo|refs/remotes/origin/master|cairo.morph - test-repo|refs/remotes/origin/master|dbus.morph - test-repo|refs/remotes/origin/master|fontconfig.morph - test-repo|refs/remotes/origin/master|freetype.morph - test-repo|refs/remotes/origin/master|glib.morph + file://TMP/test-repo|refs/remotes/origin/master|cairo.morph + file://TMP/test-repo|refs/remotes/origin/master|dbus.morph + file://TMP/test-repo|refs/remotes/origin/master|fontconfig.morph + file://TMP/test-repo|refs/remotes/origin/master|freetype.morph + file://TMP/test-repo|refs/remotes/origin/master|glib.morph group: - test-repo|refs/remotes/origin/master|dbus-glib.morph - test-repo|refs/remotes/origin/master|gdk-pixbuf.morph - test-repo|refs/remotes/origin/master|pango.morph + file://TMP/test-repo|refs/remotes/origin/master|dbus-glib.morph + file://TMP/test-repo|refs/remotes/origin/master|gdk-pixbuf.morph + file://TMP/test-repo|refs/remotes/origin/master|pango.morph group: - test-repo|refs/remotes/origin/master|gtk.morph + file://TMP/test-repo|refs/remotes/origin/master|gtk.morph group: - test-repo|refs/remotes/origin/master|gtk-stack.morph + file://TMP/test-repo|refs/remotes/origin/master|gtk-stack.morph group: - test-repo|refs/remotes/origin/master|libxfce4util.morph - test-repo|refs/remotes/origin/master|tumbler.morph + file://TMP/test-repo|refs/remotes/origin/master|libxfce4util.morph + file://TMP/test-repo|refs/remotes/origin/master|tumbler.morph group: - test-repo|refs/remotes/origin/master|exo.morph - test-repo|refs/remotes/origin/master|garcon.morph - test-repo|refs/remotes/origin/master|xfconf.morph + file://TMP/test-repo|refs/remotes/origin/master|exo.morph + file://TMP/test-repo|refs/remotes/origin/master|garcon.morph + file://TMP/test-repo|refs/remotes/origin/master|xfconf.morph group: - test-repo|refs/remotes/origin/master|libxfce4ui.morph + file://TMP/test-repo|refs/remotes/origin/master|libxfce4ui.morph group: - test-repo|refs/remotes/origin/master|gtk-xfce-engine.morph - test-repo|refs/remotes/origin/master|thunar.morph - test-repo|refs/remotes/origin/master|xfce4-appfinder.morph - test-repo|refs/remotes/origin/master|xfce4-panel.morph - test-repo|refs/remotes/origin/master|xfce4-session.morph - test-repo|refs/remotes/origin/master|xfce4-settings.morph - test-repo|refs/remotes/origin/master|xfdesktop.morph - test-repo|refs/remotes/origin/master|xfwm4.morph + file://TMP/test-repo|refs/remotes/origin/master|gtk-xfce-engine.morph + file://TMP/test-repo|refs/remotes/origin/master|thunar.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-appfinder.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-panel.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-session.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce4-settings.morph + file://TMP/test-repo|refs/remotes/origin/master|xfdesktop.morph + file://TMP/test-repo|refs/remotes/origin/master|xfwm4.morph group: - test-repo|refs/remotes/origin/master|xfce-core.morph + file://TMP/test-repo|refs/remotes/origin/master|xfce-core.morph |