Mercurial > hg
comparison mercurial/destutil.py @ 28385:3f9e25a42e69
destutil: choose non-closed branch head at first (BC)
Before this patch, destupdate() returns the tipmost (descendant)
branch head regardless of closed or not. But updating to closed branch
head isn't reasonable for ordinary workflow, because:
- "hg heads" doesn't show closed heads (= updated parent itself) by
default
- subsequent committing on it re-opens closed branch
even if inactivation of closed head is needed, update destination
isn't it, because it should be merged into to another branch in
such case.
This patch chooses non-closed descendant branch head as default update
destination at first. If all descendant branch heads are closed,
destupdate() returns the tipmost closed branch head.
For simplicity, this patch chooses adding _destupdatebranchfallback()
instead largely changing _destupdatebranch().
This patch changes not only normal lookup code path, but also the "no
default branch" code path, for consistency.
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Mon, 07 Mar 2016 03:14:19 +0900 |
parents | de8b09482fb7 |
children | d0210a35c81a |
comparison
equal
deleted
inserted
replaced
28384:3356bf61fa25 | 28385:3f9e25a42e69 |
---|---|
86 if node is not None: | 86 if node is not None: |
87 activemark = node | 87 activemark = node |
88 return node, movemark, activemark | 88 return node, movemark, activemark |
89 | 89 |
90 def _destupdatebranch(repo, clean, check): | 90 def _destupdatebranch(repo, clean, check): |
91 """decide on an update destination from current branch""" | 91 """decide on an update destination from current branch |
92 | |
93 This ignores closed branch heads. | |
94 """ | |
92 wc = repo[None] | 95 wc = repo[None] |
93 movemark = node = None | 96 movemark = node = None |
94 currentbranch = wc.branch() | 97 currentbranch = wc.branch() |
95 if currentbranch in repo.branchmap(): | 98 if currentbranch in repo.branchmap(): |
96 heads = repo.branchheads(currentbranch, closed=True) | 99 heads = repo.branchheads(currentbranch) |
97 if heads: | 100 if heads: |
98 node = repo.revs('max(.::(%ln))', heads).first() | 101 node = repo.revs('max(.::(%ln))', heads).first() |
99 if bookmarks.isactivewdirparent(repo): | 102 if bookmarks.isactivewdirparent(repo): |
100 movemark = repo['.'].node() | 103 movemark = repo['.'].node() |
101 else: | 104 else: |
102 if currentbranch == 'default': # no default branch! | 105 if currentbranch == 'default': # no default branch! |
103 node = repo.lookup('tip') # update to tip | 106 # update to the tipmost non-closed branch head |
107 node = repo.revs('max(head() and not closed())').first() | |
104 else: | 108 else: |
105 raise error.Abort(_("branch %s not found") % currentbranch) | 109 raise error.Abort(_("branch %s not found") % currentbranch) |
106 return node, movemark, None | 110 return node, movemark, None |
107 | 111 |
112 def _destupdatebranchfallback(repo, clean, check): | |
113 """decide on an update destination from closed heads in current branch""" | |
114 wc = repo[None] | |
115 currentbranch = wc.branch() | |
116 movemark = None | |
117 if currentbranch in repo.branchmap(): | |
118 # here, all descendant branch heads are closed | |
119 heads = repo.branchheads(currentbranch, closed=True) | |
120 assert heads, "any branch has at least one head" | |
121 node = repo.revs('max(.::(%ln))', heads).first() | |
122 assert node is not None, ("any revision has at least " | |
123 "one descendant branch head") | |
124 if bookmarks.isactivewdirparent(repo): | |
125 movemark = repo['.'].node() | |
126 else: | |
127 # here, no "default" branch, and all branches are closed | |
128 node = repo.lookup('tip') | |
129 assert node is not None, "'tip' exists even in empty repository" | |
130 return node, movemark, None | |
131 | |
108 # order in which each step should be evalutated | 132 # order in which each step should be evalutated |
109 # steps are run until one finds a destination | 133 # steps are run until one finds a destination |
110 destupdatesteps = ['evolution', 'bookmark', 'branch'] | 134 destupdatesteps = ['evolution', 'bookmark', 'branch', 'branchfallback'] |
111 # mapping to ease extension overriding steps. | 135 # mapping to ease extension overriding steps. |
112 destupdatestepmap = {'evolution': _destupdateobs, | 136 destupdatestepmap = {'evolution': _destupdateobs, |
113 'bookmark': _destupdatebook, | 137 'bookmark': _destupdatebook, |
114 'branch': _destupdatebranch, | 138 'branch': _destupdatebranch, |
139 'branchfallback': _destupdatebranchfallback, | |
115 } | 140 } |
116 | 141 |
117 def destupdate(repo, clean=False, check=False): | 142 def destupdate(repo, clean=False, check=False): |
118 """destination for bare update operation | 143 """destination for bare update operation |
119 | 144 |
360 currentbranch = repo.dirstate.branch() | 385 currentbranch = repo.dirstate.branch() |
361 allheads = repo.branchheads(currentbranch, closed=True) | 386 allheads = repo.branchheads(currentbranch, closed=True) |
362 heads = repo.branchheads(currentbranch) | 387 heads = repo.branchheads(currentbranch) |
363 if repo.revs('%ln and parents()', allheads): | 388 if repo.revs('%ln and parents()', allheads): |
364 # we are on a head, even though it might be closed | 389 # we are on a head, even though it might be closed |
390 # | |
391 # on closed otherheads | |
392 # ========= ========== | |
393 # o 0 all heads for current branch are closed | |
394 # N only descendant branch heads are closed | |
395 # x 0 there is only one non-closed branch head | |
396 # N there are some non-closed branch heads | |
397 # ========= ========== | |
365 otherheads = repo.revs('%ln - parents()', heads) | 398 otherheads = repo.revs('%ln - parents()', heads) |
366 if otherheads: | 399 if repo['.'].closesbranch(): |
400 ui.status(_('updated to a closed branch head, ' | |
401 'because all descendant heads are closed.\n' | |
402 'beware of re-opening closed head ' | |
403 'by subsequent commit here.\n')) | |
404 if otherheads: | |
405 ui.status(_('%i other heads for branch "%s"\n') % | |
406 (len(otherheads), currentbranch)) | |
407 else: | |
408 ui.status(_('all heads for branch "%s" are closed.\n') % | |
409 currentbranch) | |
410 elif otherheads: | |
367 ui.status(_('%i other heads for branch "%s"\n') % | 411 ui.status(_('%i other heads for branch "%s"\n') % |
368 (len(otherheads), currentbranch)) | 412 (len(otherheads), currentbranch)) |
369 | 413 |
370 def statusotherdests(ui, repo): | 414 def statusotherdests(ui, repo): |
371 """Print message about other head""" | 415 """Print message about other head""" |