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

Skip to content

Commit 4c34d5c

Browse files
committed
Split big submodule file into smaller files. Tried to manually get imports right, but its not yet tested
1 parent ebe8f64 commit 4c34d5c

File tree

4 files changed

+369
-345
lines changed

4 files changed

+369
-345
lines changed

lib/git/objects/submodule/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
from base import *
3+
from root import *

lib/git/objects/submodule.py renamed to lib/git/objects/submodule/base.py

Lines changed: 6 additions & 345 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,23 @@
1-
import base
2-
from util import Traversable
1+
import git.objects.base
2+
from util import *
3+
from git.objects.util import Traversable
34
from StringIO import StringIO # need a dict to set bloody .name field
45
from git.util import Iterable, join_path_native, to_native_path_linux
5-
from git.config import GitConfigParser, SectionConstraint
6+
from git.config import SectionConstraint
67
from git.exc import InvalidGitRepositoryError, NoSuchPathError
78
import stat
89
import git
910

1011
import os
1112
import sys
12-
import weakref
13+
1314
import shutil
1415

1516
__all__ = ("Submodule", "RootModule")
1617

17-
#{ Utilities
18-
19-
def sm_section(name):
20-
""":return: section title used in .gitmodules configuration file"""
21-
return 'submodule "%s"' % name
22-
23-
def sm_name(section):
24-
""":return: name of the submodule as parsed from the section name"""
25-
section = section.strip()
26-
return section[11:-1]
27-
28-
def mkhead(repo, path):
29-
""":return: New branch/head instance"""
30-
return git.Head(repo, git.Head.to_full_path(path))
31-
32-
def unbare_repo(func):
33-
"""Methods with this decorator raise InvalidGitRepositoryError if they
34-
encounter a bare repository"""
35-
def wrapper(self, *args, **kwargs):
36-
if self.repo.bare:
37-
raise InvalidGitRepositoryError("Method '%s' cannot operate on bare repositories" % func.__name__)
38-
#END bare method
39-
return func(self, *args, **kwargs)
40-
# END wrapper
41-
wrapper.__name__ = func.__name__
42-
return wrapper
43-
44-
def find_first_remote_branch(remotes, branch):
45-
"""Find the remote branch matching the name of the given branch or raise InvalidGitRepositoryError"""
46-
for remote in remotes:
47-
try:
48-
return remote.refs[branch.name]
49-
except IndexError:
50-
continue
51-
# END exception handling
52-
#END for remote
53-
raise InvalidGitRepositoryError("Didn't find remote branch %r in any of the given remotes", branch)
54-
55-
#} END utilities
56-
57-
58-
#{ Classes
59-
60-
class SubmoduleConfigParser(GitConfigParser):
61-
"""
62-
Catches calls to _write, and updates the .gitmodules blob in the index
63-
with the new data, if we have written into a stream. Otherwise it will
64-
add the local file to the index to make it correspond with the working tree.
65-
Additionally, the cache must be cleared
66-
67-
Please note that no mutating method will work in bare mode
68-
"""
69-
70-
def __init__(self, *args, **kwargs):
71-
self._smref = None
72-
self._index = None
73-
self._auto_write = True
74-
super(SubmoduleConfigParser, self).__init__(*args, **kwargs)
75-
76-
#{ Interface
77-
def set_submodule(self, submodule):
78-
"""Set this instance's submodule. It must be called before
79-
the first write operation begins"""
80-
self._smref = weakref.ref(submodule)
81-
82-
def flush_to_index(self):
83-
"""Flush changes in our configuration file to the index"""
84-
assert self._smref is not None
85-
# should always have a file here
86-
assert not isinstance(self._file_or_files, StringIO)
87-
88-
sm = self._smref()
89-
if sm is not None:
90-
index = self._index
91-
if index is None:
92-
index = sm.repo.index
93-
# END handle index
94-
index.add([sm.k_modules_file], write=self._auto_write)
95-
sm._clear_cache()
96-
# END handle weakref
97-
98-
#} END interface
99-
100-
#{ Overridden Methods
101-
def write(self):
102-
rval = super(SubmoduleConfigParser, self).write()
103-
self.flush_to_index()
104-
return rval
105-
# END overridden methods
10618

10719

