Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 63771e1

Browse files
authored
Update root.py
1 parent a79d006 commit 63771e1

File tree

1 file changed

+1
-366
lines changed

1 file changed

+1
-366
lines changed

git/objects/submodule/root.py

Lines changed: 1 addition & 366 deletions
Original file line numberDiff line numberDiff line change
@@ -2,368 +2,7 @@
22
Submodule,
33
UpdateProgress
44
)
5-
from .util import (
6-
find_first_remote_branch
7-
)
8-
from git.exc import InvalidGitRepositoryError
9-
import git
10-
11-
import logging
12-
13-
# typing -------------------------------------------------------------------
14-
15-
from typing import TYPE_CHECKING, Union
16-
17-
from git.types import Commit_ish
18-
19-
if TYPE_CHECKING:
20-
from git.repo import Repo
21-
from git.util import IterableList
22-
23-
# ----------------------------------------------------------------------------
24-
25-
__all__ = ["RootModule", "RootUpdateProgress"]
26-
27-
log = logging.getLogger('git.objects.submodule.root')
28-
log.addHandler(logging.NullHandler())
29-
30-
31-
class RootUpdateProgress(UpdateProgress):
32-
"""Utility class which adds more opcodes to the UpdateProgress"""
33-
REMOVE, PATHCHANGE, BRANCHCHANGE, URLCHANGE = [
34-
1 << x for x in range(UpdateProgress._num_op_codes, UpdateProgress._num_op_codes + 4)]
35-
_num_op_codes = UpdateProgress._num_op_codes + 4
36-
37-
__slots__ = ()
38-
39-
40-
BEGIN = RootUpdateProgress.BEGIN
41-
END = RootUpdateProgress.END
42-
REMOVE = RootUpdateProgress.REMOVE
43-
BRANCHCHANGE = RootUpdateProgress.BRANCHCHANGE
44-
URLCHANGE = RootUpdateProgress.URLCHANGE
45-
PATHCHANGE = RootUpdateProgress.PATHCHANGE
46-
47-
48-
class RootModule(Submodule):
49-
50-
"""A (virtual) Root of all submodules in the given repository. It can be used
51-
to more easily traverse all submodules of the master repository"""
52-
53-
__slots__ = ()
54-
55-
k_root_name = '__ROOT__'
56-
57-
def __init__(self, repo: 'Repo'):
58-
# repo, binsha, mode=None, path=None, name = None, parent_commit=None, url=None, ref=None)
59-
super(RootModule, self).__init__(
60-
repo,
61-
binsha=self.NULL_BIN_SHA,
62-
mode=self.k_default_mode,
63-
path='',
64-
name=self.k_root_name,
65-
parent_commit=repo.head.commit,
66-
url='',
67-
branch_path=git.Head.to_full_path(self.k_head_default)
68-
)
69-
70-
def _clear_cache(self) -> None:
71-
"""May not do anything"""
72-
pass
73-
74-
#{ Interface
75-
76-
def update(self, previous_commit: Union[Commit_ish, None] = None, # type: ignore[override]
77-
recursive: bool = True, force_remove: bool = False, init: bool = True,
78-
to_latest_revision: bool = False, progress: Union[None, 'RootUpdateProgress'] = None,
79-
dry_run: bool = False, force_reset: bool = False, keep_going: bool = False
80-
) -> 'RootModule':
81-
"""Update the submodules of this repository to the current HEAD commit.
82-
This method behaves smartly by determining changes of the path of a submodules
83-
repository, next to changes to the to-be-checked-out commit or the branch to be
84-
checked out. This works if the submodules ID does not change.
85-
Additionally it will detect addition and removal of submodules, which will be handled
86-
gracefully.
87-
88-
:param previous_commit: If set to a commit'ish, the commit we should use
89-
as the previous commit the HEAD pointed to before it was set to the commit it points to now.
90-
If None, it defaults to HEAD@{1} otherwise
91-
:param recursive: if True, the children of submodules will be updated as well
92-
using the same technique
93-
:param force_remove: If submodules have been deleted, they will be forcibly removed.
94-
Otherwise the update may fail if a submodule's repository cannot be deleted as
95-
changes have been made to it (see Submodule.update() for more information)
96-
:param init: If we encounter a new module which would need to be initialized, then do it.
97-
:param to_latest_revision: If True, instead of checking out the revision pointed to
98-
by this submodule's sha, the checked out tracking branch will be merged with the
99-
latest remote branch fetched from the repository's origin.
100-
Unless force_reset is specified, a local tracking branch will never be reset into its past, therefore
101-
the remote branch must be in the future for this to have an effect.
102-
:param force_reset: if True, submodules may checkout or reset their branch even if the repository has
103-
pending changes that would be overwritten, or if the local tracking branch is in the future of the
104-
remote tracking branch and would be reset into its past.
105-
:param progress: RootUpdateProgress instance or None if no progress should be sent
106-
:param dry_run: if True, operations will not actually be performed. Progress messages
107-
will change accordingly to indicate the WOULD DO state of the operation.
108-
:param keep_going: if True, we will ignore but log all errors, and keep going recursively.
109-
Unless dry_run is set as well, keep_going could cause subsequent/inherited errors you wouldn't see
110-
otherwise.
111-
In conjunction with dry_run, it can be useful to anticipate all errors when updating submodules
112-
:return: self"""
113-
if self.repo.bare:
114-
raise InvalidGitRepositoryError("Cannot update submodules in bare repositories")
115-
# END handle bare
116-
117-
if progress is None:
118-
progress = RootUpdateProgress()
119-
# END assure progress is set
120-
121-
prefix = ''
122-
if dry_run:
123-
prefix = 'DRY-RUN: '
124-
125-
repo = self.repo
126-
127-
try:
128-
# SETUP BASE COMMIT
129-
###################
130-
cur_commit = repo.head.commit
131-
if previous_commit is None:
132-
try:
133-
previous_commit = repo.commit(repo.head.log_entry(-1).oldhexsha)
134-
if previous_commit.binsha == previous_commit.NULL_BIN_SHA:
135-
raise IndexError
136-
# END handle initial commit
137-
except IndexError:
138-
# in new repositories, there is no previous commit
139-
previous_commit = cur_commit
140-
# END exception handling
141-
else:
142-
previous_commit = repo.commit(previous_commit) # obtain commit object
143-
# END handle previous commit
144-
145-
psms: 'IterableList[Submodule]' = self.list_items(repo, parent_commit=previous_commit)
146-
sms: 'IterableList[Submodule]' = self.list_items(repo)
147-
spsms = set(psms)
148-
ssms = set(sms)
149-
150-
# HANDLE REMOVALS
151-
###################
152-
rrsm = (spsms - ssms)
153-
len_rrsm = len(rrsm)
154-
155-
for i, rsm in enumerate(rrsm):
156-
op = REMOVE
157-
if i == 0:
158-
op |= BEGIN
159-
# END handle begin
160-
161-
# fake it into thinking its at the current commit to allow deletion
162-
# of previous module. Trigger the cache to be updated before that
163-
progress.update(op, i, len_rrsm, prefix + "Removing submodule %r at %s" % (rsm.name, rsm.abspath))
164-
rsm._parent_commit = repo.head.commit
165-
rsm.remove(configuration=False, module=True, force=force_remove, dry_run=dry_run)
166-
167-
if i == len_rrsm - 1:
168-
op |= END
169-
# END handle end
170-
progress.update(op, i, len_rrsm, prefix + "Done removing submodule %r" % rsm.name)
171-
# END for each removed submodule
172-
173-
# HANDLE PATH RENAMES
174-
#####################
175-
# url changes + branch changes
176-
csms = (spsms & ssms)
177-
len_csms = len(csms)
178-
for i, csm in enumerate(csms):
179-
psm: 'Submodule' = psms[csm.name]
180-
sm: 'Submodule' = sms[csm.name]
181-
182-
# PATH CHANGES
183-
##############
184-
if sm.path != psm.path and psm.module_exists():
185-
progress.update(BEGIN | PATHCHANGE, i, len_csms, prefix +
186-
"Moving repository of submodule %r from %s to %s"
187-
% (sm.name, psm.abspath, sm.abspath))
188-
# move the module to the new path
189-
if not dry_run:
190-
psm.move(sm.path, module=True, configuration=False)
191-
# END handle dry_run
192-
progress.update(
193-
END | PATHCHANGE, i, len_csms, prefix + "Done moving repository of submodule %r" % sm.name)
194-
# END handle path changes
195-
196-
if sm.module_exists():
197-
# HANDLE URL CHANGE
198-
###################
199-
if sm.url != psm.url:
200-
# Add the new remote, remove the old one
201-
# This way, if the url just changes, the commits will not
202-
# have to be re-retrieved
203-
nn = '__new_origin__'
204-
smm = sm.module()
205-
rmts = smm.remotes
206-
207-
# don't do anything if we already have the url we search in place
208-
if len([r for r in rmts if r.url == sm.url]) == 0:
209-
progress.update(BEGIN | URLCHANGE, i, len_csms, prefix +
210-
"Changing url of submodule %r from %s to %s" % (sm.name, psm.url, sm.url))
211-
212-
if not dry_run:
213-
assert nn not in [r.name for r in rmts]
214-
smr = smm.create_remote(nn, sm.url)
215-
smr.fetch(progress=progress)
216-
217-
# If we have a tracking branch, it should be available
218-
# in the new remote as well.
219-
if len([r for r in smr.refs if r.remote_head == sm.branch_name]) == 0:
220-
raise ValueError(
221-
"Submodule branch named %r was not available in new submodule remote at %r"
222-
% (sm.branch_name, sm.url)
223-
)
224-
# END head is not detached
225-
226-
# now delete the changed one
227-
rmt_for_deletion = None
228-
for remote in rmts:
229-
if remote.url == psm.url:
230-
rmt_for_deletion = remote
231-
break
232-
# END if urls match
233-
# END for each remote
234-
235-
# if we didn't find a matching remote, but have exactly one,
236-
# we can safely use this one
237-
if rmt_for_deletion is None:
238-
if len(rmts) == 1:
239-
rmt_for_deletion = rmts[0]
240-
else:
241-
# if we have not found any remote with the original url
242-
# we may not have a name. This is a special case,
243-
# and its okay to fail here
244-
# Alternatively we could just generate a unique name and leave all
245-
# existing ones in place
246-
raise InvalidGitRepositoryError(
247-
"Couldn't find original remote-repo at url %r" % psm.url)
248-
# END handle one single remote
249-
# END handle check we found a remote
250-
251-
orig_name = rmt_for_deletion.name
252-
smm.delete_remote(rmt_for_deletion)
253-
# NOTE: Currently we leave tags from the deleted remotes
254-
# as well as separate tracking branches in the possibly totally
255-
# changed repository ( someone could have changed the url to
256-
# another project ). At some point, one might want to clean
257-
# it up, but the danger is high to remove stuff the user
258-
# has added explicitly
259-
260-
# rename the new remote back to what it was
261-
smr.rename(orig_name)
262-
263-
# early on, we verified that the our current tracking branch
264-
# exists in the remote. Now we have to assure that the
265-
# sha we point to is still contained in the new remote
266-
# tracking branch.
267-
smsha = sm.binsha
268-
found = False
269-
rref = smr.refs[self.branch_name]
270-
for c in rref.commit.traverse():
271-
if c.binsha == smsha:
272-
found = True
273-
break
274-
# END traverse all commits in search for sha
275-
# END for each commit
276-
277-
if not found:
278-
# adjust our internal binsha to use the one of the remote
279-
# this way, it will be checked out in the next step
280-
# This will change the submodule relative to us, so
281-
# the user will be able to commit the change easily
282-
log.warning("Current sha %s was not contained in the tracking\
283-
branch at the new remote, setting it the the remote's tracking branch", sm.hexsha)
284-
sm.binsha = rref.commit.binsha
285-
# END reset binsha
286-
287-
# NOTE: All checkout is performed by the base implementation of update
288-
# END handle dry_run
289-
progress.update(
290-
END | URLCHANGE, i, len_csms, prefix + "Done adjusting url of submodule %r" % (sm.name))
291-
# END skip remote handling if new url already exists in module
292-
# END handle url
293-
294-
# HANDLE PATH CHANGES
295-
#####################
296-
if sm.branch_path != psm.branch_path:
297-
# finally, create a new tracking branch which tracks the
298-
# new remote branch
299-
progress.update(BEGIN | BRANCHCHANGE, i, len_csms, prefix +
300-
"Changing branch of submodule %r from %s to %s"
301-
% (sm.name, psm.branch_path, sm.branch_path))
302-
if not dry_run:
303-
smm = sm.module()
304-
smmr = smm.remotes
305-
# As the branch might not exist yet, we will have to fetch all remotes to be sure ... .
306-
for remote in smmr:
307-
remote.fetch(progress=progress)
308-
# end for each remote
309-
310-
try:
311-
tbr = git.Head.create(smm, sm.branch_name, logmsg='branch: Created from HEAD')
312-
except OSError:
313-
# ... or reuse the existing one
314-
tbr = git.Head(smm, sm.branch_path)
315-
# END assure tracking branch exists
316-
317-
tbr.set_tracking_branch(find_first_remote_branch(smmr, sm.branch_name))
318-
# NOTE: All head-resetting is done in the base implementation of update
319-
# but we will have to checkout the new branch here. As it still points to the currently
320-
# checkout out commit, we don't do any harm.
321-
# As we don't want to update working-tree or index, changing the ref is all there is to do
322-
smm.head.reference = tbr
323-
# END handle dry_run
324-
325-
progress.update(
326-
END | BRANCHCHANGE, i, len_csms, prefix + "Done changing branch of submodule %r" % sm.name)
327-
# END handle branch
328-
# END handle
329-
# END for each common submodule
330-
except Exception as err:
331-
if not keep_going:
332-
raise
333-
log.error(str(err))
334-
# end handle keep_going
335-
336-
# FINALLY UPDATE ALL ACTUAL SUBMODULES
337-
######################################
338-
for sm in sms:
339-
# update the submodule using the default method
340-
sm.update(recursive=False, init=init, to_latest_revision=to_latest_revision,
341-
progress=progress, dry_run=dry_run, force=force_reset, keep_going=keep_going)
342-
343-
# update recursively depth first - question is which inconsitent
344-
# state will be better in case it fails somewhere. Defective branch
345-
# or defective depth. The RootSubmodule type will never process itself,
346-
# which was done in the previous expression
347-
if recursive:
348-
# the module would exist by now if we are not in dry_run mode
349-
if sm.module_exists():
350-
type(self)(sm.module()).update(recursive=True, force_remove=force_remove,
351-
init=init, to_latest_revision=to_latest_revision,
352-
progress=progress, dry_run=dry_run, force_reset=force_reset,
353-
keep_going=keep_going)
354-
# END handle dry_run
355-
# END handle recursive
356-
# END for each submodule to update
357-
358-
return self
359-
360-
from .base import (
361-
Submodule,
362-
UpdateProgress
363-
)
364-
from .util import (
365-
find_first_remote_branch
366-
)
5+
from .util import find_first_remote_branch
3676
from git.exc import InvalidGitRepositoryError
3687
import git
3698

@@ -720,8 +359,4 @@ def module(self) -> 'Repo':
720359
""":return: the actual repository containing the submodules"""
721360
return self.repo
722361
#} END interface
723-
#} END classes
724-
""":return: the actual repository containing the submodules"""
725-
return self.repo
726-
#} END interface
727362
#} END classes

0 commit comments

Comments
 (0)