Show More
@@ -223,17 +223,9 b' class GitCommit(base.BaseCommit):' | |||||
223 | """ |
|
223 | """ | |
224 | Returns list of child commits. |
|
224 | Returns list of child commits. | |
225 | """ |
|
225 | """ | |
226 | rev_filter = settings.GIT_REV_FILTER |
|
|||
227 | output, __ = self.repository.run_git_command( |
|
|||
228 | ['rev-list', '--children'] + rev_filter) |
|
|||
229 |
|
226 | |||
230 | child_ids = [] |
|
227 | children = self._remote.children(self.raw_id) | |
231 | pat = re.compile(r'^%s' % self.raw_id) |
|
228 | return self._make_commits(children) | |
232 | for l in output.splitlines(): |
|
|||
233 | if pat.match(l): |
|
|||
234 | found_ids = l.split(' ')[1:] |
|
|||
235 | child_ids.extend(found_ids) |
|
|||
236 | return self._make_commits(child_ids) |
|
|||
237 |
|
229 | |||
238 | def _make_commits(self, commit_ids): |
|
230 | def _make_commits(self, commit_ids): | |
239 | def commit_maker(_commit_id): |
|
231 | def commit_maker(_commit_id): | |
@@ -271,52 +263,27 b' class GitCommit(base.BaseCommit):' | |||||
271 | """ |
|
263 | """ | |
272 | Returns history of file as reversed list of `GitCommit` objects for |
|
264 | Returns history of file as reversed list of `GitCommit` objects for | |
273 | which file at given `path` has been modified. |
|
265 | which file at given `path` has been modified. | |
274 |
|
||||
275 | TODO: This function now uses an underlying 'git' command which works |
|
|||
276 | quickly but ideally we should replace with an algorithm. |
|
|||
277 | """ |
|
266 | """ | |
278 | self._get_filectx(path) |
|
|||
279 | f_path = safe_str(path) |
|
|||
280 |
|
267 | |||
281 | # optimize for n==1, rev-list is much faster for that use-case |
|
268 | path = self._get_filectx(path) | |
282 | if limit == 1: |
|
269 | hist = self._remote.node_history(self.raw_id, path, limit) | |
283 | cmd = ['rev-list', '-1', self.raw_id, '--', f_path] |
|
|||
284 | else: |
|
|||
285 | cmd = ['log'] |
|
|||
286 | if limit: |
|
|||
287 | cmd.extend(['-n', str(safe_int(limit, 0))]) |
|
|||
288 | cmd.extend(['--pretty=format: %H', '-s', self.raw_id, '--', f_path]) |
|
|||
289 |
|
||||
290 | output, __ = self.repository.run_git_command(cmd) |
|
|||
291 | commit_ids = re.findall(r'[0-9a-fA-F]{40}', output) |
|
|||
292 |
|
||||
293 | return [ |
|
270 | return [ | |
294 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) |
|
271 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) | |
295 |
for commit_id in |
|
272 | for commit_id in hist] | |
296 |
|
273 | |||
297 | def get_file_annotate(self, path, pre_load=None): |
|
274 | def get_file_annotate(self, path, pre_load=None): | |
298 | """ |
|
275 | """ | |
299 | Returns a generator of four element tuples with |
|
276 | Returns a generator of four element tuples with | |
300 | lineno, commit_id, commit lazy loader and line |
|
277 | lineno, commit_id, commit lazy loader and line | |
|
278 | """ | |||
301 |
|
279 | |||
302 | TODO: This function now uses os underlying 'git' command which is |
|
280 | result = self._remote.node_annotate(self.raw_id, path) | |
303 | generally not good. Should be replaced with algorithm iterating |
|
|||
304 | commits. |
|
|||
305 | """ |
|
|||
306 | cmd = ['blame', '-l', '--root', '-r', self.raw_id, '--', path] |
|
|||
307 | # -l ==> outputs long shas (and we need all 40 characters) |
|
|||
308 | # --root ==> doesn't put '^' character for bounderies |
|
|||
309 | # -r commit_id ==> blames for the given commit |
|
|||
310 | output, __ = self.repository.run_git_command(cmd) |
|
|||
311 |
|
281 | |||
312 | for i, blame_line in enumerate(output.split('\n')[:-1]): |
|
282 | for ln_no, commit_id, content in result: | |
313 | line_no = i + 1 |
|
|||
314 | commit_id, line = re.split(r' ', blame_line, 1) |
|
|||
315 | yield ( |
|
283 | yield ( | |
316 |
l |
|
284 | ln_no, commit_id, | |
317 | lambda: self.repository.get_commit(commit_id=commit_id, |
|
285 | lambda: self.repository.get_commit(commit_id=commit_id, pre_load=pre_load), | |
318 | pre_load=pre_load), |
|
286 | content) | |
319 | line) |
|
|||
320 |
|
287 | |||
321 | def get_nodes(self, path): |
|
288 | def get_nodes(self, path): | |
322 |
|
289 |
@@ -549,33 +549,16 b' class GitRepository(BaseRepository):' | |||||
549 | if path1 is not None and path1 != path: |
|
549 | if path1 is not None and path1 != path: | |
550 | raise ValueError("Diff of two different paths not supported.") |
|
550 | raise ValueError("Diff of two different paths not supported.") | |
551 |
|
551 | |||
552 |
f |
|
552 | if path: | |
553 | '-U%s' % context, '--full-index', '--binary', '-p', |
|
553 | file_filter = path | |
554 | '-M', '--abbrev=40'] |
|
|||
555 | if ignore_whitespace: |
|
|||
556 | flags.append('-w') |
|
|||
557 |
|
||||
558 | if commit1 == self.EMPTY_COMMIT: |
|
|||
559 | cmd = ['show'] + flags + [commit2.raw_id] |
|
|||
560 | else: |
|
554 | else: | |
561 | cmd = ['diff'] + flags + [commit1.raw_id, commit2.raw_id] |
|
555 | file_filter = None | |
562 |
|
||||
563 | if path: |
|
|||
564 | cmd.extend(['--', path]) |
|
|||
565 |
|
556 | |||
566 | stdout, __ = self.run_git_command(cmd) |
|
557 | diff = self._remote.diff( | |
567 | # If we used 'show' command, strip first few lines (until actual diff |
|
558 | commit1.raw_id, commit2.raw_id, file_filter=file_filter, | |
568 | # starts) |
|
559 | opt_ignorews=ignore_whitespace, | |
569 | if commit1 == self.EMPTY_COMMIT: |
|
560 | context=context) | |
570 | lines = stdout.splitlines() |
|
561 | return GitDiff(diff) | |
571 | x = 0 |
|
|||
572 | for line in lines: |
|
|||
573 | if line.startswith('diff'): |
|
|||
574 | break |
|
|||
575 | x += 1 |
|
|||
576 | # Append new line just like 'diff' command do |
|
|||
577 | stdout = '\n'.join(lines[x:]) + '\n' |
|
|||
578 | return GitDiff(stdout) |
|
|||
579 |
|
562 | |||
580 | def strip(self, commit_id, branch_name): |
|
563 | def strip(self, commit_id, branch_name): | |
581 | commit = self.get_commit(commit_id=commit_id) |
|
564 | commit = self.get_commit(commit_id=commit_id) |
@@ -266,8 +266,7 b' class MercurialCommit(base.BaseCommit):' | |||||
266 | for ln_no, commit_id, content in result: |
|
266 | for ln_no, commit_id, content in result: | |
267 | yield ( |
|
267 | yield ( | |
268 | ln_no, commit_id, |
|
268 | ln_no, commit_id, | |
269 | lambda: self.repository.get_commit(commit_id=commit_id, |
|
269 | lambda: self.repository.get_commit(commit_id=commit_id, pre_load=pre_load), | |
270 | pre_load=pre_load), |
|
|||
271 | content) |
|
270 | content) | |
272 |
|
271 | |||
273 | def get_nodes(self, path): |
|
272 | def get_nodes(self, path): |
@@ -1065,37 +1065,35 b' class TestGitSpecificWithRepo(BackendTes' | |||||
1065 |
|
1065 | |||
1066 | def test_paths_fast_traversing(self): |
|
1066 | def test_paths_fast_traversing(self): | |
1067 | commit = self.repo.get_commit() |
|
1067 | commit = self.repo.get_commit() | |
1068 | assert ( |
|
1068 | assert commit.get_node('foobar/static/js/admin/base.js').content == 'base' | |
1069 | commit.get_node('foobar/static/js/admin/base.js').content == |
|
|||
1070 | 'base') |
|
|||
1071 |
|
1069 | |||
1072 | def test_get_diff_runs_git_command_with_hashes(self): |
|
1070 | def test_get_diff_runs_git_command_with_hashes(self): | |
1073 | comm1 = self.repo[0] |
|
1071 | comm1 = self.repo[0] | |
1074 | comm2 = self.repo[1] |
|
1072 | comm2 = self.repo[1] | |
1075 | self.repo.run_git_command = mock.Mock(return_value=['', '']) |
|
1073 | ||
|
1074 | with mock.patch.object(self.repo, '_remote') as remote_mock: | |||
1076 | self.repo.get_diff(comm1, comm2) |
|
1075 | self.repo.get_diff(comm1, comm2) | |
1077 |
|
1076 | |||
1078 |
|
|
1077 | remote_mock.diff.assert_called_once_with( | |
1079 | ['diff', '-U3', '--full-index', '--binary', '-p', '-M', |
|
1078 | comm1.raw_id, comm2.raw_id, | |
1080 | '--abbrev=40', comm1.raw_id, comm2.raw_id]) |
|
1079 | file_filter=None, opt_ignorews=False, context=3) | |
1081 |
|
1080 | |||
1082 | def test_get_diff_runs_git_command_with_str_hashes(self): |
|
1081 | def test_get_diff_runs_git_command_with_str_hashes(self): | |
1083 | comm2 = self.repo[1] |
|
1082 | comm2 = self.repo[1] | |
1084 | self.repo.run_git_command = mock.Mock(return_value=['', '']) |
|
1083 | with mock.patch.object(self.repo, '_remote') as remote_mock: | |
1085 | self.repo.get_diff(self.repo.EMPTY_COMMIT, comm2) |
|
1084 | self.repo.get_diff(self.repo.EMPTY_COMMIT, comm2) | |
1086 |
|
|
1085 | remote_mock.diff.assert_called_once_with( | |
1087 | ['show', '-U3', '--full-index', '--binary', '-p', '-M', |
|
1086 | self.repo.EMPTY_COMMIT.raw_id, comm2.raw_id, | |
1088 | '--abbrev=40', comm2.raw_id]) |
|
1087 | file_filter=None, opt_ignorews=False, context=3) | |
1089 |
|
1088 | |||
1090 | def test_get_diff_runs_git_command_with_path_if_its_given(self): |
|
1089 | def test_get_diff_runs_git_command_with_path_if_its_given(self): | |
1091 | comm1 = self.repo[0] |
|
1090 | comm1 = self.repo[0] | |
1092 | comm2 = self.repo[1] |
|
1091 | comm2 = self.repo[1] | |
1093 | self.repo.run_git_command = mock.Mock(return_value=['', '']) |
|
1092 | with mock.patch.object(self.repo, '_remote') as remote_mock: | |
1094 | self.repo.get_diff(comm1, comm2, 'foo') |
|
1093 | self.repo.get_diff(comm1, comm2, 'foo') | |
1095 |
|
|
1094 | remote_mock.diff.assert_called_once_with( | |
1096 | ['diff', '-U3', '--full-index', '--binary', '-p', '-M', |
|
1095 | self.repo._lookup_commit(0), comm2.raw_id, | |
1097 | '--abbrev=40', self.repo._lookup_commit(0), |
|
1096 | file_filter='foo', opt_ignorews=False, context=3) | |
1098 | comm2.raw_id, '--', 'foo']) |
|
|||
1099 |
|
1097 | |||
1100 |
|
1098 | |||
1101 | @pytest.mark.usefixtures("vcs_repository_support") |
|
1099 | @pytest.mark.usefixtures("vcs_repository_support") |
General Comments 0
You need to be logged in to leave comments.
Login now