Show More
@@ -149,48 +149,60 b' def findcommonoutgoing(repo, other, only' | |||
|
149 | 149 | |
|
150 | 150 | return og |
|
151 | 151 | |
|
152 |
def _ |
|
|
152 | def _headssummary(repo, remote, outgoing): | |
|
153 | 153 | """compute a summary of branch and heads status before and after push |
|
154 | 154 | |
|
155 | - oldmap: {'branch': [heads]} mapping for remote | |
|
156 | - newmap: {'branch': [heads]} mapping for local | |
|
157 | - unsynced: set of branch that have unsynced remote changes | |
|
158 | - branches: set of all common branch pushed | |
|
159 | - newbranches: list of plain new pushed branch | |
|
155 | return {'branch': ([remoteheads], [newheads], [unsyncedheads])} mapping | |
|
156 | ||
|
157 | - branch: the branch name | |
|
158 | - remoteheads: the list of remote heads known locally | |
|
159 | None is the branch is new | |
|
160 | - newheads: the new remote heads (known locally) with outgoing pushed | |
|
161 | - unsyncedheads: the list of remote heads unknown locally. | |
|
160 | 162 | """ |
|
161 | 163 | cl = repo.changelog |
|
162 | ||
|
164 | headssum = {} | |
|
163 | 165 | # A. Create set of branches involved in the push. |
|
164 | 166 | branches = set(repo[n].branch() for n in outgoing.missing) |
|
165 | 167 | remotemap = remote.branchmap() |
|
166 | 168 | newbranches = branches - set(remotemap) |
|
167 | 169 | branches.difference_update(newbranches) |
|
168 | 170 | |
|
169 | # B. Construct the initial oldmap and newmap dicts. | |
|
170 | # They contain information about the remote heads before and | |
|
171 | # after the push, respectively. | |
|
172 | # Heads not found locally are not included in either dict, | |
|
173 | # since they won't be affected by the push. | |
|
174 | # unsynced contains all branches with incoming changesets. | |
|
175 | oldmap = {} | |
|
176 | newmap = {} | |
|
177 | unsynced = set() | |
|
178 | for branch in branches: | |
|
179 | remotebrheads = remotemap[branch] | |
|
171 | # A. register remote heads | |
|
172 | remotebranches = set() | |
|
173 | for branch, heads in remote.branchmap().iteritems(): | |
|
174 | remotebranches.add(branch) | |
|
175 | known = [] | |
|
176 | unsynced = [] | |
|
177 | for h in heads: | |
|
178 | if h in cl.nodemap: | |
|
179 | known.append(h) | |
|
180 | else: | |
|
181 | unsynced.append(h) | |
|
182 | headssum[branch] = (known, list(known), unsynced) | |
|
183 | # B. add new branch data | |
|
184 | missingctx = list(repo[n] for n in outgoing.missing) | |
|
185 | touchedbranches = set() | |
|
186 | for ctx in missingctx: | |
|
187 | branch = ctx.branch() | |
|
188 | touchedbranches.add(branch) | |
|
189 | if branch not in headssum: | |
|
190 | headssum[branch] = (None, [], []) | |
|
180 | 191 | |
|
181 | prunedbrheads = [h for h in remotebrheads if h in cl.nodemap] | |
|
182 | oldmap[branch] = prunedbrheads | |
|
183 | newmap[branch] = list(prunedbrheads) | |
|
184 | if len(remotebrheads) > len(prunedbrheads): | |
|
185 | unsynced.add(branch) | |
|
192 | # C drop data about untouched branches: | |
|
193 | for branch in remotebranches - touchedbranches: | |
|
194 | del headssum[branch] | |
|
186 | 195 | |
|
187 |
# |
|
|
196 | # D. Update newmap with outgoing changes. | |
|
188 | 197 | # This will possibly add new heads and remove existing ones. |
|
189 | ctxgen = (repo[n] for n in outgoing.missing) | |
|
190 | repo._updatebranchcache(newmap, ctxgen) | |
|
191 | return oldmap, newmap, unsynced, branches, newbranches | |
|
198 | newmap = dict((branch, heads[1]) for branch, heads in headssum.iteritems() | |
|
199 | if heads[0] is not None) | |
|
200 | repo._updatebranchcache(newmap, missingctx) | |
|
201 | for branch, newheads in newmap.iteritems(): | |
|
202 | headssum[branch][1][:] = newheads | |
|
203 | return headssum | |
|
192 | 204 | |
|
193 |
def _old |
|
|
205 | def _oldheadssummary(repo, remoteheads, outgoing, inc=False): | |
|
194 | 206 | """Compute branchmapsummary for repo without branchmap support""" |
|
195 | 207 | |
|
196 | 208 | cl = repo.changelog |
@@ -204,11 +216,9 b' def _oldbranchmapsummary(repo, remotehea' | |||
|
204 | 216 | # - nullrev |
|
205 | 217 | # This explains why the new head are very simple to compute. |
|
206 | 218 | r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing) |
|
207 | branches = set([None]) | |
|
208 | newmap = {None: list(c.node() for c in r)} | |
|
209 | oldmap = {None: oldheads} | |
|
210 | unsynced = inc and branches or set() | |
|
211 | return oldmap, newmap, unsynced, branches, set() | |
|
219 | newheads = list(c.node() for c in r) | |
|
220 | unsynced = inc and set([None]) or set() | |
|
221 | return {None: (oldheads, newheads, unsynced)} | |
|
212 | 222 | |
|
213 | 223 | def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False): |
|
214 | 224 | """Check that a push won't add any outgoing head |
@@ -226,10 +236,11 b' def checkheads(repo, remote, outgoing, r' | |||
|
226 | 236 | return |
|
227 | 237 | |
|
228 | 238 | if remote.capable('branchmap'): |
|
229 |
|
|
|
239 | headssum = _headssummary(repo, remote, outgoing) | |
|
230 | 240 | else: |
|
231 |
|
|
|
232 | oldmap, newmap, unsynced, branches, newbranches = bms | |
|
241 | headssum = _oldheadssummary(repo, remoteheads, outgoing, inc) | |
|
242 | newbranches = [branch for branch, heads in headssum.iteritems() | |
|
243 | if heads[0] is None] | |
|
233 | 244 | # 1. Check for new branches on the remote. |
|
234 | 245 | if newbranches and not newbranch: # new branch requires --new-branch |
|
235 | 246 | branchnames = ', '.join(sorted(newbranches)) |
@@ -244,12 +255,18 b' def checkheads(repo, remote, outgoing, r' | |||
|
244 | 255 | error = None |
|
245 | 256 | localbookmarks = repo._bookmarks |
|
246 | 257 | |
|
247 | for branch in branches: | |
|
248 | newhs = set(newmap[branch]) | |
|
249 | oldhs = set(oldmap[branch]) | |
|
258 | unsynced = False | |
|
259 | for branch, heads in headssum.iteritems(): | |
|
260 | if heads[0] is None: | |
|
261 | # Maybe we should abort if we push more that one head | |
|
262 | # for new branches ? | |
|
263 | continue | |
|
264 | if heads[2]: | |
|
265 | unsynced = True | |
|
266 | oldhs = set(heads[0]) | |
|
267 | newhs = set(heads[1]) | |
|
250 | 268 | dhs = None |
|
251 | 269 | if len(newhs) > len(oldhs): |
|
252 | # strip updates to existing remote heads from the new heads list | |
|
253 | 270 | remotebookmarks = remote.listkeys('bookmarks') |
|
254 | 271 | bookmarkedheads = set() |
|
255 | 272 | for bm in localbookmarks: |
@@ -258,6 +275,7 b' def checkheads(repo, remote, outgoing, r' | |||
|
258 | 275 | lctx, rctx = repo[bm], repo[rnode] |
|
259 | 276 | if rctx == lctx.ancestor(rctx): |
|
260 | 277 | bookmarkedheads.add(lctx.node()) |
|
278 | # strip updates to existing remote heads from the new heads list | |
|
261 | 279 | dhs = list(newhs - bookmarkedheads - oldhs) |
|
262 | 280 | if dhs: |
|
263 | 281 | if error is None: |
@@ -267,7 +285,7 b' def checkheads(repo, remote, outgoing, r' | |||
|
267 | 285 | else: |
|
268 | 286 | error = _("push creates new remote head %s!" |
|
269 | 287 | ) % short(dhs[0]) |
|
270 |
if |
|
|
288 | if heads[2]: # unsynced | |
|
271 | 289 | hint = _("you should pull and merge or " |
|
272 | 290 | "use push -f to force") |
|
273 | 291 | else: |
General Comments 0
You need to be logged in to leave comments.
Login now