summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/branching-merging-systems.mdwn28
-rw-r--r--morphlib/plugins/branch_and_merge_plugin.py232
-rwxr-xr-xtests.branching/branch-creates-new-system-branch-not-from-master.script18
-rw-r--r--tests.branching/branch-creates-new-system-branch-not-from-master.stdout12
-rwxr-xr-xtests.branching/branch-creates-new-system-branch.script18
-rw-r--r--tests.branching/branch-creates-new-system-branch.stdout10
-rwxr-xr-xtests.branching/branch-when-branchdir-exists-locally.script10
-rwxr-xr-xtests.branching/checkout-existing-branch.script16
-rw-r--r--tests.branching/checkout-existing-branch.stdout10
-rwxr-xr-xtests.branching/checkout-non-aliased-repos.script61
-rw-r--r--tests.branching/checkout-non-aliased-repos.stdout38
-rwxr-xr-xtests.branching/edit-checkouts-existing-chunk.script18
-rwxr-xr-xtests.branching/edit-clones-chunk.script29
-rwxr-xr-xtests.branching/edit-updates-stratum.script13
-rwxr-xr-xtests.branching/edit-uses-ref-from-stratum.script13
-rwxr-xr-xtests.branching/init-cwd.script10
-rwxr-xr-xtests.branching/init-default.script10
-rwxr-xr-xtests.branching/init-existing.script10
-rwxr-xr-xtests.branching/init-newdir.script12
-rw-r--r--tests.branching/init-newdir.stderr1
-rw-r--r--tests.branching/init-newdir.stdout2
-rwxr-xr-xtests.branching/init-nonempty.script10
-rw-r--r--tests.branching/init-nonempty.stderr2
-rwxr-xr-xtests.branching/merge-explicitly-named-repos.script21
-rwxr-xr-xtests.branching/minedir-not-found.script10
-rw-r--r--tests.branching/minedir-not-found.stderr2
-rwxr-xr-xtests.branching/minedir.script14
-rw-r--r--tests.branching/minedir.stdout2
-rwxr-xr-xtests.branching/petrify.script12
-rwxr-xr-xtests.branching/setup11
-rw-r--r--tests.branching/show-system-branch-fails-outside-workspace.exit (renamed from tests.branching/init-newdir.exit)0
-rwxr-xr-xtests.branching/show-system-branch-fails-outside-workspace.script (renamed from tests.branching/show-system-branch-shows-name-correctly.script)22
-rw-r--r--tests.branching/show-system-branch-fails-outside-workspace.stderr1
-rw-r--r--tests.branching/show-system-branch-fails-when-branch-is-ambiguous.exit1
-rwxr-xr-xtests.branching/show-system-branch-fails-when-branch-is-ambiguous.script32
-rw-r--r--tests.branching/show-system-branch-fails-when-branch-is-ambiguous.stderr1
-rw-r--r--tests.branching/show-system-branch-shows-name-correctly.stdout1
-rwxr-xr-xtests.branching/show-system-branch-works-anywhere-with-a-single-branch.script31
-rw-r--r--tests.branching/show-system-branch-works-anywhere-with-a-single-branch.stdout1
-rwxr-xr-xtests.branching/show-system-branch-works-in-different-directories-in-a-branch.script57
-rw-r--r--tests.branching/show-system-branch-works-in-different-directories-in-a-branch.stdout6
-rwxr-xr-xtests.branching/workflow.script21
42 files changed, 572 insertions, 257 deletions
diff --git a/doc/branching-merging-systems.mdwn b/doc/branching-merging-systems.mdwn
index 3daee73b..c2e24d77 100644
--- a/doc/branching-merging-systems.mdwn
+++ b/doc/branching-merging-systems.mdwn
@@ -57,15 +57,15 @@ we introduce the following concepts (FIXME: naming needs attention):
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
+* **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 mine directory
+ inside the morph workspace directory
As a picture:
/home/liw/ -- user's home directory
- baserock/ -- morph mine
+ baserock/ -- morph workspace
.morph/ -- morph shared state, cache, etc
unstable/ -- system branch directory: mainline devel
morphs/ -- git repository for system, stratum morphs
@@ -76,13 +76,13 @@ As a picture:
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
+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 mine directory.
+ 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.)
@@ -105,7 +105,7 @@ 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`
+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,
@@ -197,7 +197,7 @@ Usage:
morph branch BRANCH [COMMIT]
-This needs to be run in the morph mine directory (the one initialized
+This needs to be run in the morph workspace directory (the one initialized
with `morph init`).
* If `./BRANCH` as a directory exists, abort.
@@ -206,7 +206,7 @@ with `morph init`).
* 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`
--------------
@@ -215,7 +215,7 @@ Usage:
morph checkout BRANCH
-This needs to be run in the morph mine directory. It works like
+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.
@@ -289,8 +289,8 @@ 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
+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.)
@@ -303,7 +303,7 @@ Usage:
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 the morph workspace.
* In each git repository modified by the `BRANCH` system branch,
run `git merge --no-commit BRANCH`, then undo any changes to
@@ -318,7 +318,7 @@ Usage:
morph mass-merge BRANCH [TARGET]...
-To be run in the morph mine directory.
+To be run in the morph workspace directory.
This just runs `morph merge BRANCH` in each `TARGET` system branch.
diff --git a/morphlib/plugins/branch_and_merge_plugin.py b/morphlib/plugins/branch_and_merge_plugin.py
index 4eede82c..56f7f44c 100644
--- a/morphlib/plugins/branch_and_merge_plugin.py
+++ b/morphlib/plugins/branch_and_merge_plugin.py
@@ -19,20 +19,19 @@ import os
import json
import glob
import tempfile
+import urlparse
import morphlib
class BranchAndMergePlugin(cliapp.Plugin):
- system_repo_base = 'morphs'
- system_repo_name = 'baserock:%s' % system_repo_base
-
def enable(self):
self.app.add_subcommand('petrify', self.petrify,
arg_synopsis='STRATUM...')
self.app.add_subcommand('init', self.init, arg_synopsis='[DIR]')
- self.app.add_subcommand('minedir', self.minedir, arg_synopsis='')
+ self.app.add_subcommand('workspace', self.workspace,
+ arg_synopsis='')
self.app.add_subcommand('branch', self.branch,
arg_synopsis='NEW [OLD]')
self.app.add_subcommand('checkout', self.checkout,
@@ -48,29 +47,66 @@ class BranchAndMergePlugin(cliapp.Plugin):
pass
@staticmethod
- def deduce_mine_directory():
+ def deduce_workspace():
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
+ raise cliapp.AppException("Can't find the workspace directory")
+
+ @staticmethod
+ def is_system_branch_directory(dirname):
+ return os.path.isdir(os.path.join(dirname, '.morph-system-branch'))
@classmethod
def deduce_system_branch(cls):
- minedir = cls.deduce_mine_directory()
- if minedir is None:
- return None
+ # 1. Deduce the workspace. If this fails, we're not inside a workspace.
+ workspace = cls.deduce_workspace()
+
+ # 2. We're in a workspace. Check if we're inside a system branch.
+ # If we are, return its name.
+ dirname = os.getcwd()
+ while dirname != workspace and dirname != '/':
+ if cls.is_system_branch_directory(dirname):
+ return os.path.relpath(dirname, workspace)
+ dirname = os.path.dirname(dirname)
+
+ # 3. We're in a workspace but not inside a branch. Try to find a
+ # branch directory in the directories below the current working
+ # directory. Avoid ambiguousity by only recursing deeper if there
+ # is only one subdirectory.
+ visited = set()
+ for dirname, subdirs, files in os.walk(os.getcwd(), followlinks=True):
+ # Avoid infinite recursion.
+ if dirname in visited:
+ break
+ visited.add(dirname)
- if not minedir.endswith('/'):
- minedir += '/'
+ if cls.is_system_branch_directory(dirname):
+ return os.path.relpath(dirname, workspace)
- cwd = os.getcwd()
- if not cwd.startswith(minedir):
- return None
+ # Do not recurse deeper if we have more than one
+ # non-hidden directory.
+ if len([x for x in subdirs if not x.startswith('.')]) > 1:
+ break
- return os.path.dirname(cwd[len(minedir):])
+ raise cliapp.AppException("Can't find the system branch directory")
+
+ @staticmethod
+ def write_branch_root(branch_dir, repo):
+ filename = os.path.join(branch_dir, '.morph-system-branch',
+ 'branch-root')
+ with open(filename, 'w') as f:
+ f.write('%s\n' % repo)
+
+ @staticmethod
+ def read_branch_root(branch_dir):
+ filename = os.path.join(branch_dir, '.morph-system-branch',
+ 'branch-root')
+ with open(filename, 'r') as f:
+ return f.read().strip()
@staticmethod
def clone_to_directory(app, dirname, reponame, ref):
@@ -90,6 +126,11 @@ class BranchAndMergePlugin(cliapp.Plugin):
if not app.settings['no-git-update']:
repo.update()
+ # Make sure the parent directories needed for the repo dir exist.
+ parent_dir = os.path.dirname(dirname)
+ if not os.path.exists(parent_dir):
+ os.makedirs(parent_dir)
+
# Clone it from cache to target directory.
repo.checkout(ref, os.path.abspath(dirname))
@@ -181,7 +222,7 @@ class BranchAndMergePlugin(cliapp.Plugin):
self.write_morphology(filename, morph)
def init(self, args):
- '''Initialize a mine.'''
+ '''Initialize a workspace directory.'''
if not args:
args = ['.']
@@ -190,94 +231,121 @@ class BranchAndMergePlugin(cliapp.Plugin):
dirname = args[0]
+ # verify the workspace is empty (and thus, can be used) or
+ # create it if it doesn't exist yet
if os.path.exists(dirname):
if os.listdir(dirname) != []:
raise cliapp.AppException('can only initialize empty '
- 'directory: %s' % dirname)
+ 'directory as a workspace: %s' %
+ dirname)
else:
- raise cliapp.AppException('can only initialize an existing '
- 'empty directory: %s' % dirname)
+ try:
+ os.makedirs(dirname)
+ except:
+ raise cliapp.AppException('failed to create workspace: %s' %
+ dirname)
os.mkdir(os.path.join(dirname, '.morph'))
- self.app.status(msg='Initialized morph mine', chatty=True)
+ self.app.status(msg='Initialized morph workspace', chatty=True)
- def minedir(self, args):
- '''Find morph mine directory from current working directory.'''
+ def workspace(self, args):
+ '''Find morph workspace directory from current working directory.'''
- dirname = self.deduce_mine_directory()
- if dirname is None:
- raise cliapp.AppException("Can't find the mine directory")
- self.app.output.write('%s\n' % dirname)
+ self.app.output.write('%s\n' % self.deduce_workspace())
def branch(self, args):
'''Branch the whole system.'''
- if len(args) not in [1, 2]:
+ if len(args) not in [2, 3]:
raise cliapp.AppException('morph branch needs name of branch '
'as parameter')
- new_branch = args[0]
- commit = 'master' if len(args) == 1 else args[1]
+ repo = args[0]
+ new_branch = args[1]
+ commit = 'master' if len(args) == 2 else args[2]
# Create the system branch directory.
os.makedirs(new_branch)
+ # Create a .morph-system-branch directory to clearly identify
+ # this directory as a morph system branch.
+ os.mkdir(os.path.join(new_branch, '.morph-system-branch'))
+
+ # Remember the repository we branched off from.
+ self.write_branch_root(new_branch, repo)
+
# Clone into system branch directory.
- new_repo = os.path.join(new_branch, self.system_repo_base)
- self.clone_to_directory(self.app, new_repo, self.system_repo_name,
- commit)
+ repo_dir = os.path.join(new_branch, self.convert_uri_to_path(repo))
+ self.clone_to_directory(self.app, repo_dir, repo, commit)
# Create a new branch in the local morphs repository.
self.app.runcmd(['git', 'checkout', '-b', new_branch, commit],
- cwd=new_repo)
+ cwd=repo_dir)
+
+ def convert_uri_to_path(self, uri):
+ parts = urlparse.urlparse(uri)
+
+ # If the URI path is relative, assume it is an aliased repo (e.g.
+ # baserock:morphs). Otherwise assume it is a full URI where we need
+ # to strip off the scheme and .git suffix.
+ if not os.path.isabs(parts.path):
+ return uri
+ else:
+ path = parts.netloc
+ if parts.path.endswith('.git'):
+ path = os.path.join(path, parts.path[1:-len('.git')])
+ else:
+ path = os.path.join(path, parts.path[1:])
+ return path
def checkout(self, args):
'''Check out an existing system branch.'''
- if len(args) != 1:
- raise cliapp.AppException('morph checkout needs name of '
- 'branch as parameter')
+ if len(args) != 2:
+ raise cliapp.AppException('morph checkout needs a repo and the '
+ 'name of a branch as parameters')
- system_branch = args[0]
+ repo = args[0]
+ system_branch = args[1]
# Create the system branch directory.
os.makedirs(system_branch)
- # Clone into system branch directory.
- new_repo = os.path.join(system_branch, self.system_repo_base)
- self.clone_to_directory(self.app, new_repo, self.system_repo_name,
- system_branch)
+ # Create a .morph-system-branch directory to clearly identify
+ # this directory as a morph system branch.
+ os.mkdir(os.path.join(system_branch, '.morph-system-branch'))
- def show_system_branch(self, args):
- '''Print name of current system branch.
+ # Remember the repository we branched off from.
+ self.write_branch_root(system_branch, repo)
- This must be run in the system branch's ``morphs`` repository.
+ # Clone into system branch directory.
+ repo_dir = os.path.join(system_branch, self.convert_uri_to_path(repo))
+ self.clone_to_directory(self.app, repo_dir, repo, system_branch)
- '''
+ def show_system_branch(self, args):
+ '''Print name of current system branch.'''
- system_branch = self.deduce_system_branch()
- if system_branch is None:
- raise cliapp.AppException("Can't determine system branch")
- self.app.output.write('%s\n' % system_branch)
+ self.app.output.write('%s\n' % self.deduce_system_branch())
def merge(self, args):
'''Merge specified repositories from another system branch.'''
- if len(args) == 0:
+ if len(args) < 2:
raise cliapp.AppException('morph merge must get a branch name '
'and some repo names as arguments')
- app = self.app
other_branch = args[0]
- mine = self.deduce_mine_directory()
+ workspace = self.deduce_workspace()
this_branch = self.deduce_system_branch()
for repo in args[1:]:
- repo = self.resolve_reponame(app, repo)
- basename = os.path.basename(repo)
- pull_from = os.path.join(mine, other_branch, basename)
- repo_dir = os.path.join(mine, this_branch, basename)
- app.runcmd(['git', 'pull', pull_from, other_branch], cwd=repo_dir)
+ repo_url = self.resolve_reponame(self.app, repo)
+ repo_path = self.convert_uri_to_path(repo)
+ pull_from = 'file://' + os.path.join(workspace, other_branch,
+ repo_path)
+ repo_dir = os.path.join(workspace, this_branch, repo_path)
+ self.app.runcmd(['git', 'pull', pull_from, other_branch],
+ cwd=repo_dir)
def edit(self, args):
'''Edit a component in a system branch.'''
@@ -286,45 +354,49 @@ class BranchAndMergePlugin(cliapp.Plugin):
raise cliapp.AppException('morph edit must get a repository name '
'and commit ref as argument')
- app = self.app
- mine_directory = self.deduce_mine_directory()
+ workspace = self.deduce_workspace()
system_branch = self.deduce_system_branch()
- if system_branch is None:
- raise morphlib.Error('Cannot deduce system branch')
- morphs_dirname = os.path.join(mine_directory, system_branch, 'morphs')
- if morphs_dirname is None:
- raise morphlib.Error('Can not find morphs directory')
+ # Find out which repository we branched off from.
+ branch_dir = os.path.join(workspace, system_branch)
+ branch_root = self.read_branch_root(branch_dir)
+
+ # Convert it to a local directory in the branch.
+ branch_root_path = self.convert_uri_to_path(branch_root)
+ branch_root_dir = os.path.join(branch_dir, branch_root_path)
- repo = self.resolve_reponame(app, args[0])
+ # Find out which repository to edit.
+ repo, repo_url = args[0], self.resolve_reponame(self.app, args[0])
+ # Find out which ref of the edit repo to check out.
if len(args) == 2:
ref = args[1]
else:
- ref = self.find_edit_ref(app, morphs_dirname, repo)
+ ref = self.find_edit_ref(self.app, branch_root_dir, repo_url)
if ref is None:
raise morphlib.Error('Cannot deduce commit to start edit from')
- new_repo = os.path.join(mine_directory, system_branch,
- os.path.basename(repo))
- self.clone_to_directory(app, new_repo, args[0], ref)
+ # Clone the repository to be edited.
+ repo_dir = os.path.join(branch_dir, self.convert_uri_to_path(repo))
+ self.clone_to_directory(self.app, repo_dir, repo, ref)
if system_branch == ref:
- app.runcmd(['git', 'checkout', system_branch],
- cwd=new_repo)
+ self.app.runcmd(['git', 'checkout', system_branch],
+ cwd=repo_dir)
else:
- app.runcmd(['git', 'checkout', '-b', system_branch, ref],
- cwd=new_repo)
+ self.app.runcmd(['git', 'checkout', '-b', system_branch, ref],
+ cwd=repo_dir)
- for filename, morph in self.morphs_for_repo(app, morphs_dirname, repo):
+ for filename, morph in \
+ self.morphs_for_repo(self.app, branch_root_dir, repo_url):
changed = False
for spec in morph['chunks']:
- spec_repo = self.resolve_reponame(app, spec['repo'])
- if spec_repo == repo and spec['ref'] != system_branch:
- app.status(msg='Replacing ref "%(ref)s" with "%(branch)s"'
- 'in %(filename)s',
- ref=spec['ref'], branch=system_branch,
- filename=filename, chatty=True)
+ spec_repo = self.resolve_reponame(self.app, spec['repo'])
+ if spec_repo == repo_url and spec['ref'] != system_branch:
+ self.app.status(msg='Replacing ref "%(ref)s" with '
+ '"%(branch)s" in %(filename)s',
+ ref=spec['ref'], branch=system_branch,
+ filename=filename, chatty=True)
spec['ref'] = system_branch
changed = True
if changed:
diff --git a/tests.branching/branch-creates-new-system-branch-not-from-master.script b/tests.branching/branch-creates-new-system-branch-not-from-master.script
index 9ab44809..e2883c83 100755
--- a/tests.branching/branch-creates-new-system-branch-not-from-master.script
+++ b/tests.branching/branch-creates-new-system-branch-not-from-master.script
@@ -1,15 +1,15 @@
#!/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.
@@ -18,18 +18,18 @@
set -eu
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch origin/alfred
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch origin/alfred
echo "File tree:"
-"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' |
+"$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
+"$SRCDIR/scripts/run-git-in" newbranch/baserock: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'
+"$SRCDIR/scripts/run-git-in" newbranch/baserock:morphs remote show origin |
+ sed 's,\(TMP/workspace/\.morph/cache/gits/file_\).*_,\1,g'
diff --git a/tests.branching/branch-creates-new-system-branch-not-from-master.stdout b/tests.branching/branch-creates-new-system-branch-not-from-master.stdout
index 7dfffab1..d68a6342 100644
--- a/tests.branching/branch-creates-new-system-branch-not-from-master.stdout
+++ b/tests.branching/branch-creates-new-system-branch-not-from-master.stdout
@@ -6,11 +6,13 @@ 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.morph
-f ./newbranch/morphs/hello-system.morph
-f ./newbranch/morphs/this.is.alfred
+d ./newbranch/.morph-system-branch
+d ./newbranch/baserock:morphs
+d ./newbranch/baserock:morphs/.git
+f ./newbranch/.morph-system-branch/branch-root
+f ./newbranch/baserock:morphs/hello-stratum.morph
+f ./newbranch/baserock:morphs/hello-system.morph
+f ./newbranch/baserock:morphs/this.is.alfred
Current branches:
master
* newbranch
diff --git a/tests.branching/branch-creates-new-system-branch.script b/tests.branching/branch-creates-new-system-branch.script
index 61e9daf4..de1a81ee 100755
--- a/tests.branching/branch-creates-new-system-branch.script
+++ b/tests.branching/branch-creates-new-system-branch.script
@@ -1,15 +1,15 @@
#!/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.
@@ -18,18 +18,18 @@
set -eu
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch
echo "File tree:"
-"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' |
+"$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
+"$SRCDIR/scripts/run-git-in" newbranch/baserock: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'
+"$SRCDIR/scripts/run-git-in" newbranch/baserock:morphs remote show origin |
+ sed 's,\(TMP/workspace/\.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
index d2884b8c..3f2dba1d 100644
--- a/tests.branching/branch-creates-new-system-branch.stdout
+++ b/tests.branching/branch-creates-new-system-branch.stdout
@@ -6,10 +6,12 @@ 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.morph
-f ./newbranch/morphs/hello-system.morph
+d ./newbranch/.morph-system-branch
+d ./newbranch/baserock:morphs
+d ./newbranch/baserock:morphs/.git
+f ./newbranch/.morph-system-branch/branch-root
+f ./newbranch/baserock:morphs/hello-stratum.morph
+f ./newbranch/baserock:morphs/hello-system.morph
Current branches:
master
* newbranch
diff --git a/tests.branching/branch-when-branchdir-exists-locally.script b/tests.branching/branch-when-branchdir-exists-locally.script
index 4692b5f6..a98f6401 100755
--- a/tests.branching/branch-when-branchdir-exists-locally.script
+++ b/tests.branching/branch-when-branchdir-exists-locally.script
@@ -1,15 +1,15 @@
#!/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.
@@ -19,9 +19,9 @@
set -eu
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
mkdir newbranch
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch
diff --git a/tests.branching/checkout-existing-branch.script b/tests.branching/checkout-existing-branch.script
index 74941e18..e7e3a379 100755
--- a/tests.branching/checkout-existing-branch.script
+++ b/tests.branching/checkout-existing-branch.script
@@ -1,33 +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.
+# Verify that "morph checkout baserock:morphs master" works.
set -eu
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" checkout master
+"$SRCDIR/scripts/test-morph" checkout baserock:morphs master
echo "File tree:"
-"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' |
+"$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
+"$SRCDIR/scripts/run-git-in" master/baserock:morphs branch
diff --git a/tests.branching/checkout-existing-branch.stdout b/tests.branching/checkout-existing-branch.stdout
index 7f405fdb..1af2900c 100644
--- a/tests.branching/checkout-existing-branch.stdout
+++ b/tests.branching/checkout-existing-branch.stdout
@@ -6,9 +6,11 @@ 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
-f ./master/morphs/hello-stratum.morph
-f ./master/morphs/hello-system.morph
+d ./master/.morph-system-branch
+d ./master/baserock:morphs
+d ./master/baserock:morphs/.git
+f ./master/.morph-system-branch/branch-root
+f ./master/baserock:morphs/hello-stratum.morph
+f ./master/baserock:morphs/hello-system.morph
Current branches:
* master
diff --git a/tests.branching/checkout-non-aliased-repos.script b/tests.branching/checkout-non-aliased-repos.script
new file mode 100755
index 00000000..6c9ac638
--- /dev/null
+++ b/tests.branching/checkout-non-aliased-repos.script
@@ -0,0 +1,61 @@
+#!/bin/bash
+# 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" works with repos that are not aliased.
+# This test in particular verifies that URI schemes are stripped off
+# and that the .git suffix is only removed at the end if it is actually
+# present.
+
+
+set -eu
+
+
+REPO_WITH_SUFFIX="file://$DATADIR/morphs.git"
+REPO_WITHOUT_SUFFIX="file://$DATADIR/morphs"
+
+TEMP_DIR=$(dirname "$DATADIR")
+
+cd "$DATADIR/workspace"
+
+"$SRCDIR/scripts/test-morph" init
+"$SRCDIR/scripts/test-morph" checkout "$REPO_WITH_SUFFIX" master
+
+echo "File tree of repo with suffix:"
+"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' |
+ sed 's,/cache/gits/file_[^/]*_,/cache/gits/file_,' |
+ sed "s,${DATADIR:1},DATADIR,g" |
+ sed "s,${TEMP_DIR:1},TEMP_DIR,g"
+
+echo "Current branches of repo with suffix:"
+"$SRCDIR/scripts/run-git-in" master/"${DATADIR:1}"/morphs branch
+
+cd "$DATADIR"
+rm -rf "$DATADIR/workspace"
+mkdir "$DATADIR/workspace"
+cd "$DATADIR/workspace"
+
+"$SRCDIR/scripts/test-morph" init
+"$SRCDIR/scripts/test-morph" checkout "$REPO_WITHOUT_SUFFIX" master
+
+echo "File tree of repo without suffix:"
+"$SRCDIR/scripts/list-tree" . | grep -v '/\.git/' |
+ sed 's,/cache/gits/file_[^/]*_,/cache/gits/file_,' |
+ sed "s,${DATADIR:1},DATADIR,g" |
+ sed "s,${TEMP_DIR:1},TEMP_DIR,g"
+
+echo "Current branches of repo without suffix:"
+"$SRCDIR/scripts/run-git-in" master/"${DATADIR:1}"/morphs branch
diff --git a/tests.branching/checkout-non-aliased-repos.stdout b/tests.branching/checkout-non-aliased-repos.stdout
new file mode 100644
index 00000000..872d74aa
--- /dev/null
+++ b/tests.branching/checkout-non-aliased-repos.stdout
@@ -0,0 +1,38 @@
+File tree of repo with suffix:
+d .
+d ./.morph
+d ./.morph/cache
+d ./.morph/cache/gits
+d ./.morph/cache/gits/file_git
+d ./.morph/cache/gits/file_git/.git
+d ./master
+d ./master/.morph-system-branch
+d ./master/tmp
+d ./master/TEMP_DIR
+d ./master/DATADIR
+d ./master/DATADIR/morphs
+d ./master/DATADIR/morphs/.git
+f ./master/.morph-system-branch/branch-root
+f ./master/DATADIR/morphs/hello-stratum.morph
+f ./master/DATADIR/morphs/hello-system.morph
+Current branches of repo with suffix:
+* master
+File tree of repo without suffix:
+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/.morph-system-branch
+d ./master/tmp
+d ./master/TEMP_DIR
+d ./master/DATADIR
+d ./master/DATADIR/morphs
+d ./master/DATADIR/morphs/.git
+f ./master/.morph-system-branch/branch-root
+f ./master/DATADIR/morphs/hello-stratum.morph
+f ./master/DATADIR/morphs/hello-system.morph
+Current branches of repo without suffix:
+* master
diff --git a/tests.branching/edit-checkouts-existing-chunk.script b/tests.branching/edit-checkouts-existing-chunk.script
index 4e88ec7c..1c8e66cd 100755
--- a/tests.branching/edit-checkouts-existing-chunk.script
+++ b/tests.branching/edit-checkouts-existing-chunk.script
@@ -1,15 +1,15 @@
#!/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.
@@ -21,19 +21,19 @@
set -eu
# Checkout the master system branch.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" checkout alfred
+"$SRCDIR/scripts/test-morph" checkout baserock:morphs alfred
# Edit the hello chunk in alfred.
-cd alfred/morphs
+cd alfred/baserock:morphs
"$SRCDIR/scripts/test-morph" edit baserock:hello alfred
echo "Current branches, morphs:"
-"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/alfred/morphs" branch
+"$SRCDIR/scripts/run-git-in" "$DATADIR/workspace/alfred/baserock:morphs" branch
echo "Current branches, hello:"
-"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/alfred/hello" branch
+"$SRCDIR/scripts/run-git-in" "$DATADIR/workspace/alfred/baserock:hello" branch
echo "Files in hello:"
-ls "$DATADIR/mine/alfred/hello"
+ls "$DATADIR/workspace/alfred/baserock:hello"
diff --git a/tests.branching/edit-clones-chunk.script b/tests.branching/edit-clones-chunk.script
index 8b87b4d2..7a3038a3 100755
--- a/tests.branching/edit-clones-chunk.script
+++ b/tests.branching/edit-clones-chunk.script
@@ -1,15 +1,15 @@
#!/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.
@@ -21,24 +21,29 @@
set -eu
# Create system branch.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch
# Edit chunk.
-cd newbranch/morphs
+cd newbranch/baserock:morphs
"$SRCDIR/scripts/test-morph" edit baserock:hello master
echo "Current branches, morphs:"
-"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/newbranch/morphs" branch
+"$SRCDIR/scripts/run-git-in" \
+ "$DATADIR/workspace/newbranch/baserock: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'
+"$SRCDIR/scripts/run-git-in" \
+ "$DATADIR/workspace/newbranch/baserock:morphs" \
+ remote show origin | \
+ sed 's,\(TMP/workspace/\.morph/cache/gits/file_\).*_,\1,g'
echo "Current branches, hello:"
-"$SRCDIR/scripts/run-git-in" "$DATADIR/mine/newbranch/hello" branch
+"$SRCDIR/scripts/run-git-in" \
+ "$DATADIR/workspace/newbranch/baserock: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'
+"$SRCDIR/scripts/run-git-in" "$DATADIR/workspace/newbranch/baserock:hello" \
+ remote show origin | \
+ sed 's,\(TMP/workspace/\.morph/cache/gits/file_\).*_,\1,g'
diff --git a/tests.branching/edit-updates-stratum.script b/tests.branching/edit-updates-stratum.script
index a3e213e5..db819088 100755
--- a/tests.branching/edit-updates-stratum.script
+++ b/tests.branching/edit-updates-stratum.script
@@ -1,15 +1,15 @@
#!/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.
@@ -21,12 +21,13 @@
set -eu
# Create system branch.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch
# Edit chunk.
-cd newbranch/morphs
"$SRCDIR/scripts/test-morph" edit baserock:hello master
+# See what effect the editing had.
+cd newbranch/baserock:morphs
git diff
diff --git a/tests.branching/edit-uses-ref-from-stratum.script b/tests.branching/edit-uses-ref-from-stratum.script
index 74c26d5a..0e4eb915 100755
--- a/tests.branching/edit-uses-ref-from-stratum.script
+++ b/tests.branching/edit-uses-ref-from-stratum.script
@@ -1,15 +1,15 @@
#!/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.
@@ -21,13 +21,12 @@
set -eu
# Create system branch.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch
# Edit chunk.
-cd newbranch/morphs
"$SRCDIR/scripts/test-morph" edit baserock:hello
-cd ../hello
+cd newbranch/baserock:hello
git branch
diff --git a/tests.branching/init-cwd.script b/tests.branching/init-cwd.script
index 91c23506..2d14586c 100755
--- a/tests.branching/init-cwd.script
+++ b/tests.branching/init-cwd.script
@@ -1,15 +1,15 @@
#!/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.
@@ -19,7 +19,7 @@ set -eu
# Test that "morph init" works for the current working directory.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init .
-"$SRCDIR/scripts/list-tree" "$DATADIR/mine"
+"$SRCDIR/scripts/list-tree" "$DATADIR/workspace"
diff --git a/tests.branching/init-default.script b/tests.branching/init-default.script
index 5ec5148d..de4627e7 100755
--- a/tests.branching/init-default.script
+++ b/tests.branching/init-default.script
@@ -1,15 +1,15 @@
#!/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.
@@ -19,6 +19,6 @@ set -eu
# Test that "morph init" works without an explicit argument.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/list-tree" "$DATADIR/mine"
+"$SRCDIR/scripts/list-tree" "$DATADIR/workspace"
diff --git a/tests.branching/init-existing.script b/tests.branching/init-existing.script
index 59b658aa..e713b9df 100755
--- a/tests.branching/init-existing.script
+++ b/tests.branching/init-existing.script
@@ -1,15 +1,15 @@
#!/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.
@@ -20,5 +20,5 @@ 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"
+"$SRCDIR/scripts/test-morph" init "$DATADIR/workspace"
+"$SRCDIR/scripts/list-tree" "$DATADIR/workspace"
diff --git a/tests.branching/init-newdir.script b/tests.branching/init-newdir.script
index 3bb4a1ba..5e79ce87 100755
--- a/tests.branching/init-newdir.script
+++ b/tests.branching/init-newdir.script
@@ -1,15 +1,15 @@
#!/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.
@@ -17,8 +17,8 @@
set -eu
-# Test that "morph init" gives an error when given the name of a
-# directory that does not exist yet.
+# Test that "morph init" works if given a directory that
+# does not exist yet.
"$SRCDIR/scripts/test-morph" init "$DATADIR/foo"
-
+"$SRCDIR/scripts/list-tree" "$DATADIR/foo"
diff --git a/tests.branching/init-newdir.stderr b/tests.branching/init-newdir.stderr
deleted file mode 100644
index 066d69c0..00000000
--- a/tests.branching/init-newdir.stderr
+++ /dev/null
@@ -1 +0,0 @@
-ERROR: can only initialize an existing empty directory: TMP/foo
diff --git a/tests.branching/init-newdir.stdout b/tests.branching/init-newdir.stdout
new file mode 100644
index 00000000..e7922ee1
--- /dev/null
+++ b/tests.branching/init-newdir.stdout
@@ -0,0 +1,2 @@
+d .
+d ./.morph
diff --git a/tests.branching/init-nonempty.script b/tests.branching/init-nonempty.script
index 28762d08..959da028 100755
--- a/tests.branching/init-nonempty.script
+++ b/tests.branching/init-nonempty.script
@@ -1,15 +1,15 @@
#!/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.
@@ -20,5 +20,5 @@ 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"
+touch "$DATADIR/workspace/foo"
+"$SRCDIR/scripts/test-morph" init "$DATADIR/workspace"
diff --git a/tests.branching/init-nonempty.stderr b/tests.branching/init-nonempty.stderr
index 4ed4bba8..bc0ef0e1 100644
--- a/tests.branching/init-nonempty.stderr
+++ b/tests.branching/init-nonempty.stderr
@@ -1 +1 @@
-ERROR: can only initialize empty directory: TMP/mine
+ERROR: can only initialize empty directory as a workspace: TMP/workspace
diff --git a/tests.branching/merge-explicitly-named-repos.script b/tests.branching/merge-explicitly-named-repos.script
index 48705f8a..ad3ef0e6 100755
--- a/tests.branching/merge-explicitly-named-repos.script
+++ b/tests.branching/merge-explicitly-named-repos.script
@@ -1,15 +1,15 @@
#!/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.
@@ -22,27 +22,26 @@ set -eu
# Create system branch.
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs newbranch
# Make a change to a chunk.
-cd newbranch/morphs
"$SRCDIR/scripts/test-morph" edit baserock:hello master
-cd ../hello
+cd newbranch/baserock: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
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" branch baserock:morphs otherbranch
+cd otherbranch
"$SRCDIR/scripts/test-morph" edit baserock:hello master
"$SRCDIR/scripts/test-morph" merge newbranch baserock:hello
# Check results.
-cd ../hello
+cd baserock: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/minedir-not-found.script b/tests.branching/minedir-not-found.script
index eb8c9d51..690f45d3 100755
--- a/tests.branching/minedir-not-found.script
+++ b/tests.branching/minedir-not-found.script
@@ -1,19 +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"
+scripts/test-morph init "$DATADIR/workspace"
cd "$DATADIR"
-"$SRCDIR/scripts/test-morph" minedir
+"$SRCDIR/scripts/test-morph" workspace
diff --git a/tests.branching/minedir-not-found.stderr b/tests.branching/minedir-not-found.stderr
index 46dbd84b..ea9fb165 100644
--- a/tests.branching/minedir-not-found.stderr
+++ b/tests.branching/minedir-not-found.stderr
@@ -1 +1 @@
-ERROR: Can't find the mine directory
+ERROR: Can't find the workspace directory
diff --git a/tests.branching/minedir.script b/tests.branching/minedir.script
index 5f3574b7..f872a37d 100755
--- a/tests.branching/minedir.script
+++ b/tests.branching/minedir.script
@@ -1,20 +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
+scripts/test-morph init "$DATADIR/workspace"
+mkdir -p "$DATADIR/workspace/a/b/c"
+cd "$DATADIR/workspace/a/b/c"
+"$SRCDIR/scripts/test-morph" workspace
diff --git a/tests.branching/minedir.stdout b/tests.branching/minedir.stdout
index 0fc25ee9..14c44f7d 100644
--- a/tests.branching/minedir.stdout
+++ b/tests.branching/minedir.stdout
@@ -1 +1 @@
-TMP/mine
+TMP/workspace
diff --git a/tests.branching/petrify.script b/tests.branching/petrify.script
index 303d7f72..502c8220 100755
--- a/tests.branching/petrify.script
+++ b/tests.branching/petrify.script
@@ -1,15 +1,15 @@
#!/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.
@@ -21,12 +21,12 @@
set -eu
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
"$SRCDIR/scripts/test-morph" update-gits baserock:morphs master \
hello-stratum.morph
-"$SRCDIR/scripts/test-morph" checkout master
+"$SRCDIR/scripts/test-morph" checkout baserock:morphs master
-cd master/morphs
+cd master/baserock:morphs
"$SRCDIR/scripts/test-morph" petrify hello-stratum.morph
cat hello-stratum.morph
diff --git a/tests.branching/setup b/tests.branching/setup
index 126714a0..477dd00a 100755
--- a/tests.branching/setup
+++ b/tests.branching/setup
@@ -18,7 +18,7 @@
# Set up $DATADIR.
#
# - a morph.conf configuration file
-# - an empty morph mine directory
+# - an empty morph workspace directory
# - a git repository called "morphs" for fake system, stratum morphologies
# - a git repository calle "hello" for a dummy chunk
@@ -41,7 +41,7 @@ GIT_COMMITTER_DATE="1343753514 +0000"
cat <<EOF > "$DATADIR/morph.conf"
[config]
repo-alias = baserock=file://$DATADIR/%s#file://$DATADIR/%s
-cachedir = $DATADIR/mine/.morph/cache
+cachedir = $DATADIR/workspace/.morph/cache
log = $DATADIR/morph.log
keep-path = true
no-distcc = true
@@ -49,13 +49,16 @@ quiet = true
EOF
-# Create an empty directory to be used as a morph mine
-mkdir "$DATADIR/mine"
+# Create an empty directory to be used as a morph workspace
+mkdir "$DATADIR/workspace"
# Create a fake morphs repository
mkdir "$DATADIR/morphs"
+## Create a link to this repo that has a .git suffix
+ln -s "$DATADIR/morphs" "$DATADIR/morphs.git"
+
cat <<EOF > "$DATADIR/morphs/hello-system.morph"
{
"name": "hello-system",
diff --git a/tests.branching/init-newdir.exit b/tests.branching/show-system-branch-fails-outside-workspace.exit
index d00491fd..d00491fd 100644
--- a/tests.branching/init-newdir.exit
+++ b/tests.branching/show-system-branch-fails-outside-workspace.exit
diff --git a/tests.branching/show-system-branch-shows-name-correctly.script b/tests.branching/show-system-branch-fails-outside-workspace.script
index 38b2aa14..5cd3bb98 100755
--- a/tests.branching/show-system-branch-shows-name-correctly.script
+++ b/tests.branching/show-system-branch-fails-outside-workspace.script
@@ -1,31 +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.
-# Check that 'morph show-system-branch' shows the name of the current system
-# branch correctly.
+# Check that 'morph show-system-branch' fails when being run
+# outside a workspace.
set -eu
-# Create system branch.
-cd "$DATADIR/mine"
+# Create a workspace and branch.
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch newbranch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs testbranch
-cd newbranch/morphs
-"$SRCDIR/scripts/test-morph" show-system-branch
+# Leave the workspace.
+cd ..
+# Try to show the current branch.
+"$SRCDIR/scripts/test-morph" show-system-branch
diff --git a/tests.branching/show-system-branch-fails-outside-workspace.stderr b/tests.branching/show-system-branch-fails-outside-workspace.stderr
new file mode 100644
index 00000000..ea9fb165
--- /dev/null
+++ b/tests.branching/show-system-branch-fails-outside-workspace.stderr
@@ -0,0 +1 @@
+ERROR: Can't find the workspace directory
diff --git a/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.exit b/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.exit
new file mode 100644
index 00000000..d00491fd
--- /dev/null
+++ b/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.exit
@@ -0,0 +1 @@
+1
diff --git a/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.script b/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.script
new file mode 100755
index 00000000..2383deb9
--- /dev/null
+++ b/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.script
@@ -0,0 +1,32 @@
+#!/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' fails when the system branch
+# is not obvious.
+
+
+set -eu
+
+# Create a workspace and two system branches
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" init
+"$SRCDIR/scripts/test-morph" branch baserock:morphs first/branch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs second/branch
+
+# Try to find out the branch from the workspace directory.
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" show-system-branch
diff --git a/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.stderr b/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.stderr
new file mode 100644
index 00000000..7c784733
--- /dev/null
+++ b/tests.branching/show-system-branch-fails-when-branch-is-ambiguous.stderr
@@ -0,0 +1 @@
+ERROR: Can't find the system branch directory
diff --git a/tests.branching/show-system-branch-shows-name-correctly.stdout b/tests.branching/show-system-branch-shows-name-correctly.stdout
deleted file mode 100644
index 467e4889..00000000
--- a/tests.branching/show-system-branch-shows-name-correctly.stdout
+++ /dev/null
@@ -1 +0,0 @@
-newbranch
diff --git a/tests.branching/show-system-branch-works-anywhere-with-a-single-branch.script b/tests.branching/show-system-branch-works-anywhere-with-a-single-branch.script
new file mode 100755
index 00000000..eb565b91
--- /dev/null
+++ b/tests.branching/show-system-branch-works-anywhere-with-a-single-branch.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' works even outside a branch
+# if there only is one in the workspcae.
+
+
+set -eu
+
+# Create a workspace and a system branch.
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" init
+"$SRCDIR/scripts/test-morph" branch baserock:morphs first/branch
+
+# Show the branch even when outside the branch.
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" show-system-branch
diff --git a/tests.branching/show-system-branch-works-anywhere-with-a-single-branch.stdout b/tests.branching/show-system-branch-works-anywhere-with-a-single-branch.stdout
new file mode 100644
index 00000000..b934ad8e
--- /dev/null
+++ b/tests.branching/show-system-branch-works-anywhere-with-a-single-branch.stdout
@@ -0,0 +1 @@
+first/branch
diff --git a/tests.branching/show-system-branch-works-in-different-directories-in-a-branch.script b/tests.branching/show-system-branch-works-in-different-directories-in-a-branch.script
new file mode 100755
index 00000000..f4abc8ea
--- /dev/null
+++ b/tests.branching/show-system-branch-works-in-different-directories-in-a-branch.script
@@ -0,0 +1,57 @@
+#!/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 from various working directories.
+
+
+set -eu
+
+# Create a workspace and two system branches.
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" init
+"$SRCDIR/scripts/test-morph" branch baserock:morphs first/branch
+"$SRCDIR/scripts/test-morph" branch baserock:morphs second/branch
+
+# Create a few subdirectories in the first branch.
+mkdir -p "$DATADIR/workspace/first/branch/foo"
+mkdir -p "$DATADIR/workspace/first/branch/bar"
+mkdir -p "$DATADIR/workspace/first/branch/foo/bar/baz"
+
+# Show the first branch when partially inside the branch.
+cd "$DATADIR/workspace/first"
+"$SRCDIR/scripts/test-morph" show-system-branch
+
+# Show the first branch when inside the main branch directory.
+cd "$DATADIR/workspace/first/branch"
+"$SRCDIR/scripts/test-morph" show-system-branch
+
+# Show the first branch when somewhere inside the branch.
+cd "$DATADIR/workspace/first/branch/foo"
+"$SRCDIR/scripts/test-morph" show-system-branch
+
+# Show the first branch when somewhere else inside the branch.
+cd "$DATADIR/workspace/first/branch/foo/bar/baz"
+"$SRCDIR/scripts/test-morph" show-system-branch
+
+# Show the second branch when partially inside the branch.
+cd "$DATADIR/workspace/second"
+"$SRCDIR/scripts/test-morph" show-system-branch
+
+# Show the second branch when inside the main branch directory.
+cd "$DATADIR/workspace/second/branch"
+"$SRCDIR/scripts/test-morph" show-system-branch
diff --git a/tests.branching/show-system-branch-works-in-different-directories-in-a-branch.stdout b/tests.branching/show-system-branch-works-in-different-directories-in-a-branch.stdout
new file mode 100644
index 00000000..f9cc3aec
--- /dev/null
+++ b/tests.branching/show-system-branch-works-in-different-directories-in-a-branch.stdout
@@ -0,0 +1,6 @@
+first/branch
+first/branch
+first/branch
+first/branch
+second/branch
+second/branch
diff --git a/tests.branching/workflow.script b/tests.branching/workflow.script
index 6a365d8e..c8ee2187 100755
--- a/tests.branching/workflow.script
+++ b/tests.branching/workflow.script
@@ -1,15 +1,15 @@
#!/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.
@@ -21,19 +21,18 @@
set -eu
-cd "$DATADIR/mine"
+cd "$DATADIR/workspace"
"$SRCDIR/scripts/test-morph" init
-"$SRCDIR/scripts/test-morph" branch me/readme-fix
-cd me/readme-fix/morphs
+"$SRCDIR/scripts/test-morph" branch baserock:morphs me/readme-fix
"$SRCDIR/scripts/test-morph" edit baserock:hello master
-cd ../hello
+cd me/readme-fix/baserock: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
+cd "$DATADIR/workspace"
+"$SRCDIR/scripts/test-morph" checkout baserock:morphs master
+cd master
"$SRCDIR/scripts/test-morph" edit baserock:hello master
-"$SRCDIR/scripts/test-morph" merge me/readme-fix hello
+"$SRCDIR/scripts/test-morph" merge me/readme-fix baserock:hello