diff options
author | Richard Maw <richard.maw@codethink.co.uk> | 2012-09-17 12:58:23 +0000 |
---|---|---|
committer | Richard Maw <richard.maw@codethink.co.uk> | 2012-09-17 12:58:23 +0000 |
commit | debcb7429328880231a7659be5c71f322a78c235 (patch) | |
tree | 01e5e4fb7626fa100aabff657afa5ae80659cc8c | |
parent | ce118d0f5dbf1ca62fd0660a4a12283e9bd7c49e (diff) | |
parent | 8ed384ddee061e173b06949977a02b59ad6e1ea1 (diff) | |
download | morph-debcb7429328880231a7659be5c71f322a78c235.tar.gz |
Merge branch 'samthursfield/complex-merges-2' of git://roadtrain.codethink.co.uk/baserock/morph
-rw-r--r-- | morphlib/git.py | 11 | ||||
-rw-r--r-- | morphlib/plugins/branch_and_merge_plugin.py | 185 | ||||
-rw-r--r-- | tests.branching/merge-handles-unmergable-cases.exit | 1 | ||||
-rwxr-xr-x | tests.branching/merge-handles-unmergable-cases.script | 30 | ||||
-rw-r--r-- | tests.branching/merge-handles-unmergable-cases.stderr | 1 | ||||
-rwxr-xr-x | tests.branching/merge-not-to-master.script | 69 | ||||
-rwxr-xr-x | tests.branching/merge-with-chunk-renamed.script | 56 | ||||
-rw-r--r-- | tests.branching/merge-with-chunk-repo-moved.exit | 1 | ||||
-rwxr-xr-x | tests.branching/merge-with-chunk-repo-moved.script | 53 | ||||
-rw-r--r-- | tests.branching/merge-with-chunk-repo-moved.stderr | 1 | ||||
-rw-r--r-- | tests.branching/merge-with-stratum-renamed.exit | 1 | ||||
-rwxr-xr-x | tests.branching/merge-with-stratum-renamed.script | 51 | ||||
-rw-r--r-- | tests.branching/merge-with-stratum-renamed.stderr | 1 | ||||
-rwxr-xr-x | tests.branching/merge.script | 2 | ||||
-rw-r--r-- | tests.branching/merge.stdout | 2 | ||||
-rwxr-xr-x | tests.branching/workflow-separate-stratum-repos.script | 48 |
16 files changed, 444 insertions, 69 deletions
diff --git a/morphlib/git.py b/morphlib/git.py index 9ab98ad0..5862ef9b 100644 --- a/morphlib/git.py +++ b/morphlib/git.py @@ -196,6 +196,17 @@ def checkout_ref(runcmd, gitdir, ref): '''Checks out a specific ref/SHA1 in a git working tree.''' runcmd(['git', 'checkout', ref], cwd=gitdir) + +def index_has_changes(runcmd, gitdir): + '''Returns True if there are no staged changes to commit''' + try: + runcmd(['git', 'diff-index', '--cached', '--quiet', + '--ignore-submodules', 'HEAD'], cwd=gitdir) + except cliapp.AppException: + return True + return False + + def reset_workdir(runcmd, gitdir): '''Removes any differences between the current commit ''' '''and the status of the working directory''' diff --git a/morphlib/plugins/branch_and_merge_plugin.py b/morphlib/plugins/branch_and_merge_plugin.py index 82d83a58..75935b72 100644 --- a/morphlib/plugins/branch_and_merge_plugin.py +++ b/morphlib/plugins/branch_and_merge_plugin.py @@ -475,27 +475,34 @@ class BranchAndMergePlugin(cliapp.Plugin): branch_root = self.get_branch_config(branch_dir, 'branch.root') self.app.output.write('%s\n' % branch_root) - def make_repository_available(self, system_branch, branch_dir, repo, ref): - existing_repo = self.find_repository(branch_dir, repo) - if existing_repo: - # Reuse the existing clone and its system branch. - self.app.runcmd(['git', 'checkout', system_branch], - cwd=existing_repo) - return existing_repo - else: - # Clone repo and create the system branch in the cloned repo. + def checkout_repository(self, branch_dir, repo, ref, parent_ref=None): + '''Make a chunk or stratum repository available for a system branch + + We ensure the 'system_branch' ref within 'repo' is checked out, + creating it from 'parent_ref' if required. + + The function aims for permissiveness, so users can try to fix any + weirdness they have caused in the repos with another call to 'morph + edit'. + + ''' + + parent_ref = parent_ref or ref + + repo_dir = self.find_repository(branch_dir, repo) + if repo_dir is None: repo_url = self.resolve_reponame(repo) repo_dir = os.path.join(branch_dir, self.convert_uri_to_path(repo)) - self.clone_to_directory(repo_dir, repo, ref) - try: - self.log_change(repo, 'branch "%s" created from "%s"' % - (system_branch, ref)) - self.app.runcmd(['git', 'checkout', '-b', system_branch], - cwd=repo_dir) - except: - self.app.runcmd(['git', 'checkout', system_branch], - cwd=repo_dir) - return repo_dir + self.clone_to_directory(repo_dir, repo, parent_ref) + + if self.resolve_ref(repo_dir, ref) is None: + self.log_change(repo, 'branch "%s" created from "%s"' % + (ref, parent_ref)) + self.app.runcmd(['git', 'checkout', '-b', ref], cwd=repo_dir) + else: + # git copes even if the system_branch ref is already checked out + self.app.runcmd(['git', 'checkout', ref], cwd=repo_dir) + return repo_dir def edit(self, args): '''Edit a component in a system branch.''' @@ -523,8 +530,9 @@ class BranchAndMergePlugin(cliapp.Plugin): stratum_name, collection='strata') # Make the stratum repository and the ref available locally. - stratum_repo_dir = self.make_repository_available( - system_branch, branch_dir, stratum['repo'], stratum['ref']) + stratum_repo_dir = self.checkout_repository( + branch_dir, stratum['repo'], system_branch, + parent_ref=stratum['ref']) # Check if we need to change anything at all. if stratum['ref'] != system_branch: @@ -560,8 +568,9 @@ class BranchAndMergePlugin(cliapp.Plugin): chunk_name, collection='chunks') # Make the chunk repository and the ref available locally. - chunk_repo_dir = self.make_repository_available( - system_branch, branch_dir, chunk['repo'], chunk['ref']) + chunk_repo_dir = self.checkout_repository( + branch_dir, chunk['repo'], system_branch, + parent_ref=chunk['ref']) # Check if we need to update anything at all. if chunk['ref'] != system_branch: @@ -577,13 +586,38 @@ class BranchAndMergePlugin(cliapp.Plugin): self.print_changelog('The following changes were made but have not ' 'been comitted') + def load_morphology_pair(self, repo_dir, ref, name): + '''Load two versions of a morphology and check for major conflicts + + Returns the version at 'ref' (if it exists) and the on-disk version. + + ''' + + new = self.load_morphology(repo_dir, name) + try: + old = self.load_morphology(repo_dir, name, ref=ref) + except cliapp.AppException as e: + return None, new + + if old['name'] != new['name']: + # We should enforce this in validation during load_morphology() + # rather than having to check it here + raise cliapp.AppException( + 'merge confict: "name" of morphology %s (name should ' + 'always match filename)' % name) + if old['kind'] != new['kind']: + raise cliapp.AppException( + 'merge conflict: "kind" of morphology %s' % name) + + return old, new + def merge_repo(self, name, from_dir, from_branch, to_dir, to_branch, commit = False): '''Merge changes for a system branch in a specific repository''' if self.get_uncommitted_changes(from_dir) != []: raise cliapp.AppException('repository %s has uncommitted ' - 'changes', name) + 'changes' % from_dir) # repo must be made into a URL to avoid ':' in pathnames confusing git from_url = urlparse.urljoin('file://', from_dir) self.app.runcmd(['git', 'pull', '--no-commit', '--no-ff', from_url, @@ -615,54 +649,87 @@ class BranchAndMergePlugin(cliapp.Plugin): 'repository : %s vs %s' % (root_repo, other_root_repo)) - def _merge_chunk(ci): - from_repo = self.find_repository(from_branch_dir, ci['repo']) - to_repo = self.make_repository_available( - to_branch, to_branch_dir, ci['repo'], to_branch) + def merge_chunk(old_ci, ci): + from_repo = self.find_repository(from_branch_dir, old_ci['repo']) + to_repo = self.checkout_repository( + to_branch_dir, ci['repo'], ci['ref']) self.merge_repo(ci['repo'], from_repo, from_branch, - to_repo, to_branch, commit=True) + to_repo, ci['ref'], commit=True) - def _merge_stratum(si): - if si['repo'] == root_repo: - to_repo = to_root_dir - else: - from_repo = self.find_repository(from_branch_dir, si['repo']) - to_repo = self.make_repository_available( - to_branch, to_branch_dir, si['repo'], to_branch) - # We will do a merge commit in this repo later on - self.merge_repo(si['repo'], from_repo, from_branch, - to_repo, to_branch, commit=False) - morphs_repo_list.add(to_repo) + def merge_stratum(old_si, si): + from_repo = self.find_repository(from_branch_dir, old_si['repo']) + to_repo = self.checkout_repository( + to_branch_dir, si['repo'], si['ref']) - stratum = self.load_morphology(to_repo, si['morph']) - for ci in stratum['chunks']: - if ci['ref'] == from_branch: - _merge_chunk(ci) - ci['ref'] = to_branch - self.save_morphology(to_repo, si['morph'], stratum) + if to_repo not in dirty_repos: + self.merge_repo(si['repo'], from_repo, from_branch, + to_repo, si['ref'], commit=False) + dirty_repos.add(to_repo) + old_stratum, stratum = self.load_morphology_pair( + to_repo, old_si['ref'], si['morph']) + + changed = False + edited_chunks = [ci for ci in stratum['chunks'] + if ci['ref'] == from_branch] + for ci in edited_chunks: + for old_ci in old_stratum['chunks']: + if old_ci['repo'] == ci['repo']: + break + else: + raise cliapp.AppException( + 'chunk %s was added within this branch and ' + 'subsequently edited. This is not yet supported: ' + 'refusing to merge.' % ci['name']) + changed = True + ci['ref'] = old_ci['ref'] + merge_chunk(old_ci, ci) + if changed: + self.save_morphology(to_repo, si['morph'], stratum) + self.app.runcmd(['git', 'add', si['morph'] + '.morph'], + cwd=to_repo) from_root_dir = self.find_repository(from_branch_dir, root_repo) to_root_dir = self.find_repository(to_branch_dir, root_repo) self.app.runcmd(['git', 'checkout', to_branch], cwd=to_root_dir) self.merge_repo(root_repo, from_root_dir, from_branch, to_root_dir, to_branch, commit=False) - morphs_repo_list = set([to_root_dir]) + dirty_repos = set([to_root_dir]) for f in glob.glob(os.path.join(to_root_dir, '*.morph')): - name = f[:-len('.morph')] - morphology = self.load_morphology(to_root_dir, name) + name = os.path.basename(f)[:-len('.morph')] + old_morphology, morphology = self.load_morphology_pair( + to_root_dir, to_branch, name) if morphology['kind'] == 'system': - for si in morphology['strata']: - if si['ref'] == from_branch: - _merge_stratum(si) - si['ref'] = to_branch - self.save_morphology(to_root_dir, name, morphology) - - for repo in morphs_repo_list: - msg = "Merge system branch '%s'" % from_branch - self.app.runcmd(['git', 'commit', '--all', '--message=%s' % msg], - cwd=repo) + changed = False + edited_strata = [si for si in morphology['strata'] + if si['ref'] == from_branch] + for si in edited_strata: + for old_si in old_morphology['strata']: + # We make no attempt at rename / move detection + if old_si['morph'] == si['morph'] \ + and old_si['repo'] == si['repo']: + break + else: + raise cliapp.AppException( + 'stratum %s was added within this branch and ' + 'subsequently edited. This is not yet supported: ' + 'refusing to merge.' % si['morph']) + changed = True + si['ref'] = old_si['ref'] + merge_stratum(old_si, si) + if changed: + self.save_morphology(to_root_dir, name, morphology) + self.app.runcmd(['git', 'add', f], cwd=to_root_dir) + + for repo_dir in dirty_repos: + # Repo will often turn out to not be dirty: if the changes we + # merged only updated refs to the system branch, we will have + # changed them back again so that the index will now be empty. + if morphlib.git.index_has_changes(self.app.runcmd, repo_dir): + msg = "Merge system branch '%s'" % from_branch + self.app.runcmd(['git', 'commit', '--all', '-m%s' % msg], + cwd=repo_dir) def build(self, args): if len(args) != 1: diff --git a/tests.branching/merge-handles-unmergable-cases.exit b/tests.branching/merge-handles-unmergable-cases.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/merge-handles-unmergable-cases.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/merge-handles-unmergable-cases.script b/tests.branching/merge-handles-unmergable-cases.script new file mode 100755 index 00000000..fd7f1478 --- /dev/null +++ b/tests.branching/merge-handles-unmergable-cases.script @@ -0,0 +1,30 @@ +#!/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. + +# Things that "morph merge" isn't expected to handle (but shouldn't crash) + +set -eu + +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" checkout baserock:morphs master +"$SRCDIR/scripts/test-morph" branch baserock:morphs test/unmergable + +cd "$DATADIR/workspace/test/unmergable/baserock:morphs" +sed -ie 's/"kind": "stratum"/"kind": "chunk"/' hello-stratum.morph +git commit --quiet --all -m "Unmergeable because kind has changed" +cd "$DATADIR/workspace/master/baserock:morphs" +"$SRCDIR/scripts/test-morph" merge test/unmergable diff --git a/tests.branching/merge-handles-unmergable-cases.stderr b/tests.branching/merge-handles-unmergable-cases.stderr new file mode 100644 index 00000000..513db2b8 --- /dev/null +++ b/tests.branching/merge-handles-unmergable-cases.stderr @@ -0,0 +1 @@ +ERROR: merge conflict: "kind" of morphology hello-stratum diff --git a/tests.branching/merge-not-to-master.script b/tests.branching/merge-not-to-master.script new file mode 100755 index 00000000..3758ce3e --- /dev/null +++ b/tests.branching/merge-not-to-master.script @@ -0,0 +1,69 @@ +#!/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 a system branch into a newly created +# system branch + +set -eu + +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" init + +# Create stable branch to merge TO +"$SRCDIR/scripts/test-morph" branch baserock:morphs test/stable +cd test/stable/baserock:morphs +git push --quiet origin test/stable + +# Create feature branch to merge FROM +"$SRCDIR/scripts/test-morph" branch baserock:morphs test/feature test/stable +cd "$DATADIR/workspace/test/feature" + +# Edit hello in FROM +"$SRCDIR/scripts/test-morph" edit hello-system hello-stratum hello +cd baserock:hello +touch newfile.txt +git add newfile.txt +git commit -m foo --quiet + +# Commit in morphs repo +# FIXME: this should become unnecessary since only the refs have +# changed. +cd ../baserock:morphs +git commit --all --quiet -m "Update morph refs for test/feature" + +# Merge changes back to test/stable +cd "$DATADIR/workspace" +cd test/stable +"$SRCDIR/scripts/test-morph" merge test/feature + +# Check results: changes to 'hello' should have been merged back to +# test/stable. +cd baserock:hello +[ -e newfile.txt ] + +# Make sure all changes are committed and to the correct branch ('hello' +# was built from 'master' before branching, so the changes should be +# merged back to 'master'). +git status --short +[ $(git rev-parse master) = $(git rev-parse HEAD) ] + +# Changes here should be on test/stable. +cd ../baserock:morphs +git status --short +[ $(git rev-parse test/stable) = $(git rev-parse HEAD) ] + +# Make sure all refs to the merged branch have gone. +! grep "\"ref\": \"test/feature\"" *.morph diff --git a/tests.branching/merge-with-chunk-renamed.script b/tests.branching/merge-with-chunk-renamed.script new file mode 100755 index 00000000..1ca2ee48 --- /dev/null +++ b/tests.branching/merge-with-chunk-renamed.script @@ -0,0 +1,56 @@ +#!/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. + +# "morph merge" should pull changes from a chunk even if its name was changed +# in the branch + +set -eu + +# Create system branch. +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch baserock:morphs baserock/newbranch + +# Rename the chunk, and then commit a seperate change +"$SRCDIR/scripts/test-morph" edit hello-system hello-stratum hello +cd baserock/newbranch/baserock:hello + +cat hello.morph | sed -e 's/"name": "hello"/"name": "goodbye"/' > goodbye.morph +git rm -q hello.morph +git add goodbye.morph +git commit -m "Rename chunk" --quiet + +touch newfile.txt +git add newfile.txt +git commit -m "Add new file" --quiet + +# Update stratum to point at the renamed chunk +cd ../baserock:morphs +sed -ie 's/"name": "hello"/"name": "goodbye"/' hello-stratum.morph +git commit --all --quiet -m "Update morph refs for baserock/newbranch" + +# Merge changes back to master +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" checkout baserock:morphs master +cd master +"$SRCDIR/scripts/test-morph" merge baserock/newbranch + +# Morph should have realised that 'goodbye' is not a new chunk, +# and pulled in the changes from 'hello' in the old branch +cd baserock:hello +[ ! -e hello.morph ] +[ -e goodbye.morph ] +[ -e newfile.txt ] diff --git a/tests.branching/merge-with-chunk-repo-moved.exit b/tests.branching/merge-with-chunk-repo-moved.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/merge-with-chunk-repo-moved.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/merge-with-chunk-repo-moved.script b/tests.branching/merge-with-chunk-repo-moved.script new file mode 100755 index 00000000..c67ccc6d --- /dev/null +++ b/tests.branching/merge-with-chunk-repo-moved.script @@ -0,0 +1,53 @@ +#!/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. + +# "morph merge" should detect changes in a repo that was added as part of the +# branch and warn the user that the changes will not be merged automatically + +set -eu + +# Create system branch. +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch baserock:morphs baserock/newbranch + +"$SRCDIR/scripts/test-morph" edit hello-system hello-stratum hello + +# Chunk moves to a new location (we manually update the ref back to master +# here, so 'morph edit' can create a system branch in the new repo from it). +git clone -q "$DATADIR/hello" "$DATADIR/hello-lorried" +cd "$DATADIR/workspace/baserock/newbranch/baserock:morphs" +sed -e 's/"repo": "baserock:hello"/"repo": "baserock:hello-lorried"/' \ + -e 's/"ref": "baserock\/newbranch"/"ref": "master"/' \ + -i hello-stratum.morph +git commit -q --all -m "'hello' repository has moved" + +# Now we further edit the chunk, just for fun. +"$SRCDIR/scripts/test-morph" edit hello-system hello-stratum hello +cd "$DATADIR/workspace/baserock/newbranch/baserock:hello-lorried" +touch newfile.txt +git add newfile.txt +git commit -m "Add new file" --quiet + +cd "$DATADIR/workspace/baserock/newbranch/baserock:morphs" +git commit -q --all -m "Update system branch refs" + +# Try to merge changes back to master (should fail, because we don't support +# adding chunks inside branches yet). +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" checkout baserock:morphs master +cd master +"$SRCDIR/scripts/test-morph" merge baserock/newbranch diff --git a/tests.branching/merge-with-chunk-repo-moved.stderr b/tests.branching/merge-with-chunk-repo-moved.stderr new file mode 100644 index 00000000..95fe61e6 --- /dev/null +++ b/tests.branching/merge-with-chunk-repo-moved.stderr @@ -0,0 +1 @@ +ERROR: chunk hello was added within this branch and subsequently edited. This is not yet supported: refusing to merge. diff --git a/tests.branching/merge-with-stratum-renamed.exit b/tests.branching/merge-with-stratum-renamed.exit new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/tests.branching/merge-with-stratum-renamed.exit @@ -0,0 +1 @@ +1 diff --git a/tests.branching/merge-with-stratum-renamed.script b/tests.branching/merge-with-stratum-renamed.script new file mode 100755 index 00000000..8df2cd18 --- /dev/null +++ b/tests.branching/merge-with-stratum-renamed.script @@ -0,0 +1,51 @@ +#!/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. + +# "morph merge" should deal with stratum renames; currently it doesn't deal +# very well, but at least we don't crash. + +set -eu + +# Create system branch. +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch baserock:morphs baserock/newbranch + +# The user may 'morph edit hello-system hello-stratum hello' and commit here: +# we currently silently ignore her changes on merge, because we don't +# associate hello-stratum and goodbye-stratum at all. + +# Rename the stratum +"$SRCDIR/scripts/test-morph" edit hello-system hello-stratum +cd baserock/newbranch/baserock:morphs + +sed -e 's/"morph": "hello-stratum"/"morph": "goodbye-stratum"/'\ + -i hello-system.morph +sed -e 's/"name": "hello-stratum"/"name": "goodbye-stratum"/' \ + hello-stratum.morph > goodbye-stratum.morph +git rm -q hello-stratum.morph +git add goodbye-stratum.morph +git commit -q --all -m "Rename hello-stratum to goodbye-stratum" + +# The user may 'morph edit hello-system goodbye-stratum hello' and commit +# here, too: same problem. + +# Merge changes back to master (this should fail, because we don't support +# adding strata inside branches yet). +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" checkout baserock:morphs master +cd master +"$SRCDIR/scripts/test-morph" merge baserock/newbranch diff --git a/tests.branching/merge-with-stratum-renamed.stderr b/tests.branching/merge-with-stratum-renamed.stderr new file mode 100644 index 00000000..ad144f93 --- /dev/null +++ b/tests.branching/merge-with-stratum-renamed.stderr @@ -0,0 +1 @@ +ERROR: stratum goodbye-stratum was added within this branch and subsequently edited. This is not yet supported: refusing to merge. diff --git a/tests.branching/merge.script b/tests.branching/merge.script index d8a28cb3..21a30116 100755 --- a/tests.branching/merge.script +++ b/tests.branching/merge.script @@ -49,6 +49,8 @@ git status --short # make sure all changes are committed cd ../baserock:morphs ! grep "\"ref\": \"baserock/newbranch\"" *.morph +# The only change here was the branch refs, which have now been +# changed back - so there should not be any new commits. echo "Commit message for baserock:morphs" git cat-file commit HEAD | tail -n 1 diff --git a/tests.branching/merge.stdout b/tests.branching/merge.stdout index e5127734..6806f75a 100644 --- a/tests.branching/merge.stdout +++ b/tests.branching/merge.stdout @@ -1,5 +1,5 @@ Commit message for baserock:morphs -Merge system branch 'baserock/newbranch' +initial Commit message for baserock:hello Merge system branch 'baserock/newbranch' diff --git a/tests.branching/workflow-separate-stratum-repos.script b/tests.branching/workflow-separate-stratum-repos.script index 3d0f6529..06c4f3b8 100755 --- a/tests.branching/workflow-separate-stratum-repos.script +++ b/tests.branching/workflow-separate-stratum-repos.script @@ -63,7 +63,6 @@ cat <<EOF > "$1/$2.morph" EOF } - # Create two more strata outside the baserock:morphs repository EXTERNAL_STRATA_REPO="$DATADIR/external-strata" @@ -84,14 +83,22 @@ git commit --quiet -m "Initial commit" create_chunk "$DATADIR/stratum2-hello" "hello" create_chunk "$DATADIR/stratum3-hello" "hello" -# Update hello-system to include them +# Update hello-system to include them ... using a system branch! Since the +# strata refs are 'master' not 'me/add-external-strata' this does not cause +# problems with merging. -cd "$DATADIR/morphs" -cat <<EOF > "$DATADIR/morphs/hello-system.morph" +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" init +"$SRCDIR/scripts/test-morph" branch baserock:morphs me/add-external-strata + +cd "$DATADIR/workspace/me/add-external-strata/baserock:morphs" + +cat <<EOF > "hello-system.morph" { "name": "hello-system", "kind": "system", "system-kind": "syslinux-disk", + "arch": "x86_64", "disk-size": "1G", "strata": [ { @@ -114,14 +121,26 @@ cat <<EOF > "$DATADIR/morphs/hello-system.morph" EOF git commit --quiet --all -m "Add two more external strata" -# Now try to branch and merge the system -# FIXME: we should try and build it, too +# Merge to master +cd "$DATADIR/workspace" +"$SRCDIR/scripts/test-morph" checkout baserock:morphs master +cd master/baserock:morphs +"$SRCDIR/scripts/test-morph" merge me/add-external-strata +# In reality the user would do: 'git push origin master' here, +# but since our remote repo is non-bare we must cheat a bit. +# We should consider a separate fixture for the workflow tests. +cd "$DATADIR/morphs" +git pull -q \ + "file://$DATADIR/workspace/master/baserock:morphs" master + +# Now make another change to the system +# FIXME: we should try and build it, too cd "$DATADIR/workspace" -"$SRCDIR/scripts/test-morph" init "$SRCDIR/scripts/test-morph" branch baserock:morphs me/readme-fixes # Edit one chunk +cd "me/readme-fixes" "$SRCDIR/scripts/test-morph" edit hello-system stratum2 hello cd "$DATADIR/workspace/me/readme-fixes/baserock:stratum2-hello" echo > README yoyoyo @@ -135,7 +154,7 @@ echo > README yoyoyo git add README git commit -m "Fix README in hello" --quiet -# Update the morphologies repos +# Update the morphology repos cd ../baserock:external-strata git commit --quiet --all -m "Commit changes for system branch" @@ -144,6 +163,17 @@ git commit --quiet --all -m "Commit changes for system branch" # Merge our system branch into master cd "$DATADIR/workspace" -"$SRCDIR/scripts/test-morph" checkout baserock:morphs master cd master "$SRCDIR/scripts/test-morph" merge me/readme-fixes + +# Check the changes have appeared +cd baserock:morphs +[ $(git rev-parse HEAD) = $(git rev-parse master) ] + +cd ../baserock:stratum2-hello +[ -e README ] +[ $(git rev-parse HEAD) = $(git rev-parse master) ] + +cd ../baserock:stratum3-hello +[ -e README ] +[ $(git rev-parse HEAD) = $(git rev-parse master) ] |