Show More
@@ -945,6 +945,15 b' information about working with phases.' | |||||
945 | Phase of newly-created commits. |
|
945 | Phase of newly-created commits. | |
946 | Default: draft |
|
946 | Default: draft | |
947 |
|
947 | |||
|
948 | ``checksubrepos`` | |||
|
949 | ||||
|
950 | Check phase of state in each subrepositories, allowed values are | |||
|
951 | "ignore", "follow" or "abort". For settings other than "ignore", | |||
|
952 | the phase of each subrepository commit is checked before committing | |||
|
953 | in the parent repository. If there is any greater phase than the parent | |||
|
954 | ("secret" vs "draft", for example), the commit is either aborted | |||
|
955 | with "abort" or the higher phase is used with "follow". Default: "follow". | |||
|
956 | ||||
948 | ``profiling`` |
|
957 | ``profiling`` | |
949 | ------------- |
|
958 | ------------- | |
950 |
|
959 |
@@ -1382,7 +1382,7 b' class localrepository(object):' | |||||
1382 | parent2=xp2, pending=p) |
|
1382 | parent2=xp2, pending=p) | |
1383 | self.changelog.finalize(trp) |
|
1383 | self.changelog.finalize(trp) | |
1384 | # set the new commit is proper phase |
|
1384 | # set the new commit is proper phase | |
1385 |
targetphase = |
|
1385 | targetphase = subrepo.newcommitphase(self.ui, ctx) | |
1386 | if targetphase: |
|
1386 | if targetphase: | |
1387 | # retract boundary do not alter parent changeset. |
|
1387 | # retract boundary do not alter parent changeset. | |
1388 | # if a parent have higher the resulting phase will |
|
1388 | # if a parent have higher the resulting phase will |
@@ -10,6 +10,7 b' import xml.dom.minidom' | |||||
10 | import stat, subprocess, tarfile |
|
10 | import stat, subprocess, tarfile | |
11 | from i18n import _ |
|
11 | from i18n import _ | |
12 | import config, util, node, error, cmdutil, bookmarks, match as matchmod |
|
12 | import config, util, node, error, cmdutil, bookmarks, match as matchmod | |
|
13 | import phases | |||
13 | import pathutil |
|
14 | import pathutil | |
14 | hg = None |
|
15 | hg = None | |
15 | propertycache = util.propertycache |
|
16 | propertycache = util.propertycache | |
@@ -351,6 +352,37 b' def subrepo(ctx, path):' | |||||
351 | raise util.Abort(_('unknown subrepo type %s') % state[2]) |
|
352 | raise util.Abort(_('unknown subrepo type %s') % state[2]) | |
352 | return types[state[2]](ctx, path, state[:2]) |
|
353 | return types[state[2]](ctx, path, state[:2]) | |
353 |
|
354 | |||
|
355 | def newcommitphase(ui, ctx): | |||
|
356 | commitphase = phases.newcommitphase(ui) | |||
|
357 | substate = getattr(ctx, "substate", None) | |||
|
358 | if not substate: | |||
|
359 | return commitphase | |||
|
360 | check = ui.config('phases', 'checksubrepos', 'follow') | |||
|
361 | if check not in ('ignore', 'follow', 'abort'): | |||
|
362 | raise util.Abort(_('invalid phases.checksubrepos configuration: %s') | |||
|
363 | % (check)) | |||
|
364 | if check == 'ignore': | |||
|
365 | return commitphase | |||
|
366 | maxphase = phases.public | |||
|
367 | maxsub = None | |||
|
368 | for s in sorted(substate): | |||
|
369 | sub = ctx.sub(s) | |||
|
370 | subphase = sub.phase(substate[s][1]) | |||
|
371 | if maxphase < subphase: | |||
|
372 | maxphase = subphase | |||
|
373 | maxsub = s | |||
|
374 | if commitphase < maxphase: | |||
|
375 | if check == 'abort': | |||
|
376 | raise util.Abort(_("can't commit in %s phase" | |||
|
377 | " conflicting %s from subrepository %s") % | |||
|
378 | (phases.phasenames[commitphase], | |||
|
379 | phases.phasenames[maxphase], maxsub)) | |||
|
380 | ui.warn(_("warning: changes are committed in" | |||
|
381 | " %s phase from subrepository %s\n") % | |||
|
382 | (phases.phasenames[maxphase], maxsub)) | |||
|
383 | return maxphase | |||
|
384 | return commitphase | |||
|
385 | ||||
354 | # subrepo classes need to implement the following abstract class: |
|
386 | # subrepo classes need to implement the following abstract class: | |
355 |
|
387 | |||
356 | class abstractsubrepo(object): |
|
388 | class abstractsubrepo(object): | |
@@ -385,6 +417,11 b' class abstractsubrepo(object):' | |||||
385 | """ |
|
417 | """ | |
386 | raise NotImplementedError |
|
418 | raise NotImplementedError | |
387 |
|
419 | |||
|
420 | def phase(self, state): | |||
|
421 | """returns phase of specified state in the subrepository. | |||
|
422 | """ | |||
|
423 | return phases.public | |||
|
424 | ||||
388 | def remove(self): |
|
425 | def remove(self): | |
389 | """remove the subrepo |
|
426 | """remove the subrepo | |
390 |
|
427 | |||
@@ -652,6 +689,10 b' class hgsubrepo(abstractsubrepo):' | |||||
652 | return node.hex(n) |
|
689 | return node.hex(n) | |
653 |
|
690 | |||
654 | @annotatesubrepoerror |
|
691 | @annotatesubrepoerror | |
|
692 | def phase(self, state): | |||
|
693 | return self._repo[state].phase() | |||
|
694 | ||||
|
695 | @annotatesubrepoerror | |||
655 | def remove(self): |
|
696 | def remove(self): | |
656 | # we can't fully delete the repository as it may contain |
|
697 | # we can't fully delete the repository as it may contain | |
657 | # local-only history |
|
698 | # local-only history |
@@ -1232,4 +1232,69 b' Courtesy phases synchronisation to publi' | |||||
1232 | searching for changes |
|
1232 | searching for changes | |
1233 | no changes found |
|
1233 | no changes found | |
1234 | [1] |
|
1234 | [1] | |
|
1235 | $ cd .. | |||
1235 |
|
1236 | |||
|
1237 | Test phase choice for newly created commit with "phases.subrepochecks" | |||
|
1238 | configuration | |||
|
1239 | ||||
|
1240 | $ cd t | |||
|
1241 | $ hg update -q -r 12 | |||
|
1242 | ||||
|
1243 | $ cat >> s/ss/.hg/hgrc <<EOF | |||
|
1244 | > [phases] | |||
|
1245 | > new-commit = secret | |||
|
1246 | > EOF | |||
|
1247 | $ cat >> s/.hg/hgrc <<EOF | |||
|
1248 | > [phases] | |||
|
1249 | > new-commit = draft | |||
|
1250 | > EOF | |||
|
1251 | $ echo phasecheck1 >> s/ss/a | |||
|
1252 | $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1 | |||
|
1253 | committing subrepository ss | |||
|
1254 | transaction abort! | |||
|
1255 | rollback completed | |||
|
1256 | abort: can't commit in draft phase conflicting secret from subrepository ss | |||
|
1257 | [255] | |||
|
1258 | $ echo phasecheck2 >> s/ss/a | |||
|
1259 | $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2 | |||
|
1260 | committing subrepository ss | |||
|
1261 | $ hg -R s/ss phase tip | |||
|
1262 | 3: secret | |||
|
1263 | $ hg -R s phase tip | |||
|
1264 | 6: draft | |||
|
1265 | $ echo phasecheck3 >> s/ss/a | |||
|
1266 | $ hg -R s commit -S -m phasecheck3 | |||
|
1267 | committing subrepository ss | |||
|
1268 | warning: changes are committed in secret phase from subrepository ss | |||
|
1269 | $ hg -R s/ss phase tip | |||
|
1270 | 4: secret | |||
|
1271 | $ hg -R s phase tip | |||
|
1272 | 7: secret | |||
|
1273 | ||||
|
1274 | $ cat >> t/.hg/hgrc <<EOF | |||
|
1275 | > [phases] | |||
|
1276 | > new-commit = draft | |||
|
1277 | > EOF | |||
|
1278 | $ cat >> .hg/hgrc <<EOF | |||
|
1279 | > [phases] | |||
|
1280 | > new-commit = public | |||
|
1281 | > EOF | |||
|
1282 | $ echo phasecheck4 >> s/ss/a | |||
|
1283 | $ echo phasecheck4 >> t/t | |||
|
1284 | $ hg commit -S -m phasecheck4 | |||
|
1285 | committing subrepository s | |||
|
1286 | committing subrepository s/ss | |||
|
1287 | warning: changes are committed in secret phase from subrepository ss | |||
|
1288 | committing subrepository t | |||
|
1289 | warning: changes are committed in secret phase from subrepository s | |||
|
1290 | created new head | |||
|
1291 | $ hg -R s/ss phase tip | |||
|
1292 | 5: secret | |||
|
1293 | $ hg -R s phase tip | |||
|
1294 | 8: secret | |||
|
1295 | $ hg -R t phase tip | |||
|
1296 | 6: draft | |||
|
1297 | $ hg phase tip | |||
|
1298 | 15: secret | |||
|
1299 | ||||
|
1300 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now