# HG changeset patch # User Alain Leufroy # Date 1316947380 -7200 # Node ID d5170cc7881c45c98cd7d9f9f01022fe782443f2 # Parent 5dcece86aeb0d611ca7ecfaa729075ed9d852cfc [states] add --exact option to `hg ` that allows to backward states bondaries diff -r 5dcece86aeb0 -r d5170cc7881c hgext/states.py --- a/hgext/states.py Wed Sep 21 03:52:13 2011 +0200 +++ b/hgext/states.py Sun Sep 25 12:43:00 2011 +0200 @@ -197,8 +197,6 @@ TODO: -- implement --exact - - implement consistency check - implement --force @@ -533,20 +531,30 @@ # automatic generation of command that set state def makecmd(state): - def cmdmoveheads(ui, repo, *changesets): + def cmdmoveheads(ui, repo, *changesets, **opts): """set revisions in %s state This command also alter state of ancestors if necessary. """ % state + if not state in repo._enabledstates: + raise error.Abort( + _('state %s is not activated' % state), + hint=_('try ``hg states %s`` before' % state)) + if opts.get('exact'): + repo.setstate_unsafe(state, changesets) + return 0 revs = scmutil.revrange(repo, changesets) repo.setstate(state, [repo.changelog.node(rev) for rev in revs]) return 0 return cmdmoveheads for state in STATES: - if state.trackheads: - cmdmoveheads = makecmd(state) - cmdtable[state.name] = (cmdmoveheads, [], '') + cmdmoveheads = makecmd(state) + cmdtable[state.name] = (cmdmoveheads, [ + ('e', 'exact', False, _('move boundary so that revs are exactly in ' + 'state ( all([rev.state == for ' + 'rev in revs]))')) + ], '') # Pushkey mechanism for mutable ######################################### @@ -795,6 +803,32 @@ """{ state-object -> set(defining head)} mapping""" return _readstatesheads(self) + def setstate_unsafe(self, state, changesets): + """Change state of targets changesets and it's ancestors. + + Simplify the list of heads. + + Unlike ``setstate``, the "lower" states are also changed + """ + #modify "lower" states + req_nodes_rst = '|'.join('((%s)::)' % rst for rst in changesets) + for st in STATES: + if st >= state: # only modify lower state heads for now + continue + try: + heads = self._statesheads[st] + except KeyError: # forget non-activated states + continue + olds = heads[:] + rst = "heads((::%s()) - (%s))" % (st.headssymbol, req_nodes_rst) + heads[:] = noderange(repo, [rst]) + if olds != heads: + _writestateshead(self) + #modify the state + if state in self._statesheads: + revs = scmutil.revrange(repo, changesets) + repo.setstate(state, [repo.changelog.node(rev) for rev in revs]) + def setstate(self, state, nodes): """change state of targets changeset and it's ancestors. diff -r 5dcece86aeb0 -r d5170cc7881c tests/test-states-exact.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-states-exact.t Sun Sep 25 12:43:00 2011 +0200 @@ -0,0 +1,282 @@ + $ cat >> $HGRCPATH < [web] + > push_ssl = false + > allow_push = * + > [extensions] + > EOF + $ echo "states=$(echo $(dirname $TESTDIR))/hgext/states.py" >> $HGRCPATH + + $ mkcommit() { + > echo "$1" > "$1" + > hg add "$1" + > hg ci -m "$1" + > } + $ alias hglog='hg log --template "{desc|short} {rev} {state}\n"' + + $ hg init alpha + $ cd alpha + $ hg states ready draft + $ mkcommit a + $ mkcommit b + $ mkcommit c + $ mkcommit d + $ mkcommit e + $ mkcommit f + +|0 - 1 - 2 - 3 - 4 - 5 + + $ hg ready 3 + $ hg published 1 + $ hglog + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 published + a 0 published + +very simple case + $ hg ready --exact 1 + $ hglog + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 published + +required state not in statesheads + $ hg draft --exact 3 + $ hglog + f 5 draft + e 4 draft + d 3 draft + c 2 ready + b 1 ready + a 0 published + +remove all other states + $ hg draft --exact 0 + $ hglog + f 5 draft + e 4 draft + d 3 draft + c 2 draft + b 1 draft + a 0 draft + +draft was not there before + $ hg ready 5 + $ hg draft --exact 4 + $ hglog + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 ready + +already in the required state + $ hg draft --exact 5 + $ hglog + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 ready + +backward and foreward + $ hg published 1 + $ hg ready --exact 1:4 + $ hglog + f 5 draft + e 4 ready + d 3 ready + c 2 ready + b 1 ready + a 0 published + +with complex revset + $ hg draft --exact 'readyheads()' + $ hglog + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 published + $ hg ready --exact 'publishedheads()' + $ hglog + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 ready + +Work with branches now + $ hg up 1 + 0 files updated, 0 files merged, 4 files removed, 0 files unresolved + $ mkcommit g + created new head + $ mkcommit h + $ hg up 3 + 2 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ mkcommit i + created new head + $ mkcommit j + +| / - - - - 6 - 7 +|0 - 1 - 2 - 3 - 4 - 5 +| \ - - - - - - - - - - - - 8 - 9 + +Set the new branches as ready + $ hg ready 9 7 + $ hglog + j 9 ready + i 8 ready + h 7 ready + g 6 ready + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 ready + +with composite revset + $ hg draft --exact 5:5 7:8 + $ hglog + j 9 draft + i 8 draft + h 7 draft + g 6 ready + f 5 draft + e 4 draft + d 3 ready + c 2 ready + b 1 ready + a 0 ready + +cross braches + $ hg published 5 7 9 + $ hg draft --exact 4:6 + $ hglog + j 9 published + i 8 published + h 7 draft + g 6 draft + f 5 draft + e 4 draft + d 3 published + c 2 published + b 1 published + a 0 published + +Ok more complicated stuffs + $ hg up 7 + 2 files updated, 0 files merged, 4 files removed, 0 files unresolved + $ mkcommit k + $ hg published 5 9 10 + +| / - - - - 6 - 7 - - - - - 10 +|0 - 1 - 2 - 3 - 4 - 5 +| \ - - - - - - - - - - - - 8 - 9 + +cross branches and propagation on the same branche + $ hg draft --exact 5:8 + $ hglog + k 10 draft + j 9 draft + i 8 draft + h 7 draft + g 6 draft + f 5 draft + e 4 published + d 3 published + c 2 published + b 1 published + a 0 published + + +cross branches and propagation on multiple branches + $ hg published 10 + $ hg ready --exact 3 6:8 + $ hglog + k 10 ready + j 9 draft + i 8 ready + h 7 ready + g 6 ready + f 5 draft + e 4 ready + d 3 ready + c 2 published + b 1 published + a 0 published + +propagate ready on multiple branches taht contains draft states + $ hg ready --exact 1 + $ hglog + k 10 ready + j 9 draft + i 8 ready + h 7 ready + g 6 ready + f 5 draft + e 4 ready + d 3 ready + c 2 ready + b 1 ready + a 0 published + +brute propagation + $ hg draft --exact 0 + $ hglog + k 10 draft + j 9 draft + i 8 draft + h 7 draft + g 6 draft + f 5 draft + e 4 draft + d 3 draft + c 2 draft + b 1 draft + a 0 draft + +forget non activated state + $ hg init beta + $ cd beta + $ hg states draft + $ mkcommit a + $ mkcommit b + $ mkcommit c + $ mkcommit d + $ mkcommit e + $ mkcommit f + $ hg published 5 + $ hg draft --exact 3 + $ hglog + f 5 draft + e 4 draft + d 3 draft + c 2 published + b 1 published + a 0 published + $ hg states + published + draft + $ hg ready 3 + abort: state ready is not activated + (try ``hg states ready`` before) + [255] + $ hglog + f 5 draft + e 4 draft + d 3 draft + c 2 published + b 1 published + a 0 published +