Show More
@@ -241,9 +241,6 b' def check_unsupported_flags(pats, opts):' | |||||
241 | if op in opts and opts[op]: |
|
241 | if op in opts and opts[op]: | |
242 | raise util.Abort(_("-G/--graph option is incompatible with --%s") |
|
242 | raise util.Abort(_("-G/--graph option is incompatible with --%s") | |
243 | % op.replace("_", "-")) |
|
243 | % op.replace("_", "-")) | |
244 | if pats and opts.get('follow'): |
|
|||
245 | raise util.Abort(_("-G/--graph option is incompatible with --follow " |
|
|||
246 | "with file argument")) |
|
|||
247 |
|
244 | |||
248 | def revset(repo, pats, opts): |
|
245 | def revset(repo, pats, opts): | |
249 | """Return revset str built of revisions, log options and file patterns. |
|
246 | """Return revset str built of revisions, log options and file patterns. | |
@@ -256,6 +253,7 b' def revset(repo, pats, opts):' | |||||
256 | 'date': ('date(%(val)r)', None), |
|
253 | 'date': ('date(%(val)r)', None), | |
257 | 'branch': ('branch(%(val)r)', ' or '), |
|
254 | 'branch': ('branch(%(val)r)', ' or '), | |
258 | '_patslog': ('filelog(%(val)r)', ' or '), |
|
255 | '_patslog': ('filelog(%(val)r)', ' or '), | |
|
256 | '_patsfollow': ('follow(%(val)r)', ' or '), | |||
259 | 'keyword': ('keyword(%(val)r)', ' or '), |
|
257 | 'keyword': ('keyword(%(val)r)', ' or '), | |
260 | 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '), |
|
258 | 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '), | |
261 | 'user': ('user(%(val)r)', ' or '), |
|
259 | 'user': ('user(%(val)r)', ' or '), | |
@@ -268,22 +266,35 b' def revset(repo, pats, opts):' | |||||
268 | if 'branch' in opts and 'only_branch' in opts: |
|
266 | if 'branch' in opts and 'only_branch' in opts: | |
269 | opts['branch'] = opts['branch'] + opts.pop('only_branch') |
|
267 | opts['branch'] = opts['branch'] + opts.pop('only_branch') | |
270 |
|
268 | |||
|
269 | follow = opts.get('follow') | |||
|
270 | if 'follow' in opts: | |||
|
271 | del opts['follow'] | |||
271 | # pats/include/exclude are passed to match.match() directly in |
|
272 | # pats/include/exclude are passed to match.match() directly in | |
272 | # _matchfile() revset but walkchangerevs() builds its matcher with |
|
273 | # _matchfile() revset but walkchangerevs() builds its matcher with | |
273 | # scmutil.match(). The difference is input pats are globbed on |
|
274 | # scmutil.match(). The difference is input pats are globbed on | |
274 | # platforms without shell expansion (windows). |
|
275 | # platforms without shell expansion (windows). | |
275 | match, pats = scmutil.matchandpats(repo[None], pats, opts) |
|
276 | pctx = repo[None] | |
|
277 | match, pats = scmutil.matchandpats(pctx, pats, opts) | |||
276 | slowpath = match.anypats() or (match.files() and opts.get('removed')) |
|
278 | slowpath = match.anypats() or (match.files() and opts.get('removed')) | |
277 | if not slowpath: |
|
279 | if not slowpath: | |
278 | for f in match.files(): |
|
280 | for f in match.files(): | |
|
281 | if follow and f not in pctx: | |||
|
282 | raise util.Abort(_('cannot follow file not in parent ' | |||
|
283 | 'revision: "%s"') % f) | |||
279 | filelog = repo.file(f) |
|
284 | filelog = repo.file(f) | |
280 | if not len(filelog): |
|
285 | if not len(filelog): | |
281 | # A zero count may be a directory or deleted file, so |
|
286 | # A zero count may be a directory or deleted file, so | |
282 | # try to find matching entries on the slow path. |
|
287 | # try to find matching entries on the slow path. | |
|
288 | if follow: | |||
|
289 | raise util.Abort( | |||
|
290 | _('cannot follow nonexistent file: "%s"') % f) | |||
283 | slowpath = True |
|
291 | slowpath = True | |
284 | if slowpath: |
|
292 | if slowpath: | |
285 | # See cmdutil.walkchangerevs() slow path. |
|
293 | # See cmdutil.walkchangerevs() slow path. | |
286 | # |
|
294 | # | |
|
295 | if follow: | |||
|
296 | raise util.Abort(_('can only follow copies/renames for explicit ' | |||
|
297 | 'filenames')) | |||
287 | # pats/include/exclude cannot be represented as separate |
|
298 | # pats/include/exclude cannot be represented as separate | |
288 | # revset expressions as their filtering logic applies at file |
|
299 | # revset expressions as their filtering logic applies at file | |
289 | # level. For instance "-I a -X a" matches a revision touching |
|
300 | # level. For instance "-I a -X a" matches a revision touching | |
@@ -298,7 +309,13 b' def revset(repo, pats, opts):' | |||||
298 | matchargs = ','.join(('%r' % p) for p in matchargs) |
|
309 | matchargs = ','.join(('%r' % p) for p in matchargs) | |
299 | opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs] |
|
310 | opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs] | |
300 | else: |
|
311 | else: | |
301 | opts['_patslog'] = list(pats) |
|
312 | if follow: | |
|
313 | if pats: | |||
|
314 | opts['_patsfollow'] = list(pats) | |||
|
315 | else: | |||
|
316 | opts['follow'] = True | |||
|
317 | else: | |||
|
318 | opts['_patslog'] = list(pats) | |||
302 |
|
319 | |||
303 | revset = [] |
|
320 | revset = [] | |
304 | for op, val in opts.iteritems(): |
|
321 | for op, val in opts.iteritems(): |
@@ -1454,8 +1454,6 b' glog always reorders nodes which explain' | |||||
1454 | ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch'))))) |
|
1454 | ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch'))))) | |
1455 | $ testlog -k expand -k merge |
|
1455 | $ testlog -k expand -k merge | |
1456 | ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge'))))) |
|
1456 | ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge'))))) | |
1457 | $ hg log -G --follow --template 'nodetag {rev}\n' | grep nodetag | wc -l |
|
|||
1458 | \s*36 (re) |
|
|||
1459 | $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l |
|
1457 | $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l | |
1460 | \s*0 (re) |
|
1458 | \s*0 (re) | |
1461 | $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l |
|
1459 | $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l | |
@@ -1492,27 +1490,30 b' glog always reorders nodes which explain' | |||||
1492 | [255] |
|
1490 | [255] | |
1493 | $ testlog --prune 31 --prune 32 |
|
1491 | $ testlog --prune 31 --prune 32 | |
1494 | ('group', ('group', ('and', ('not', ('group', ('or', ('string', '31'), ('func', ('symbol', 'ancestors'), ('string', '31'))))), ('not', ('group', ('or', ('string', '32'), ('func', ('symbol', 'ancestors'), ('string', '32')))))))) |
|
1492 | ('group', ('group', ('and', ('not', ('group', ('or', ('string', '31'), ('func', ('symbol', 'ancestors'), ('string', '31'))))), ('not', ('group', ('or', ('string', '32'), ('func', ('symbol', 'ancestors'), ('string', '32')))))))) | |
1495 | $ hg log -G --follow a |
|
|||
1496 | abort: -G/--graph option is incompatible with --follow with file argument |
|
|||
1497 | [255] |
|
|||
1498 |
|
1493 | |||
1499 |
|
1494 | Dedicated repo for --follow and paths filtering. The g is crafted to | ||
1500 | Dedicated repo for --follow and paths filtering |
|
1495 | have 2 filelog topological heads in a linear changeset graph. | |
1501 |
|
1496 | |||
1502 | $ cd .. |
|
1497 | $ cd .. | |
1503 | $ hg init follow |
|
1498 | $ hg init follow | |
1504 | $ cd follow |
|
1499 | $ cd follow | |
1505 | $ echo a > a |
|
1500 | $ echo a > a | |
1506 | $ echo aa > aa |
|
1501 | $ echo aa > aa | |
|
1502 | $ echo f > f | |||
1507 | $ hg ci -Am "add a" |
|
1503 | $ hg ci -Am "add a" | |
1508 | adding a |
|
1504 | adding a | |
1509 | adding aa |
|
1505 | adding aa | |
|
1506 | adding f | |||
1510 | $ hg cp a b |
|
1507 | $ hg cp a b | |
|
1508 | $ hg cp f g | |||
1511 | $ hg ci -m "copy a b" |
|
1509 | $ hg ci -m "copy a b" | |
1512 | $ mkdir dir |
|
1510 | $ mkdir dir | |
1513 | $ hg mv b dir |
|
1511 | $ hg mv b dir | |
|
1512 | $ echo g >> g | |||
|
1513 | $ echo f >> f | |||
1514 | $ hg ci -m "mv b dir/b" |
|
1514 | $ hg ci -m "mv b dir/b" | |
1515 | $ hg mv a b |
|
1515 | $ hg mv a b | |
|
1516 | $ hg cp -f f g | |||
1516 | $ echo a > d |
|
1517 | $ echo a > d | |
1517 | $ hg add d |
|
1518 | $ hg add d | |
1518 | $ hg ci -m "mv a b; add d" |
|
1519 | $ hg ci -m "mv a b; add d" | |
@@ -1555,3 +1556,65 b' Test glob expansion of pats' | |||||
1555 | > testlog a*; |
|
1556 | > testlog a*; | |
1556 | > fi; |
|
1557 | > fi; | |
1557 | ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'aa')))) |
|
1558 | ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'aa')))) | |
|
1559 | ||||
|
1560 | Test --follow on a directory | |||
|
1561 | ||||
|
1562 | $ testlog -f dir | |||
|
1563 | abort: cannot follow file not in parent revision: "dir" | |||
|
1564 | abort: cannot follow file not in parent revision: "dir" | |||
|
1565 | abort: cannot follow file not in parent revision: "dir" | |||
|
1566 | ||||
|
1567 | Test --follow on file not in parent revision | |||
|
1568 | ||||
|
1569 | $ testlog -f a | |||
|
1570 | abort: cannot follow file not in parent revision: "a" | |||
|
1571 | abort: cannot follow file not in parent revision: "a" | |||
|
1572 | abort: cannot follow file not in parent revision: "a" | |||
|
1573 | ||||
|
1574 | Test --follow and patterns | |||
|
1575 | ||||
|
1576 | $ testlog -f 'glob:*' | |||
|
1577 | abort: can only follow copies/renames for explicit filenames | |||
|
1578 | abort: can only follow copies/renames for explicit filenames | |||
|
1579 | abort: can only follow copies/renames for explicit filenames | |||
|
1580 | ||||
|
1581 | Test --follow on a single rename | |||
|
1582 | ||||
|
1583 | $ hg up -q 2 | |||
|
1584 | $ testlog -f a | |||
|
1585 | ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'a')))) | |||
|
1586 | ||||
|
1587 | Test --follow and multiple renames | |||
|
1588 | ||||
|
1589 | $ hg up -q tip | |||
|
1590 | $ testlog -f e | |||
|
1591 | ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'e')))) | |||
|
1592 | ||||
|
1593 | Test --follow and multiple filelog heads | |||
|
1594 | ||||
|
1595 | $ hg up -q 2 | |||
|
1596 | $ testlog -f g | |||
|
1597 | ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'g')))) | |||
|
1598 | $ cat log.nodes | |||
|
1599 | nodetag 2 | |||
|
1600 | nodetag 1 | |||
|
1601 | nodetag 0 | |||
|
1602 | $ hg up -q tip | |||
|
1603 | $ testlog -f g | |||
|
1604 | ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'g')))) | |||
|
1605 | $ cat log.nodes | |||
|
1606 | nodetag 3 | |||
|
1607 | nodetag 2 | |||
|
1608 | nodetag 0 | |||
|
1609 | ||||
|
1610 | Test --follow and multiple files | |||
|
1611 | ||||
|
1612 | $ testlog -f g e | |||
|
1613 | ('group', ('group', ('or', ('func', ('symbol', 'follow'), ('string', 'g')), ('func', ('symbol', 'follow'), ('string', 'e'))))) | |||
|
1614 | $ cat log.nodes | |||
|
1615 | nodetag 4 | |||
|
1616 | nodetag 3 | |||
|
1617 | nodetag 2 | |||
|
1618 | nodetag 1 | |||
|
1619 | nodetag 0 | |||
|
1620 |
General Comments 0
You need to be logged in to leave comments.
Login now