##// END OF EJS Templates
git: use a fetch_sync based creation of remote repos....
marcink -
r3078:0a44452a default
parent child Browse files
Show More
@@ -66,6 +66,7 b' class TestCreatePullRequestApi(object):'
66 66 expected_message = "Created new pull request `{title}`".format(
67 67 title=data['title'])
68 68 result = response.json
69 assert result['error'] == None
69 70 assert result['result']['msg'] == expected_message
70 71 pull_request_id = result['result']['pull_request_id']
71 72 pull_request = PullRequestModel().get(pull_request_id)
@@ -88,6 +89,7 b' class TestCreatePullRequestApi(object):'
88 89 expected_message = "Created new pull request `{title}`".format(
89 90 title=data['title'])
90 91 result = response.json
92 assert result['error'] == None
91 93 assert result['result']['msg'] == expected_message
92 94 pull_request_id = result['result']['pull_request_id']
93 95 pull_request = PullRequestModel().get(pull_request_id)
@@ -127,6 +129,7 b' class TestCreatePullRequestApi(object):'
127 129 expected_message = "Created new pull request `{title}`".format(
128 130 title=data['title'])
129 131 result = response.json
132 assert result['error'] == None
130 133 assert result['result']['msg'] == expected_message
131 134 pull_request_id = result['result']['pull_request_id']
132 135 pull_request = PullRequestModel().get(pull_request_id)
@@ -170,6 +173,7 b' class TestCreatePullRequestApi(object):'
170 173 expected_message = "Created new pull request `{title}`".format(
171 174 title=data['title'])
172 175 result = response.json
176 assert result['error'] == None
173 177 assert result['result']['msg'] == expected_message
174 178 pull_request_id = result['result']['pull_request_id']
175 179 pull_request = PullRequestModel().get(pull_request_id)
@@ -123,7 +123,7 b' def create_repo(form_data, cur_user):'
123 123 'enable_downloads', defs.get('repo_enable_downloads'))
124 124
125 125 try:
126 repo = RepoModel()._create_repo(
126 RepoModel()._create_repo(
127 127 repo_name=repo_name_full,
128 128 repo_type=repo_type,
129 129 description=description,
@@ -58,13 +58,13 b' class GitRepository(BaseRepository):'
58 58 contact = BaseRepository.DEFAULT_CONTACT
59 59
60 60 def __init__(self, repo_path, config=None, create=False, src_url=None,
61 update_after_clone=False, with_wire=None, bare=False):
61 do_workspace_checkout=False, with_wire=None, bare=False):
62 62
63 63 self.path = safe_str(os.path.abspath(repo_path))
64 64 self.config = config if config else self.get_default_config()
65 65 self.with_wire = with_wire
66 66
67 self._init_repo(create, src_url, update_after_clone, bare)
67 self._init_repo(create, src_url, do_workspace_checkout, bare)
68 68
69 69 # caches
70 70 self._commit_ids = {}
@@ -145,24 +145,36 b' class GitRepository(BaseRepository):'
145 145 pass
146 146 return False
147 147
148 def _init_repo(self, create, src_url=None, update_after_clone=False,
148 def _init_repo(self, create, src_url=None, do_workspace_checkout=False,
149 149 bare=False):
150 150 if create and os.path.exists(self.path):
151 151 raise RepositoryError(
152 152 "Cannot create repository at %s, location already exist"
153 153 % self.path)
154 154
155 if bare and do_workspace_checkout:
156 raise RepositoryError("Cannot update a bare repository")
155 157 try:
156 if create and src_url:
158
159 if src_url:
160 # check URL before any actions
157 161 GitRepository.check_url(src_url, self.config)
158 self.clone(src_url, update_after_clone, bare)
159 elif create:
162
163 if create:
160 164 os.makedirs(self.path, mode=0755)
161 165
162 166 if bare:
163 167 self._remote.init_bare()
164 168 else:
165 169 self._remote.init()
170
171 if src_url and bare:
172 # bare repository only allows a fetch and checkout is not allowed
173 self.fetch(src_url, commit_ids=None)
174 elif src_url:
175 self.pull(src_url, commit_ids=None,
176 update_after=do_workspace_checkout)
177
166 178 else:
167 179 if not self._remote.assert_correct_path():
168 180 raise RepositoryError(
@@ -630,49 +642,27 b' class GitRepository(BaseRepository):'
630 642 """
631 643 return GitInMemoryCommit(self)
632 644
633 def clone(self, url, update_after_clone=True, bare=False):
645 def pull(self, url, commit_ids=None, update_after=False):
634 646 """
635 Tries to clone commits from external location.
636
637 :param update_after_clone: If set to ``False``, git won't checkout
638 working directory
639 :param bare: If set to ``True``, repository would be cloned into
640 *bare* git repository (no working directory at all).
641 """
642 # init_bare and init expect empty dir created to proceed
643 if not os.path.exists(self.path):
644 os.mkdir(self.path)
647 Pull changes from external location. Pull is different in GIT
648 that fetch since it's doing a checkout
645 649
646 if bare:
647 self._remote.init_bare()
648 else:
649 self._remote.init()
650
651 deferred = '^{}'
652 valid_refs = ('refs/heads', 'refs/tags', 'HEAD')
653
654 return self._remote.clone(
655 url, deferred, valid_refs, update_after_clone)
656
657 def pull(self, url, commit_ids=None):
650 :param commit_ids: Optional. Can be set to a list of commit ids
651 which shall be pulled from the other repository.
658 652 """
659 Tries to pull changes from external location. We use fetch here since
660 pull in get does merges and we want to be compatible with hg backend so
661 pull == fetch in this case
662 """
663 self.fetch(url, commit_ids=commit_ids)
653 refs = None
654 if commit_ids is not None:
655 remote_refs = self._remote.get_remote_refs(url)
656 refs = [ref for ref in remote_refs if remote_refs[ref] in commit_ids]
657 self._remote.pull(url, refs=refs, update_after=update_after)
658 self._remote.invalidate_vcs_cache()
664 659
665 660 def fetch(self, url, commit_ids=None):
666 661 """
667 Tries to fetch changes from external location.
662 Fetch all git objects from external location.
668 663 """
669 refs = None
670
671 if commit_ids is not None:
672 remote_refs = self._remote.get_remote_refs(url)
673 refs = [
674 ref for ref in remote_refs if remote_refs[ref] in commit_ids]
675 self._remote.fetch(url, refs=refs)
664 self._remote.sync_fetch(url, refs=commit_ids)
665 self._remote.invalidate_vcs_cache()
676 666
677 667 def push(self, url):
678 668 refs = None
@@ -57,7 +57,7 b' class MercurialRepository(BaseRepository'
57 57 DEFAULT_BRANCH_NAME = 'default'
58 58
59 59 def __init__(self, repo_path, config=None, create=False, src_url=None,
60 update_after_clone=False, with_wire=None):
60 do_workspace_checkout=False, with_wire=None, bare=False):
61 61 """
62 62 Raises RepositoryError if repository could not be find at the given
63 63 ``repo_path``.
@@ -67,8 +67,9 b' class MercurialRepository(BaseRepository'
67 67 :param create=False: if set to True, would try to create repository if
68 68 it does not exist rather than raising exception
69 69 :param src_url=None: would try to clone repository from given location
70 :param update_after_clone=False: sets update of working copy after
70 :param do_workspace_checkout=False: sets update of working copy after
71 71 making a clone
72 :param bare: not used, compatible with other VCS
72 73 """
73 74
74 75 self.path = safe_str(os.path.abspath(repo_path))
@@ -79,7 +80,7 b' class MercurialRepository(BaseRepository'
79 80 default=[('extensions', 'largefiles', '1')])
80 81 self.with_wire = with_wire
81 82
82 self._init_repo(create, src_url, update_after_clone)
83 self._init_repo(create, src_url, do_workspace_checkout)
83 84
84 85 # caches
85 86 self._commit_ids = {}
@@ -328,7 +329,7 b' class MercurialRepository(BaseRepository'
328 329 def is_valid_repository(path):
329 330 return os.path.isdir(os.path.join(path, '.hg'))
330 331
331 def _init_repo(self, create, src_url=None, update_after_clone=False):
332 def _init_repo(self, create, src_url=None, do_workspace_checkout=False):
332 333 """
333 334 Function will check for mercurial repository in given path. If there
334 335 is no repository in that path it will raise an exception unless
@@ -337,7 +338,7 b' class MercurialRepository(BaseRepository'
337 338
338 339 If `src_url` is given, would try to clone repository from the
339 340 location at given clone_point. Additionally it'll make update to
340 working copy accordingly to `update_after_clone` flag.
341 working copy accordingly to `do_workspace_checkout` flag.
341 342 """
342 343 if create and os.path.exists(self.path):
343 344 raise RepositoryError(
@@ -348,7 +349,7 b' class MercurialRepository(BaseRepository'
348 349 url = str(self._get_url(src_url))
349 350 MercurialRepository.check_url(url, self.config)
350 351
351 self._remote.clone(url, self.path, update_after_clone)
352 self._remote.clone(url, self.path, do_workspace_checkout)
352 353
353 354 # Don't try to create if we've already cloned repo
354 355 create = False
@@ -538,7 +539,7 b' class MercurialRepository(BaseRepository'
538 539
539 540 def pull(self, url, commit_ids=None):
540 541 """
541 Tries to pull changes from external location.
542 Pull changes from external location.
542 543
543 544 :param commit_ids: Optional. Can be set to a list of commit ids
544 545 which shall be pulled from the other repository.
@@ -547,6 +548,12 b' class MercurialRepository(BaseRepository'
547 548 self._remote.pull(url, commit_ids=commit_ids)
548 549 self._remote.invalidate_vcs_cache()
549 550
551 def fetch(self, url, commit_ids=None):
552 """
553 Backward compatibility with GIT fetch==pull
554 """
555 return self.pull(url, commit_ids=commit_ids)
556
550 557 def push(self, url):
551 558 url = self._get_url(url)
552 559 self._remote.sync_push(url)
@@ -68,7 +68,7 b' class SubversionRepository(base.BaseRepo'
68 68 contact = base.BaseRepository.DEFAULT_CONTACT
69 69 description = base.BaseRepository.DEFAULT_DESCRIPTION
70 70
71 def __init__(self, repo_path, config=None, create=False, src_url=None,
71 def __init__(self, repo_path, config=None, create=False, src_url=None, bare=False,
72 72 **kwargs):
73 73 self.path = safe_str(os.path.abspath(repo_path))
74 74 self.config = config if config else self.get_default_config()
@@ -399,7 +399,7 b' class ScmModel(BaseModel):'
399 399 repo_name = dbrepo.repo_name
400 400 try:
401 401 # TODO: we need to make sure those operations call proper hooks !
402 repo.pull(remote_uri)
402 repo.fetch(remote_uri)
403 403
404 404 self.mark_for_invalidation(repo_name)
405 405 except Exception:
@@ -581,7 +581,7 b' class Backend(object):'
581 581
582 582 def create_repo(
583 583 self, commits=None, number_of_commits=0, heads=None,
584 name_suffix=u'', **kwargs):
584 name_suffix=u'', bare=False, **kwargs):
585 585 """
586 586 Create a repository and record it for later cleanup.
587 587
@@ -591,16 +591,17 b' class Backend(object):'
591 591 commits will be added to the new repository.
592 592 :param heads: Optional. Can be set to a sequence of of commit
593 593 names which shall be pulled in from the master repository.
594
594 :param name_suffix: adds special suffix to generated repo name
595 :param bare: set a repo as bare (no checkout)
595 596 """
596 597 self.repo_name = self._next_repo_name() + name_suffix
597 598 repo = self._fixture.create_repo(
598 self.repo_name, repo_type=self.alias, **kwargs)
599 self.repo_name, repo_type=self.alias, bare=bare, **kwargs)
599 600 self._cleanup_repos.append(repo.repo_name)
600 601
601 602 commits = commits or [
602 603 {'message': 'Commit %s of %s' % (x, self.repo_name)}
603 for x in xrange(number_of_commits)]
604 for x in range(number_of_commits)]
604 605 self._add_commits_to_repo(repo.scm_instance(), commits)
605 606 if heads:
606 607 self.pull_heads(repo, heads)
@@ -773,14 +774,15 b' class VcsBackend(object):'
773 774 """
774 775 return get_backend(self.alias)
775 776
776 def create_repo(self, commits=None, number_of_commits=0, _clone_repo=None):
777 def create_repo(self, commits=None, number_of_commits=0, _clone_repo=None,
778 bare=False):
777 779 repo_name = self._next_repo_name()
778 780 self._repo_path = get_new_dir(repo_name)
779 781 repo_class = get_backend(self.alias)
780 782 src_url = None
781 783 if _clone_repo:
782 784 src_url = _clone_repo.path
783 repo = repo_class(self._repo_path, create=True, src_url=src_url)
785 repo = repo_class(self._repo_path, create=True, src_url=src_url, bare=bare)
784 786 self._cleanup_repos.append(repo)
785 787
786 788 commits = commits or [
@@ -1158,13 +1160,13 b' class UserUtility(object):'
1158 1160 return repo_group
1159 1161
1160 1162 def create_repo(self, owner=TEST_USER_ADMIN_LOGIN, parent=None,
1161 auto_cleanup=True, repo_type='hg'):
1163 auto_cleanup=True, repo_type='hg', bare=False):
1162 1164 repo_name = "{prefix}_repository_{count}".format(
1163 1165 prefix=self._test_name,
1164 1166 count=len(self.repos_ids))
1165 1167
1166 1168 repository = self.fixture.create_repo(
1167 repo_name, cur_user=owner, repo_group=parent, repo_type=repo_type)
1169 repo_name, cur_user=owner, repo_group=parent, repo_type=repo_type, bare=bare)
1168 1170 if auto_cleanup:
1169 1171 self.repos_ids.append(repository.repo_id)
1170 1172 return repository
@@ -94,7 +94,7 b' class TestGitRepository:'
94 94 repo = GitRepository(TEST_GIT_REPO)
95 95 repo_clone = GitRepository(
96 96 TEST_GIT_REPO_CLONE,
97 src_url=TEST_GIT_REPO, create=True, update_after_clone=True)
97 src_url=TEST_GIT_REPO, create=True, do_workspace_checkout=True)
98 98 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
99 99 # Checking hashes of commits should be enough
100 100 for commit in repo.get_commits():
@@ -111,7 +111,7 b' class TestGitRepository:'
111 111 clone_path = TEST_GIT_REPO_CLONE + '_with_update'
112 112 repo_clone = GitRepository(
113 113 clone_path,
114 create=True, src_url=TEST_GIT_REPO, update_after_clone=True)
114 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=True)
115 115 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
116 116
117 117 # check if current workdir was updated
@@ -123,7 +123,7 b' class TestGitRepository:'
123 123 clone_path = TEST_GIT_REPO_CLONE + '_without_update'
124 124 repo_clone = GitRepository(
125 125 clone_path,
126 create=True, src_url=TEST_GIT_REPO, update_after_clone=False)
126 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=False)
127 127 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
128 128 # check if current workdir was *NOT* updated
129 129 fpath = os.path.join(clone_path, 'MANIFEST.in')
@@ -153,7 +153,7 b' class TestGitRepository:'
153 153 # Note: This is a git specific part of the API, it's only implemented
154 154 # by the git backend.
155 155 source_repo = vcsbackend_git.repo
156 target_repo = vcsbackend_git.create_repo()
156 target_repo = vcsbackend_git.create_repo(bare=True)
157 157 target_repo.fetch(source_repo.path)
158 158 # Note: Get a fresh instance, avoids caching trouble
159 159 target_repo = vcsbackend_git.backend(target_repo.path)
@@ -162,32 +162,31 b' class TestGitRepository:'
162 162 def test_commit_ids(self):
163 163 # there are 112 commits (by now)
164 164 # so we can assume they would be available from now on
165 subset = set([
166 'c1214f7e79e02fc37156ff215cd71275450cffc3',
167 '38b5fe81f109cb111f549bfe9bb6b267e10bc557',
168 'fa6600f6848800641328adbf7811fd2372c02ab2',
169 '102607b09cdd60e2793929c4f90478be29f85a17',
170 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
171 '2d1028c054665b962fa3d307adfc923ddd528038',
172 'd7e0d30fbcae12c90680eb095a4f5f02505ce501',
173 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
174 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
175 '8430a588b43b5d6da365400117c89400326e7992',
176 'd955cd312c17b02143c04fa1099a352b04368118',
177 'f67b87e5c629c2ee0ba58f85197e423ff28d735b',
178 'add63e382e4aabc9e1afdc4bdc24506c269b7618',
179 'f298fe1189f1b69779a4423f40b48edf92a703fc',
180 'bd9b619eb41994cac43d67cf4ccc8399c1125808',
181 '6e125e7c890379446e98980d8ed60fba87d0f6d1',
182 'd4a54db9f745dfeba6933bf5b1e79e15d0af20bd',
183 '0b05e4ed56c802098dfc813cbe779b2f49e92500',
184 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
185 '45223f8f114c64bf4d6f853e3c35a369a6305520',
186 'ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
187 'f5ea29fc42ef67a2a5a7aecff10e1566699acd68',
188 '27d48942240f5b91dfda77accd2caac94708cc7d',
189 '622f0eb0bafd619d2560c26f80f09e3b0b0d78af',
190 'e686b958768ee96af8029fe19c6050b1a8dd3b2b'])
165 subset = {'c1214f7e79e02fc37156ff215cd71275450cffc3',
166 '38b5fe81f109cb111f549bfe9bb6b267e10bc557',
167 'fa6600f6848800641328adbf7811fd2372c02ab2',
168 '102607b09cdd60e2793929c4f90478be29f85a17',
169 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
170 '2d1028c054665b962fa3d307adfc923ddd528038',
171 'd7e0d30fbcae12c90680eb095a4f5f02505ce501',
172 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
173 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
174 '8430a588b43b5d6da365400117c89400326e7992',
175 'd955cd312c17b02143c04fa1099a352b04368118',
176 'f67b87e5c629c2ee0ba58f85197e423ff28d735b',
177 'add63e382e4aabc9e1afdc4bdc24506c269b7618',
178 'f298fe1189f1b69779a4423f40b48edf92a703fc',
179 'bd9b619eb41994cac43d67cf4ccc8399c1125808',
180 '6e125e7c890379446e98980d8ed60fba87d0f6d1',
181 'd4a54db9f745dfeba6933bf5b1e79e15d0af20bd',
182 '0b05e4ed56c802098dfc813cbe779b2f49e92500',
183 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
184 '45223f8f114c64bf4d6f853e3c35a369a6305520',
185 'ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
186 'f5ea29fc42ef67a2a5a7aecff10e1566699acd68',
187 '27d48942240f5b91dfda77accd2caac94708cc7d',
188 '622f0eb0bafd619d2560c26f80f09e3b0b0d78af',
189 'e686b958768ee96af8029fe19c6050b1a8dd3b2b'}
191 190 assert subset.issubset(set(self.repo.commit_ids))
192 191
193 192 def test_slicing(self):
@@ -281,12 +280,12 b' TODO: To be written...'
281 280
282 281 new_branch = 'new_branch'
283 282 assert repo_clone._current_branch() == 'master'
284 assert set(repo_clone.branches) == set(('master',))
283 assert set(repo_clone.branches) == {'master'}
285 284 repo_clone._checkout(new_branch, create=True)
286 285
287 286 # Branches is a lazy property so we need to recrete the Repo object.
288 287 repo_clone = GitRepository(repo_clone.path)
289 assert set(repo_clone.branches) == set(('master', new_branch))
288 assert set(repo_clone.branches) == {'master', new_branch}
290 289 assert repo_clone._current_branch() == new_branch
291 290
292 291 def test_checkout(self):
@@ -1171,7 +1170,7 b' class TestGitRegression(BackendTestMixin'
1171 1170 assert paths == expected_paths
1172 1171
1173 1172
1174 class TestDiscoverGitVersion:
1173 class TestDiscoverGitVersion(object):
1175 1174
1176 1175 def test_returns_git_version(self, baseapp):
1177 1176 version = discover_git_version()
@@ -122,7 +122,7 b' class TestMercurialRepository:'
122 122 repo = MercurialRepository(TEST_HG_REPO)
123 123 repo_clone = MercurialRepository(
124 124 TEST_HG_REPO_CLONE + '_w_update',
125 src_url=TEST_HG_REPO, update_after_clone=True)
125 src_url=TEST_HG_REPO, do_workspace_checkout=True)
126 126 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
127 127
128 128 # check if current workdir was updated
@@ -133,7 +133,7 b' class TestMercurialRepository:'
133 133 repo = MercurialRepository(TEST_HG_REPO)
134 134 repo_clone = MercurialRepository(
135 135 TEST_HG_REPO_CLONE + '_wo_update',
136 src_url=TEST_HG_REPO, update_after_clone=False)
136 src_url=TEST_HG_REPO, do_workspace_checkout=False)
137 137 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
138 138 assert not os.path.isfile(
139 139 os.path.join(TEST_HG_REPO_CLONE + '_wo_update', 'MANIFEST.in'))
General Comments 0
You need to be logged in to leave comments. Login now