Merge ~wgrant/git-build-recipe:nest-part into git-build-recipe:master

Proposed by William Grant
Status: Merged
Merged at revision: 7bd6e2e234504c813ff79cbcba1960cf884cba8b
Proposed branch: ~wgrant/git-build-recipe:nest-part
Merge into: git-build-recipe:master
Prerequisite: ~wgrant/git-build-recipe:bug-1542673
Diff against target: 179 lines (+23/-26)
3 files modified
debian/changelog (+6/-0)
gitbuildrecipe/recipe.py (+3/-5)
gitbuildrecipe/tests/test_recipe.py (+14/-21)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+286479@code.launchpad.net

Commit message

Implement nest-part (LP: #1537579).

Description of the change

A simpler, faster https://code.launchpad.net/~cjwatson/git-build-recipe/+git/git-build-recipe/+merge/283756.

Using an actual git subtree doesn't buy us much, since we can't easily support merges into nested parts. It would possibly vaguely work in bzr due to file IDs, but no such luck here. read-tree of the tip rev is much faster than rewriting the whole branch, so let's do that.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 0c8e1bd..8a94f44 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
1git-build-recipe (0.3) UNRELEASED; urgency=medium
2
3 * Implement nest-part (LP: #1537579).
4
5 -- Colin Watson <cjwatson@ubuntu.com> Mon, 25 Jan 2016 02:51:00 +0000
6
1git-build-recipe (0.2.1) trusty; urgency=medium7git-build-recipe (0.2.1) trusty; urgency=medium
28
3 * Configure "lp:" as shorthand for "https://git.launchpad.net/".9 * Configure "lp:" as shorthand for "https://git.launchpad.net/".
diff --git a/gitbuildrecipe/recipe.py b/gitbuildrecipe/recipe.py
index f1ea7d0..703c2d1 100644
--- a/gitbuildrecipe/recipe.py
+++ b/gitbuildrecipe/recipe.py
@@ -368,11 +368,9 @@ def nest_part_branch(child_branch, target_path, subpath, target_subdir=None):
368 child_branch.path = target_path368 child_branch.path = target_path
369 fetch_branches(child_branch)369 fetch_branches(child_branch)
370 child_branch.resolve_commit()370 child_branch.resolve_commit()
371 subtree_commit = child_branch.git_output(371 child_branch.git_call(
372 "subtree", "split", "-P", subpath, child_branch.commit)372 "read-tree", "--prefix", target_subdir, "-u",
373 child_branch.path = os.path.join(target_path, target_subdir)373 child_branch.commit + ":" + subpath)
374 git_clone(".", child_branch.path, child_branch.remote_name)
375 child_branch.git_call("checkout", subtree_commit)
376374
377375
378def _build_inner_tree(base_branch, target_path):376def _build_inner_tree(base_branch, target_path):
diff --git a/gitbuildrecipe/tests/test_recipe.py b/gitbuildrecipe/tests/test_recipe.py
index 298eea7..c3c8491 100644
--- a/gitbuildrecipe/tests/test_recipe.py
+++ b/gitbuildrecipe/tests/test_recipe.py
@@ -14,10 +14,10 @@
1414
15import os15import os
16import shutil16import shutil
17import unittest
1817
19from testtools.matchers import (18from testtools.matchers import (
20 FileContains,19 FileContains,
20 Not,
21 PathExists,21 PathExists,
22 )22 )
2323
@@ -287,7 +287,6 @@ class RecipeParserTests(GitTestCase):
287 self.assertEqual(None, location)287 self.assertEqual(None, location)
288 self.check_recipe_branch(child_branch, "bar", "http://bar.org")288 self.check_recipe_branch(child_branch, "bar", "http://bar.org")
289289
290 @unittest.skip("nest_part broken")
291 def test_builds_recipe_with_nest_part(self):290 def test_builds_recipe_with_nest_part(self):
292 base_branch = self.get_recipe(self.basic_header_and_branch291 base_branch = self.get_recipe(self.basic_header_and_branch
293 + "nest-part bar http://bar.org some/path")292 + "nest-part bar http://bar.org some/path")
@@ -300,7 +299,6 @@ class RecipeParserTests(GitTestCase):
300 self.assertEqual("some/path", instruction.subpath)299 self.assertEqual("some/path", instruction.subpath)
301 self.assertEqual(None, instruction.target_subdir)300 self.assertEqual(None, instruction.target_subdir)
302301
303 @unittest.skip("nest_part broken")
304 def test_builds_recipe_with_nest_part_subdir(self):302 def test_builds_recipe_with_nest_part_subdir(self):
305 base_branch = self.get_recipe(self.basic_header_and_branch303 base_branch = self.get_recipe(self.basic_header_and_branch
306 + "nest-part bar http://bar.org some/path target-subdir")304 + "nest-part bar http://bar.org some/path target-subdir")
@@ -313,7 +311,6 @@ class RecipeParserTests(GitTestCase):
313 self.assertEqual("some/path", instruction.subpath)311 self.assertEqual("some/path", instruction.subpath)
314 self.assertEqual("target-subdir", instruction.target_subdir)312 self.assertEqual("target-subdir", instruction.target_subdir)
315313
316 @unittest.skip("nest_part broken")
317 def test_builds_recipe_with_nest_part_subdir_and_revspec(self):314 def test_builds_recipe_with_nest_part_subdir_and_revspec(self):
318 base_branch = self.get_recipe(self.basic_header_and_branch315 base_branch = self.get_recipe(self.basic_header_and_branch
319 + "nest-part bar http://bar.org some/path target-subdir 1234")316 + "nest-part bar http://bar.org some/path target-subdir 1234")
@@ -631,7 +628,6 @@ class BuildTreeTests(GitTestCase):
631 self.assertEqual(source1_commit, base_branch.commit)628 self.assertEqual(source1_commit, base_branch.commit)
632 self.assertEqual(source2_commit, merged_branch.commit)629 self.assertEqual(source2_commit, merged_branch.commit)
633630
634 @unittest.skip("nest_part broken")
635 def test_build_tree_implicit_dir(self):631 def test_build_tree_implicit_dir(self):
636 # Branches nested into non-existent directories trigger creation of632 # Branches nested into non-existent directories trigger creation of
637 # those directories.633 # those directories.
@@ -647,11 +643,11 @@ class BuildTreeTests(GitTestCase):
647 base_branch = BaseRecipeBranch("source1", "1", 0.4)643 base_branch = BaseRecipeBranch("source1", "1", 0.4)
648 merged_branch_2 = RecipeBranch("merged", "source2")644 merged_branch_2 = RecipeBranch("merged", "source2")
649 # Merge source2 into path implicit/b645 # Merge source2 into path implicit/b
650 base_branch.nest_part_branch(merged_branch_2, ".",646 base_branch.nest_part_branch(merged_branch_2, "/",
651 target_subdir="implicit/b")647 target_subdir="implicit/b")
652 # Merge source3 into path implicit/moreimplicit/c648 # Merge source3 into path implicit/moreimplicit/c
653 merged_branch_3 = RecipeBranch("merged", "source3")649 merged_branch_3 = RecipeBranch("merged2", "source3")
654 base_branch.nest_part_branch(merged_branch_3, ".",650 base_branch.nest_part_branch(merged_branch_3, "/",
655 target_subdir="moreimplicit/another/c")651 target_subdir="moreimplicit/another/c")
656 build_tree(base_branch, "target")652 build_tree(base_branch, "target")
657 self.assertThat("target/implicit/b/file", FileContains("new file"))653 self.assertThat("target/implicit/b/file", FileContains("new file"))
@@ -659,7 +655,6 @@ class BuildTreeTests(GitTestCase):
659 "target/moreimplicit/another/c/yetanotherfile",655 "target/moreimplicit/another/c/yetanotherfile",
660 FileContains("rugby"))656 FileContains("rugby"))
661657
662 @unittest.skip("nest_part broken")
663 def test_build_tree_nest_part(self):658 def test_build_tree_nest_part(self):
664 """A recipe can specify a merge of just part of an unrelated tree."""659 """A recipe can specify a merge of just part of an unrelated tree."""
665 source1 = self.make_source_branch("source1")660 source1 = self.make_source_branch("source1")
@@ -667,7 +662,9 @@ class BuildTreeTests(GitTestCase):
667 source1_commit = source1.last_revision()662 source1_commit = source1.last_revision()
668 # Add 'b' to source2.663 # Add 'b' to source2.
669 source2.build_tree_contents([664 source2.build_tree_contents([
670 ("b", "new file"), ("not-b", "other file")])665 ("b/",), ("b/a", "new file"),
666 ("not-b/",), ("not-b/a", "other file"),
667 ])
671 source2.add(["b", "not-b"])668 source2.add(["b", "not-b"])
672 source2_commit = source2.commit("two")669 source2_commit = source2.commit("two")
673 base_branch = BaseRecipeBranch("source1", "1", 0.2)670 base_branch = BaseRecipeBranch("source1", "1", 0.2)
@@ -675,15 +672,13 @@ class BuildTreeTests(GitTestCase):
675 # Merge just 'b' from source2; 'a' is untouched.672 # Merge just 'b' from source2; 'a' is untouched.
676 base_branch.nest_part_branch(merged_branch, "b")673 base_branch.nest_part_branch(merged_branch, "b")
677 build_tree(base_branch, "target")674 build_tree(base_branch, "target")
678 file_id = source1.path2id("a")
679 self.assertThat(675 self.assertThat(
680 "target/a", FileContains(source1.get_file_text(file_id)))676 "target/a", FileContains(source1._git_output("show", "HEAD:a")))
681 self.assertThat("target/b", FileContains("new file"))677 self.assertThat("target/b/a", FileContains("new file"))
682 self.assertNotInWorkingTree("not-b", "target")678 self.assertThat("target/not-b", Not(PathExists()))
683 self.assertEqual(source1_commit, base_branch.commit)679 self.assertEqual(source1_commit, base_branch.commit)
684 self.assertEqual(source2_commit, merged_branch.commit)680 self.assertEqual(source2_commit, merged_branch.commit)
685681
686 @unittest.skip("nest_part broken")
687 def test_build_tree_nest_part_explicit_target(self):682 def test_build_tree_nest_part_explicit_target(self):
688 """A recipe can specify a merge of just part of an unrelated tree into683 """A recipe can specify a merge of just part of an unrelated tree into
689 a specific subdirectory of the target tree.684 a specific subdirectory of the target tree.
@@ -696,7 +691,8 @@ class BuildTreeTests(GitTestCase):
696 source1_commit = source1.last_revision()691 source1_commit = source1.last_revision()
697 # Add 'b' to source2.692 # Add 'b' to source2.
698 source2.build_tree_contents([693 source2.build_tree_contents([
699 ("b", "new file"), ("not-b", "other file")])694 ("b/",), ("b/a", "new file"),
695 ("not-b/",), ("not-b/a", "other file")])
700 source2.add(["b", "not-b"])696 source2.add(["b", "not-b"])
701 source2_commit = source2.commit("two")697 source2_commit = source2.commit("two")
702 base_branch = BaseRecipeBranch("source1", "1", 0.2)698 base_branch = BaseRecipeBranch("source1", "1", 0.2)
@@ -704,8 +700,8 @@ class BuildTreeTests(GitTestCase):
704 # Merge just 'b' from source2; 'a' is untouched.700 # Merge just 'b' from source2; 'a' is untouched.
705 base_branch.nest_part_branch(merged_branch, "b", "dir/b")701 base_branch.nest_part_branch(merged_branch, "b", "dir/b")
706 build_tree(base_branch, "target")702 build_tree(base_branch, "target")
707 self.assertThat("target/dir/b", FileContains("new file"))703 self.assertThat("target/dir/b/a", FileContains("new file"))
708 self.assertNotInWorkingTree("dir/not-b", "target")704 self.assertThat("target/dir/not-b", Not(PathExists()))
709 self.assertEqual(source1_commit, base_branch.commit)705 self.assertEqual(source1_commit, base_branch.commit)
710 self.assertEqual(source2_commit, merged_branch.commit)706 self.assertEqual(source2_commit, merged_branch.commit)
711707
@@ -1006,7 +1002,6 @@ class StringifyTests(GitTestCase):
1006 base_branch.nest_branch(".", nested_branch1)1002 base_branch.nest_branch(".", nested_branch1)
1007 self.assertRaises(InstructionParseError, str, base_branch)1003 self.assertRaises(InstructionParseError, str, base_branch)
10081004
1009 @unittest.skip("nest_part broken")
1010 def test_with_nest_part(self):1005 def test_with_nest_part(self):
1011 base_branch = BaseRecipeBranch("base_url", "1", 0.1)1006 base_branch = BaseRecipeBranch("base_url", "1", 0.1)
1012 base_branch.commit = "base_revid"1007 base_branch.commit = "base_revid"
@@ -1019,7 +1014,6 @@ class StringifyTests(GitTestCase):
1019 "nest-part nested1 nested1_url foo bar tag:foo\n",1014 "nest-part nested1 nested1_url foo bar tag:foo\n",
1020 manifest)1015 manifest)
10211016
1022 @unittest.skip("nest_part broken")
1023 def test_with_nest_part_with_no_target_dir(self):1017 def test_with_nest_part_with_no_target_dir(self):
1024 base_branch = BaseRecipeBranch("base_url", "1", 0.1)1018 base_branch = BaseRecipeBranch("base_url", "1", 0.1)
1025 base_branch.commit = "base_revid"1019 base_branch.commit = "base_revid"
@@ -1032,7 +1026,6 @@ class StringifyTests(GitTestCase):
1032 "nest-part nested1 nested1_url foo foo tag:foo\n",1026 "nest-part nested1 nested1_url foo foo tag:foo\n",
1033 manifest)1027 manifest)
10341028
1035 @unittest.skip("nest_part broken")
1036 def test_with_nest_part_with_no_target_dir_no_revspec(self):1029 def test_with_nest_part_with_no_target_dir_no_revspec(self):
1037 base_branch = BaseRecipeBranch("base_url", "1", 0.1)1030 base_branch = BaseRecipeBranch("base_url", "1", 0.1)
1038 base_branch.commit = "base_revid"1031 base_branch.commit = "base_revid"

Subscribers

People subscribed via source and target branches