changeset 2782:0148869345f7

merge with self.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Fri, 04 Aug 2006 10:38:17 -0700
parents a9fadbef21e9 (diff) ae726521717c (current diff)
children 6b27a7125b67
files
diffstat 3 files changed, 178 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -125,12 +125,22 @@ def walkchangerevs(ui, repo, pats, opts)
 
 
     files, matchfn, anypats = matchpats(repo, pats, opts)
-    follow = opts.get('follow')
+    follow = opts.get('follow') or opts.get('follow_first')
 
     if repo.changelog.count() == 0:
         return [], False, matchfn
 
-    revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0']))
+    if follow:
+        p = repo.dirstate.parents()[0]
+        if p == nullid:
+            ui.warn(_('No working directory revision; defaulting to tip\n'))
+            start = 'tip'
+        else:
+            start = repo.changelog.rev(p)
+        defrange = '%s:0' % start
+    else:
+        defrange = 'tip:0'
+    revs = map(int, revrange(ui, repo, opts['rev'] or [defrange]))
     wanted = {}
     slowpath = anypats
     fncache = {}
@@ -206,10 +216,55 @@ def walkchangerevs(ui, repo, pats, opts)
                 wanted[rev] = 1
 
     def iterate():
+        class followfilter:
+            def __init__(self, onlyfirst=False):
+                self.startrev = -1
+                self.roots = []
+                self.onlyfirst = onlyfirst
+
+            def match(self, rev):
+                def realparents(rev):
+                    if self.onlyfirst:
+                        return repo.changelog.parentrevs(rev)[0:1]
+                    else:
+                        return filter(lambda x: x != -1, repo.changelog.parentrevs(rev))
+
+                if self.startrev == -1:
+                    self.startrev = rev
+                    return True
+
+                if rev > self.startrev:
+                    # forward: all descendants
+                    if not self.roots:
+                        self.roots.append(self.startrev)
+                    for parent in realparents(rev):
+                        if parent in self.roots:
+                            self.roots.append(rev)
+                            return True
+                else:
+                    # backwards: all parents
+                    if not self.roots:
+                        self.roots.extend(realparents(self.startrev))
+                    if rev in self.roots:
+                        self.roots.remove(rev)
+                        self.roots.extend(realparents(rev))
+                        return True
+
+                return False
+
+        if follow and not files:
+            ff = followfilter(onlyfirst=opts.get('follow_first'))
+            def want(rev):
+                if rev not in wanted:
+                    return False
+                return ff.match(rev)
+        else:
+            def want(rev):
+                return rev in wanted
+
         for i, window in increasing_windows(0, len(revs)):
             yield 'window', revs[0] < revs[-1], revs[-1]
-            nrevs = [rev for rev in revs[i:i+window]
-                     if rev in wanted]
+            nrevs = [rev for rev in revs[i:i+window] if want(rev)]
             srevs = list(nrevs)
             srevs.sort()
             for rev in srevs:
@@ -1972,8 +2027,14 @@ def log(ui, repo, *pats, **opts):
     project.
 
     File history is shown without following rename or copy history of
-    files.  Use -f/--follow to follow history across renames and
-    copies.
+    files.  Use -f/--follow with a file name to follow history across
+    renames and copies. --follow without a file name will only show
+    ancestors or descendants of the starting revision. --follow-first
+    only follows the first parent of merge revisions.
+
+    If no revision range is specified, the default is tip:0 unless
+    --follow is set, in which case the working directory parent is
+    used as the starting revision.
 
     By default this command outputs: changeset id and hash, tags,
     non-trivial parents, user, date and time, and a summary for each
@@ -3087,7 +3148,9 @@ table = {
         (log,
          [('b', 'branches', None, _('show branches')),
           ('f', 'follow', None,
-           _('follow file history across copies and renames')),
+           _('follow changeset history, or file history across copies and renames')),
+          ('', 'follow-first', None,
+           _('only follow the first parent of merge changesets')),
           ('k', 'keyword', [], _('search for a keyword')),
           ('l', 'limit', '', _('limit number of changes displayed')),
           ('r', 'rev', [], _('show the specified revision or range')),
--- a/tests/test-log
+++ b/tests/test-log
@@ -28,3 +28,38 @@ echo % one rename
 hg log -vf a
 echo % many renames
 hg log -vf e
+
+# log --follow tests
+hg init ../follow
+cd ../follow
+echo base > base
+hg ci -Ambase -d '1 0'
+
+echo r1 >> base
+hg ci -Amr1 -d '1 0'
+echo r2 >> base
+hg ci -Amr2 -d '1 0'
+
+hg up -C 1
+echo b1 > b1
+hg ci -Amb1 -d '1 0'
+
+echo % log -f
+hg log -f
+
+hg up -C 0
+echo b2 > b2
+hg ci -Amb2 -d '1 0'
+
+echo % log -f -r 1:tip
+hg log -f -r 1:tip
+
+hg up -C 3
+hg merge tip
+hg ci -mm12 -d '1 0'
+
+echo postm >> b1
+hg ci -Amb1.1 -d'1 0'
+
+echo % log --follow-first
+hg log --follow-first
--- a/tests/test-log.out
+++ b/tests/test-log.out
@@ -76,3 +76,76 @@ description:
 a
 
 
+adding base
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+adding b1
+% log -f
+changeset:   3:e62f78d544b4
+tag:         tip
+parent:      1:3d5bf5654eda
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     b1
+
+changeset:   1:3d5bf5654eda
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     r1
+
+changeset:   0:67e992f2c4f3
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     base
+
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+adding b2
+% log -f -r 1:tip
+changeset:   1:3d5bf5654eda
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     r1
+
+changeset:   2:60c670bf5b30
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     r2
+
+changeset:   3:e62f78d544b4
+parent:      1:3d5bf5654eda
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     b1
+
+2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+% log --follow-first
+changeset:   6:2404bbcab562
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     b1.1
+
+changeset:   5:302e9dd6890d
+parent:      3:e62f78d544b4
+parent:      4:ddb82e70d1a1
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     m12
+
+changeset:   3:e62f78d544b4
+parent:      1:3d5bf5654eda
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     b1
+
+changeset:   1:3d5bf5654eda
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     r1
+
+changeset:   0:67e992f2c4f3
+user:        test
+date:        Thu Jan 01 00:00:01 1970 +0000
+summary:     base
+