##// END OF EJS Templates
git: replaced some raw subprocess commands with dedicated GIT vcsserver commands.
marcink -
r3862:44edb079 default
parent child Browse files
Show More
@@ -223,17 +223,9 b' class GitCommit(base.BaseCommit):'
223 223 """
224 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 = []
231 pat = re.compile(r'^%s' % self.raw_id)
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)
227 children = self._remote.children(self.raw_id)
228 return self._make_commits(children)
237 229
238 230 def _make_commits(self, commit_ids):
239 231 def commit_maker(_commit_id):
@@ -271,52 +263,27 b' class GitCommit(base.BaseCommit):'
271 263 """
272 264 Returns history of file as reversed list of `GitCommit` objects for
273 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
282 if limit == 1:
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
268 path = self._get_filectx(path)
269 hist = self._remote.node_history(self.raw_id, path, limit)
293 270 return [
294 271 self.repository.get_commit(commit_id=commit_id, pre_load=pre_load)
295 for commit_id in commit_ids]
272 for commit_id in hist]
296 273
297 274 def get_file_annotate(self, path, pre_load=None):
298 275 """
299 276 Returns a generator of four element tuples with
300 277 lineno, commit_id, commit lazy loader and line
278 """
301 279
302 TODO: This function now uses os underlying 'git' command which is
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)
280 result = self._remote.node_annotate(self.raw_id, path)
311 281
312 for i, blame_line in enumerate(output.split('\n')[:-1]):
313 line_no = i + 1
314 commit_id, line = re.split(r' ', blame_line, 1)
282 for ln_no, commit_id, content in result:
315 283 yield (
316 line_no, commit_id,
317 lambda: self.repository.get_commit(commit_id=commit_id,
318 pre_load=pre_load),
319 line)
284 ln_no, commit_id,
285 lambda: self.repository.get_commit(commit_id=commit_id, pre_load=pre_load),
286 content)
320 287
321 288 def get_nodes(self, path):
322 289
@@ -549,33 +549,16 b' class GitRepository(BaseRepository):'
549 549 if path1 is not None and path1 != path:
550 550 raise ValueError("Diff of two different paths not supported.")
551 551
552 flags = [
553 '-U%s' % context, '--full-index', '--binary', '-p',
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]
552 if path:
553 file_filter = path
560 554 else:
561 cmd = ['diff'] + flags + [commit1.raw_id, commit2.raw_id]
562
563 if path:
564 cmd.extend(['--', path])
555 file_filter = None
565 556
566 stdout, __ = self.run_git_command(cmd)
567 # If we used 'show' command, strip first few lines (until actual diff
568 # starts)
569 if commit1 == self.EMPTY_COMMIT:
570 lines = stdout.splitlines()
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)
557 diff = self._remote.diff(
558 commit1.raw_id, commit2.raw_id, file_filter=file_filter,
559 opt_ignorews=ignore_whitespace,
560 context=context)
561 return GitDiff(diff)
579 562
580 563 def strip(self, commit_id, branch_name):
581 564 commit = self.get_commit(commit_id=commit_id)
@@ -266,8 +266,7 b' class MercurialCommit(base.BaseCommit):'
266 266 for ln_no, commit_id, content in result:
267 267 yield (
268 268 ln_no, commit_id,
269 lambda: self.repository.get_commit(commit_id=commit_id,
270 pre_load=pre_load),
269 lambda: self.repository.get_commit(commit_id=commit_id, pre_load=pre_load),
271 270 content)
272 271
273 272 def get_nodes(self, path):
@@ -1065,37 +1065,35 b' class TestGitSpecificWithRepo(BackendTes'
1065 1065
1066 1066 def test_paths_fast_traversing(self):
1067 1067 commit = self.repo.get_commit()
1068 assert (
1069 commit.get_node('foobar/static/js/admin/base.js').content ==
1070 'base')
1068 assert commit.get_node('foobar/static/js/admin/base.js').content == 'base'
1071 1069
1072 1070 def test_get_diff_runs_git_command_with_hashes(self):
1073 1071 comm1 = self.repo[0]
1074 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 1075 self.repo.get_diff(comm1, comm2)
1077 1076
1078 self.repo.run_git_command.assert_called_once_with(
1079 ['diff', '-U3', '--full-index', '--binary', '-p', '-M',
1080 '--abbrev=40', comm1.raw_id, comm2.raw_id])
1077 remote_mock.diff.assert_called_once_with(
1078 comm1.raw_id, comm2.raw_id,
1079 file_filter=None, opt_ignorews=False, context=3)
1081 1080
1082 1081 def test_get_diff_runs_git_command_with_str_hashes(self):
1083 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 1084 self.repo.get_diff(self.repo.EMPTY_COMMIT, comm2)
1086 self.repo.run_git_command.assert_called_once_with(
1087 ['show', '-U3', '--full-index', '--binary', '-p', '-M',
1088 '--abbrev=40', comm2.raw_id])
1085 remote_mock.diff.assert_called_once_with(
1086 self.repo.EMPTY_COMMIT.raw_id, comm2.raw_id,
1087 file_filter=None, opt_ignorews=False, context=3)
1089 1088
1090 1089 def test_get_diff_runs_git_command_with_path_if_its_given(self):
1091 1090 comm1 = self.repo[0]
1092 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 1093 self.repo.get_diff(comm1, comm2, 'foo')
1095 self.repo.run_git_command.assert_called_once_with(
1096 ['diff', '-U3', '--full-index', '--binary', '-p', '-M',
1097 '--abbrev=40', self.repo._lookup_commit(0),
1098 comm2.raw_id, '--', 'foo'])
1094 remote_mock.diff.assert_called_once_with(
1095 self.repo._lookup_commit(0), comm2.raw_id,
1096 file_filter='foo', opt_ignorews=False, context=3)
1099 1097
1100 1098
1101 1099 @pytest.mark.usefixtures("vcs_repository_support")
@@ -57,7 +57,7 b' def repo(request, baseapp):'
57 57 return repo
58 58
59 59
60 class TestMercurialRepository:
60 class TestMercurialRepository(object):
61 61
62 62 # pylint: disable=protected-access
63 63
General Comments 0
You need to be logged in to leave comments. Login now