123 if windowsize < sizelimit: |
123 if windowsize < sizelimit: |
124 windowsize *= 2 |
124 windowsize *= 2 |
125 |
125 |
126 |
126 |
127 files, matchfn, anypats = matchpats(repo, pats, opts) |
127 files, matchfn, anypats = matchpats(repo, pats, opts) |
|
128 follow = opts.get('follow') |
128 |
129 |
129 if repo.changelog.count() == 0: |
130 if repo.changelog.count() == 0: |
130 return [], False, matchfn |
131 return [], False, matchfn |
131 |
132 |
132 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0'])) |
133 revs = map(int, revrange(ui, repo, opts['rev'] or ['tip:0'])) |
142 return ch |
143 return ch |
143 |
144 |
144 if not slowpath and not files: |
145 if not slowpath and not files: |
145 # No files, no patterns. Display all revs. |
146 # No files, no patterns. Display all revs. |
146 wanted = dict(zip(revs, revs)) |
147 wanted = dict(zip(revs, revs)) |
|
148 copies = [] |
147 if not slowpath: |
149 if not slowpath: |
148 # Only files, no patterns. Check the history of each file. |
150 # Only files, no patterns. Check the history of each file. |
149 def filerevgen(filelog): |
151 def filerevgen(filelog, node): |
150 cl_count = repo.changelog.count() |
152 cl_count = repo.changelog.count() |
151 for i, window in increasing_windows(filelog.count()-1, -1): |
153 if node is None: |
|
154 last = filelog.count() - 1 |
|
155 else: |
|
156 last = filelog.rev(node) |
|
157 for i, window in increasing_windows(last, -1): |
152 revs = [] |
158 revs = [] |
153 for j in xrange(i - window, i + 1): |
159 for j in xrange(i - window, i + 1): |
154 revs.append(filelog.linkrev(filelog.node(j))) |
160 n = filelog.node(j) |
|
161 revs.append((filelog.linkrev(n), |
|
162 follow and filelog.renamed(n))) |
155 revs.reverse() |
163 revs.reverse() |
156 for rev in revs: |
164 for rev in revs: |
157 # only yield rev for which we have the changelog, it can |
165 # only yield rev for which we have the changelog, it can |
158 # happen while doing "hg log" during a pull or commit |
166 # happen while doing "hg log" during a pull or commit |
159 if rev < cl_count: |
167 if rev[0] < cl_count: |
160 yield rev |
168 yield rev |
161 |
169 def iterfiles(): |
|
170 for filename in files: |
|
171 yield filename, None |
|
172 for filename_node in copies: |
|
173 yield filename_node |
162 minrev, maxrev = min(revs), max(revs) |
174 minrev, maxrev = min(revs), max(revs) |
163 for file_ in files: |
175 for file_, node in iterfiles(): |
164 filelog = repo.file(file_) |
176 filelog = repo.file(file_) |
165 # A zero count may be a directory or deleted file, so |
177 # A zero count may be a directory or deleted file, so |
166 # try to find matching entries on the slow path. |
178 # try to find matching entries on the slow path. |
167 if filelog.count() == 0: |
179 if filelog.count() == 0: |
168 slowpath = True |
180 slowpath = True |
169 break |
181 break |
170 for rev in filerevgen(filelog): |
182 for rev, copied in filerevgen(filelog, node): |
171 if rev <= maxrev: |
183 if rev <= maxrev: |
172 if rev < minrev: |
184 if rev < minrev: |
173 break |
185 break |
174 fncache.setdefault(rev, []) |
186 fncache.setdefault(rev, []) |
175 fncache[rev].append(file_) |
187 fncache[rev].append(file_) |
176 wanted[rev] = 1 |
188 wanted[rev] = 1 |
|
189 if follow and copied: |
|
190 copies.append(copied) |
177 if slowpath: |
191 if slowpath: |
|
192 if follow: |
|
193 raise util.Abort(_('can only follow copies/renames for explicit ' |
|
194 'file names')) |
|
195 |
178 # The slow path checks files modified in every changeset. |
196 # The slow path checks files modified in every changeset. |
179 def changerevgen(): |
197 def changerevgen(): |
180 for i, window in increasing_windows(repo.changelog.count()-1, -1): |
198 for i, window in increasing_windows(repo.changelog.count()-1, -1): |
181 for j in xrange(i - window, i + 1): |
199 for j in xrange(i - window, i + 1): |
182 yield j, getchange(j)[3] |
200 yield j, getchange(j)[3] |
1928 ui.write(((pats and rel) or abs), end) |
1946 ui.write(((pats and rel) or abs), end) |
1929 |
1947 |
1930 def log(ui, repo, *pats, **opts): |
1948 def log(ui, repo, *pats, **opts): |
1931 """show revision history of entire repository or files |
1949 """show revision history of entire repository or files |
1932 |
1950 |
1933 Print the revision history of the specified files or the entire project. |
1951 Print the revision history of the specified files or the entire |
|
1952 project. |
|
1953 |
|
1954 File history is shown without following rename or copy history of |
|
1955 files. Use -f/--follow to follow history across renames and |
|
1956 copies. |
1934 |
1957 |
1935 By default this command outputs: changeset id and hash, tags, |
1958 By default this command outputs: changeset id and hash, tags, |
1936 non-trivial parents, user, date and time, and a summary for each |
1959 non-trivial parents, user, date and time, and a summary for each |
1937 commit. When the -v/--verbose switch is used, the list of changed |
1960 commit. When the -v/--verbose switch is used, the list of changed |
1938 files and full commit message is shown. |
1961 files and full commit message is shown. |
3041 ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
3064 ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
3042 _('hg locate [OPTION]... [PATTERN]...')), |
3065 _('hg locate [OPTION]... [PATTERN]...')), |
3043 "^log|history": |
3066 "^log|history": |
3044 (log, |
3067 (log, |
3045 [('b', 'branches', None, _('show branches')), |
3068 [('b', 'branches', None, _('show branches')), |
|
3069 ('f', 'follow', None, |
|
3070 _('follow file history across copies and renames')), |
3046 ('k', 'keyword', [], _('search for a keyword')), |
3071 ('k', 'keyword', [], _('search for a keyword')), |
3047 ('l', 'limit', '', _('limit number of changes displayed')), |
3072 ('l', 'limit', '', _('limit number of changes displayed')), |
3048 ('r', 'rev', [], _('show the specified revision or range')), |
3073 ('r', 'rev', [], _('show the specified revision or range')), |
3049 ('M', 'no-merges', None, _('do not show merges')), |
3074 ('M', 'no-merges', None, _('do not show merges')), |
3050 ('', 'style', '', _('display using template map file')), |
3075 ('', 'style', '', _('display using template map file')), |