108-
class Submodule(base.IndexObject, Iterable, Traversable):
20+
class Submodule(git.objects.base.IndexObject, Iterable, Traversable):
10921
"""Implements access to a git submodule. They are special in that their sha
11022
represents a commit in the submodule's repository which is to be checked out
11123
at the path of this instance.
@@ -879,255 +791,4 @@ def iter_items(cls, repo, parent_commit='HEAD'):
879791
# END for each section
880792

881793
#} END iterable interface
882-
883-
884-
class RootModule(Submodule):
885-
"""A (virtual) Root of all submodules in the given repository. It can be used
886-
to more easily traverse all submodules of the master repository"""
887-
888-
__slots__ = tuple()
889-
890-
k_root_name = '__ROOT__'
891-
892-
def __init__(self, repo):
893-
# repo, binsha, mode=None, path=None, name = None, parent_commit=None, url=None, ref=None)
894-
super(RootModule, self).__init__(
895-
repo,
896-
binsha = self.NULL_BIN_SHA,
897-
mode = self.k_default_mode,
898-
path = '',
899-
name = self.k_root_name,
900-
parent_commit = repo.head.commit,
901-
url = '',
902-
branch = mkhead(repo, self.k_head_default)
903-
)
904-
905-
906-
def _clear_cache(self):
907-
"""May not do anything"""
908-
pass
909-
910-
#{ Interface
911-
912-
def update(self, previous_commit=None, recursive=True, force_remove=False, init=True, to_latest_revision=False):
913-
"""Update the submodules of this repository to the current HEAD commit.
914-
This method behaves smartly by determining changes of the path of a submodules
915-
repository, next to changes to the to-be-checked-out commit or the branch to be
916-
checked out. This works if the submodules ID does not change.
917-
Additionally it will detect addition and removal of submodules, which will be handled
918-
gracefully.
919-
920-
:param previous_commit: If set to a commit'ish, the commit we should use
921-
as the previous commit the HEAD pointed to before it was set to the commit it points to now.
922-
If None, it defaults to ORIG_HEAD otherwise, or the parent of the current
923-
commit if it is not given
924-
:param recursive: if True, the children of submodules will be updated as well
925-
using the same technique
926-
:param force_remove: If submodules have been deleted, they will be forcibly removed.
927-
Otherwise the update may fail if a submodule's repository cannot be deleted as
928-
changes have been made to it (see Submodule.update() for more information)
929-
:param init: If we encounter a new module which would need to be initialized, then do it.
930-
:param to_latest_revision: If True, instead of checking out the revision pointed to
931-
by this submodule's sha, the checked out tracking branch will be merged with the
932-
newest remote branch fetched from the repository's origin"""
933-
if self.repo.bare:
934-
raise InvalidGitRepositoryError("Cannot update submodules in bare repositories")
935-
# END handle bare
936-
937-
repo = self.repo
938-
939-
# HANDLE COMMITS
940-
##################
941-
cur_commit = repo.head.commit
942-
if previous_commit is None:
943-
symref = repo.head.orig_head()
944-
try:
945-
previous_commit = symref.commit
946-
except Exception:
947-
pcommits = cur_commit.parents
948-
if pcommits:
949-
previous_commit = pcommits[0]
950-
else:
951-
# in this special case, we just diff against ourselve, which
952-
# means exactly no change
953-
previous_commit = cur_commit
954-
# END handle initial commit
955-
# END no ORIG_HEAD
956-
else:
957-
previous_commit = repo.commit(previous_commit) # obtain commit object
958-
# END handle previous commit
959-
960-
961-
psms = self.list_items(repo, parent_commit=previous_commit)
962-
sms = self.list_items(self.module())
963-
spsms = set(psms)
964-
ssms = set(sms)
965-
966-
# HANDLE REMOVALS
967-
###################
968-
for rsm in (spsms - ssms):
969-
# fake it into thinking its at the current commit to allow deletion
970-
# of previous module. Trigger the cache to be updated before that
971-
#rsm.url
972-
rsm._parent_commit = repo.head.commit
973-
rsm.remove(configuration=False, module=True, force=force_remove)
974-
# END for each removed submodule
975-
976-
# HANDLE PATH RENAMES
977-
#####################
978-
# url changes + branch changes
979-
for csm in (spsms & ssms):
980-
psm = psms[csm.name]
981-
sm = sms[csm.name]
982-
983-
if sm.path != psm.path and psm.module_exists():
984-
# move the module to the new path
985-
psm.move(sm.path, module=True, configuration=False)
986-
# END handle path changes
987-
988-
if sm.module_exists():
989-
# handle url change
990-
if sm.url != psm.url:
991-
# Add the new remote, remove the old one
992-
# This way, if the url just changes, the commits will not
993-
# have to be re-retrieved
994-
nn = '__new_origin__'
995-
smm = sm.module()
996-
rmts = smm.remotes
997-
998-
# don't do anything if we already have the url we search in place
999-
if len([r for r in rmts if r.url == sm.url]) == 0:
1000-
1001-
1002-
assert nn not in [r.name for r in rmts]
1003-
smr = smm.create_remote(nn, sm.url)
1004-
smr.fetch()
1005-
1006-
# If we have a tracking branch, it should be available
1007-
# in the new remote as well.
1008-
if len([r for r in smr.refs if r.remote_head == sm.branch.name]) == 0:
1009-
raise ValueError("Submodule branch named %r was not available in new submodule remote at %r" % (sm.branch.name, sm.url))
1010-
# END head is not detached
1011-
1012-
# now delete the changed one
1013-
rmt_for_deletion = None
1014-
for remote in rmts:
1015-
if remote.url == psm.url:
1016-
rmt_for_deletion = remote
1017-
break
1018-
# END if urls match
1019-
# END for each remote
1020-
1021-
# if we didn't find a matching remote, but have exactly one,
1022-
# we can safely use this one
1023-
if rmt_for_deletion is None:
1024-
if len(rmts) == 1:
1025-
rmt_for_deletion = rmts[0]
1026-
else:
1027-
# if we have not found any remote with the original url
1028-
# we may not have a name. This is a special case,
1029-
# and its okay to fail here
1030-
# Alternatively we could just generate a unique name and leave all
1031-
# existing ones in place
1032-
raise InvalidGitRepositoryError("Couldn't find original remote-repo at url %r" % psm.url)
1033-
#END handle one single remote
1034-
# END handle check we found a remote
1035-
1036-
orig_name = rmt_for_deletion.name
1037-
smm.delete_remote(rmt_for_deletion)
1038-
# NOTE: Currently we leave tags from the deleted remotes
1039-
# as well as separate tracking branches in the possibly totally
1040-
# changed repository ( someone could have changed the url to
1041-
# another project ). At some point, one might want to clean
1042-
# it up, but the danger is high to remove stuff the user
1043-
# has added explicitly
1044-
1045-
# rename the new remote back to what it was
1046-
smr.rename(orig_name)
1047-
1048-
# early on, we verified that the our current tracking branch
1049-
# exists in the remote. Now we have to assure that the
1050-
# sha we point to is still contained in the new remote
1051-
# tracking branch.
1052-
smsha = sm.binsha
1053-
found = False
1054-
rref = smr.refs[self.branch.name]
1055-
for c in rref.commit.traverse():
1056-
if c.binsha == smsha:
1057-
found = True
1058-
break
1059-
# END traverse all commits in search for sha
1060-
# END for each commit
1061-
1062-
if not found:
1063-
# adjust our internal binsha to use the one of the remote
1064-
# this way, it will be checked out in the next step
1065-
# This will change the submodule relative to us, so
1066-
# the user will be able to commit the change easily
1067-
print >> sys.stderr, "WARNING: Current sha %s was not contained in the tracking branch at the new remote, setting it the the remote's tracking branch" % sm.hexsha
1068-
sm.binsha = rref.commit.binsha
1069-
#END reset binsha
1070-
1071-
#NOTE: All checkout is performed by the base implementation of update
1072-
1073-
# END skip remote handling if new url already exists in module
1074-
# END handle url
1075-
1076-
if sm.branch != psm.branch:
1077-
# finally, create a new tracking branch which tracks the
1078-
# new remote branch
1079-
smm = sm.module()
1080-
smmr = smm.remotes
1081-
try:
1082-
tbr = git.Head.create(smm, sm.branch.name)
1083-
except git.GitCommandError, e:
1084-
if e.status != 128:
1085-
raise
1086-
#END handle something unexpected
1087-
1088-
# ... or reuse the existing one
1089-
tbr = git.Head(smm, git.Head.to_full_path(sm.branch.name))
1090-
#END assure tracking branch exists
1091-
1092-
tbr.set_tracking_branch(find_first_remote_branch(smmr, sm.branch))
1093-
# figure out whether the previous tracking branch contains
1094-
# new commits compared to the other one, if not we can
1095-
# delete it.
1096-
try:
1097-
tbr = find_first_remote_branch(smmr, psm.branch)
1098-
if len(smm.git.cherry(tbr, psm.branch)) == 0:
1099-
psm.branch.delete(smm, psm.branch)
1100-
#END delete original tracking branch if there are no changes
1101-
except InvalidGitRepositoryError:
1102-
# ignore it if the previous branch couldn't be found in the
1103-
# current remotes, this just means we can't handle it
1104-
pass
1105-
# END exception handling
1106-
1107-
#NOTE: All checkout is done in the base implementation of update
1108-
1109-
#END handle branch
1110-
#END handle
1111-
# END for each common submodule
1112-
1113-
# FINALLY UPDATE ALL ACTUAL SUBMODULES
1114-
######################################
1115-
for sm in sms:
1116-
# update the submodule using the default method
1117-
sm.update(recursive=True, init=init, to_latest_revision=to_latest_revision)
1118-
1119-
# update recursively depth first - question is which inconsitent
1120-
# state will be better in case it fails somewhere. Defective branch
1121-
# or defective depth. The RootSubmodule type will never process itself,
1122-
# which was done in the previous expression
1123-
if recursive:
1124-
type(self)(sm.module()).update(recursive=True, force_remove=force_remove,
1125-
init=init, to_latest_revision=to_latest_revision)
1126-
#END handle recursive
1127-
# END for each submodule to update
1128794

1129-
def module(self):
1130-
""":return: the actual repository containing the submodules"""
1131-
return self.repo
1132-
#} END interface
1133-
#} END classes

0 commit comments

Comments
 (0)