Merge lp:~jelmer/brz/bzr-bound-to-git into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/bzr-bound-to-git
Merge into: lp:brz
Diff against target: 187 lines (+57/-16)
4 files modified
breezy/commit.py (+8/-4)
breezy/git/branch.py (+27/-6)
breezy/git/interrepo.py (+8/-6)
breezy/git/tests/test_branch.py (+14/-0)
To merge this branch: bzr merge lp:~jelmer/brz/bzr-bound-to-git
Reviewer Review Type Date Requested Status
Martin Packman Approve
Review via email: mp+355573@code.launchpad.net

Commit message

Support committing to a bzr branch bound to a git branch.

Description of the change

Support committing to a bzr branch bound to a git branch.

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

Thanks, all makes sense.

review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/commit.py'
2--- breezy/commit.py 2018-11-16 18:40:46 +0000
3+++ breezy/commit.py 2018-11-17 00:41:27 +0000
4@@ -562,9 +562,9 @@
5 # to local.
6
7 # Make sure the local branch is identical to the master
8- master_info = self.master_branch.last_revision_info()
9- local_info = self.branch.last_revision_info()
10- if local_info != master_info:
11+ master_revid = self.master_branch.last_revision()
12+ local_revid = self.branch.last_revision()
13+ if local_revid != master_revid:
14 raise errors.BoundBranchOutOfDate(self.branch,
15 self.master_branch)
16
17@@ -588,7 +588,11 @@
18 # - in a checkout scenario the tree may have no
19 # parents but the branch may do.
20 first_tree_parent = breezy.revision.NULL_REVISION
21- old_revno, master_last = self.master_branch.last_revision_info()
22+ try:
23+ old_revno, master_last = self.master_branch.last_revision_info()
24+ except errors.UnsupportedOperation:
25+ master_last = self.master_branch.last_revision()
26+ old_revno = self.branch.revision_id_to_revno(master_last)
27 if master_last != first_tree_parent:
28 if master_last != breezy.revision.NULL_REVISION:
29 raise errors.OutOfDateTree(self.work_tree)
30
31=== modified file 'breezy/git/branch.py'
32--- breezy/git/branch.py 2018-11-16 18:40:46 +0000
33+++ breezy/git/branch.py 2018-11-17 00:41:27 +0000
34@@ -595,6 +595,26 @@
35 self._tag_refs = list(self._iter_tag_refs())
36 return self._tag_refs
37
38+ def import_last_revision_info_and_tags(self, source, revno, revid,
39+ lossy=False):
40+ """Set the last revision info, importing from another repo if necessary.
41+
42+ This is used by the bound branch code to upload a revision to
43+ the master branch first before updating the tip of the local branch.
44+ Revisions referenced by source's tags are also transferred.
45+
46+ :param source: Source branch to optionally fetch from
47+ :param revno: Revision number of the new tip
48+ :param revid: Revision id of the new tip
49+ :param lossy: Whether to discard metadata that can not be
50+ natively represented
51+ :return: Tuple with the new revision number and revision id
52+ (should only be different from the arguments when lossy=True)
53+ """
54+ push_result = source.push(
55+ self, stop_revision=revid, lossy=lossy, _stop_revno=revno)
56+ return (push_result.new_revno, push_result.new_revid)
57+
58
59 class LocalGitBranch(GitBranch):
60 """A local Git branch."""
61@@ -1188,12 +1208,13 @@
62 return (not isinstance(source, GitBranch) and
63 isinstance(target, GitBranch))
64
65- def _get_new_refs(self, stop_revision=None, fetch_tags=None):
66+ def _get_new_refs(self, stop_revision=None, fetch_tags=None,
67+ stop_revno=None):
68 if not self.source.is_locked():
69 raise errors.ObjectNotLocked(self.source)
70 if stop_revision is None:
71 (stop_revno, stop_revision) = self.source.last_revision_info()
72- else:
73+ elif stop_revno is None:
74 stop_revno = self.source.revision_id_to_revno(stop_revision)
75 if not isinstance(stop_revision, bytes):
76 raise TypeError(stop_revision)
77@@ -1285,13 +1306,13 @@
78 raise errors.NoRoundtrippingSupport(self.source, self.target)
79
80 def pull(self, overwrite=False, stop_revision=None, local=False,
81- possible_transports=None, run_hooks=True):
82+ possible_transports=None, run_hooks=True, _stop_revno=None):
83 result = GitBranchPullResult()
84 result.source_branch = self.source
85 result.target_branch = self.target
86 with self.source.lock_read(), self.target.lock_write():
87 new_refs, main_ref, stop_revinfo = self._get_new_refs(
88- stop_revision)
89+ stop_revision, stop_revno=_stop_revno)
90
91 def update_refs(old_refs):
92 return self._update_refs(result, old_refs, new_refs, overwrite)
93@@ -1314,7 +1335,7 @@
94 return result
95
96 def push(self, overwrite=False, stop_revision=None, lossy=False,
97- _override_hook_source_branch=None):
98+ _override_hook_source_branch=None, _stop_revno=None):
99 result = GitBranchPushResult()
100 result.source_branch = self.source
101 result.target_branch = self.target
102@@ -1322,7 +1343,7 @@
103 result.master_branch = result.target_branch
104 with self.source.lock_read(), self.target.lock_write():
105 new_refs, main_ref, stop_revinfo = self._get_new_refs(
106- stop_revision)
107+ stop_revision, stop_revno=_stop_revno)
108
109 def update_refs(old_refs):
110 return self._update_refs(result, old_refs, new_refs, overwrite)
111
112=== modified file 'breezy/git/interrepo.py'
113--- breezy/git/interrepo.py 2018-11-16 11:47:52 +0000
114+++ breezy/git/interrepo.py 2018-11-17 00:41:27 +0000
115@@ -264,6 +264,7 @@
116
117 def fetch_refs(self, update_refs, lossy, overwrite=False):
118 self._warn_slow()
119+ result_refs = {}
120 with self.source_store.lock_read():
121 old_refs = self._get_target_bzr_refs()
122 new_refs = update_refs(old_refs)
123@@ -288,7 +289,8 @@
124 self.target_refs.add_if_new(name, gitid)
125 else:
126 self.target_refs.set_if_equals(name, old_git_id, gitid)
127- return revidmap, old_refs, new_refs
128+ result_refs[name] = (gitid, revid if not lossy else self.mapping.revision_id_foreign_to_bzr(gitid))
129+ return revidmap, old_refs, result_refs
130
131 def fetch_objects(self, revs, lossy, limit=None):
132 if not lossy and not self.mapping.roundtripping:
133@@ -362,10 +364,10 @@
134
135 def git_update_refs(old_refs):
136 ret = {}
137- self.old_refs = dict([(k, (v, None))
138- for (k, v) in viewitems(old_refs)])
139- self.new_refs = update_refs(self.old_refs)
140- for name, (gitid, revid) in viewitems(self.new_refs):
141+ self.old_refs = {
142+ k: (v, None) for (k, v) in viewitems(old_refs)}
143+ new_refs = update_refs(self.old_refs)
144+ for name, (gitid, revid) in viewitems(new_refs):
145 if gitid is None:
146 git_sha = self.source_store._lookup_revision_sha1(revid)
147 gitid = unpeel_map.re_unpeel_tag(
148@@ -381,7 +383,7 @@
149 new_refs = self.target.send_pack(
150 git_update_refs, self.source_store.generate_lossy_pack_data)
151 # FIXME: revidmap?
152- return revidmap, self.old_refs, self.new_refs
153+ return revidmap, self.old_refs, new_refs
154
155 @staticmethod
156 def is_compatible(source, target):
157
158=== modified file 'breezy/git/tests/test_branch.py'
159--- breezy/git/tests/test_branch.py 2018-11-11 04:08:32 +0000
160+++ breezy/git/tests/test_branch.py 2018-11-17 00:41:27 +0000
161@@ -32,6 +32,7 @@
162 import os
163
164 from ... import (
165+ errors,
166 revision,
167 urlutils,
168 )
169@@ -271,6 +272,19 @@
170 self.assertEqual(revid1, newbranch.last_revision())
171 self.assertTrue(newbranch.repository.has_revision(revid2))
172
173+ def test_bzr_branch_bound_to_git(self):
174+ path, (gitsha1, gitsha2) = self.make_tworev_branch()
175+ wt = Branch.open(path).create_checkout('co')
176+ self.build_tree_contents([('co/foobar', b'blah')])
177+ self.assertRaises(
178+ errors.NoRoundtrippingSupport, wt.commit,
179+ 'commit from bound branch.')
180+ revid = wt.commit('commit from bound branch.', lossy=True)
181+ self.assertEqual(revid, wt.branch.last_revision())
182+ self.assertEqual(
183+ revid,
184+ wt.branch.get_master_branch().last_revision())
185+
186
187 class ForeignTestsBranchFactory(object):
188

Subscribers

People subscribed via source and target branches