Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc7b16ad

Browse files
committed
Submodule.remove() now deals with .git files correctly.
A simple test verifies this at least.
1 parent67680a0 commitc7b16ad

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

‎git/objects/submodule/base.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
fromgit.configimport (
2121
SectionConstraint,
22+
GitConfigParser,
2223
cp
2324
)
2425
fromgit.excimport (
@@ -231,7 +232,7 @@ def _clone_repo(cls, repo, url, path, name, **kwargs):
231232

232233
clone=git.Repo.clone_from(url,module_checkout_path,**kwargs)
233234
ifcls._need_gitfile_submodules(repo.git):
234-
cls._write_git_file(module_checkout_path,module_abspath)
235+
cls._write_git_file_and_module_config(module_checkout_path,module_abspath)
235236
# end
236237
returnclone
237238

@@ -258,10 +259,13 @@ def _to_relative_path(cls, parent_repo, path):
258259
returnpath
259260

260261
@classmethod
261-
def_write_git_file(cls,working_tree_dir,module_abspath):
262+
def_write_git_file_and_module_config(cls,working_tree_dir,module_abspath):
262263
"""Writes a .git file containing a (preferably) relative path to the actual git module repository.
263264
It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir
264265
:note: will overwrite existing files !
266+
:note: as we rewrite both the git file as well as the module configuration, we might fail on the configuration
267+
and will not roll back changes done to the git file. This should be a non-issue, but may easily be fixed
268+
if it becomes one
265269
:param working_tree_dir: directory to write the .git file into
266270
:param module_abspath: absolute path to the bare repository
267271
"""
@@ -271,6 +275,10 @@ def _write_git_file(cls, working_tree_dir, module_abspath):
271275
fp.write(("gitdir: %s"%rela_path).encode(defenc))
272276
fp.close()
273277

278+
writer=GitConfigParser(os.path.join(module_abspath,'config'),read_only=False,merge_includes=False)
279+
writer.set_value('core','worktree',os.path.relpath(working_tree_dir,start=module_abspath))
280+
writer.release()
281+
274282
#{ Edit Interface
275283

276284
@classmethod
@@ -629,7 +637,7 @@ def move(self, module_path, configuration=True, module=True):
629637

630638
ifself._need_gitfile_submodules(self.repo.git):
631639
module_abspath=self._module_abspath(self.repo,self.path,self.name)
632-
self._write_git_file(module_checkout_abspath,module_abspath)
640+
self._write_git_file_and_module_config(module_checkout_abspath,module_abspath)
633641
# end handle git file rewrite
634642
# END move physical module
635643

@@ -668,7 +676,7 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
668676
"""Remove this submodule from the repository. This will remove our entry
669677
from the .gitmodules file and the entry in the .git/config file.
670678
671-
:param module: If True, the module we point to will be deleted
679+
:param module: If True, the modulecheckoutwe point to will be deleted
672680
as well. If the module is currently on a commit which is not part
673681
of any branch in the remote, if the currently checked out branch
674682
working tree, or untracked files,
@@ -687,15 +695,25 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
687695
we would usually throw
688696
:return: self
689697
:note: doesn't work in bare repositories
698+
:note: doesn't work atomically, as failure to remove any part of the submodule will leave
699+
an inconsistent state
690700
:raise InvalidGitRepositoryError: thrown if the repository cannot be deleted
691701
:raise OSError: if directories or files could not be removed"""
692702
ifnot (module+configuration):
693703
raiseValueError("Need to specify to delete at least the module, or the configuration")
694-
# END handle params
704+
# END handle parameters
705+
706+
# Recursively remove children of this submodule
707+
forcsminself.children():
708+
csm.remove(module,force,configuration,dry_run)
709+
del(csm)
710+
# end
695711

696-
# DELETEMODULEREPOSITORY
697-
##########################
712+
# DELETE REPOSITORY WORKING TREE
713+
################################
698714
ifmoduleandself.module_exists():
715+
mod=self.module()
716+
git_dir=mod.git_dir
699717
ifforce:
700718
# take the fast lane and just delete everything in our module path
701719
# TODO: If we run into permission problems, we have a highly inconsistent
@@ -715,7 +733,6 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
715733
# END apply deletion method
716734
else:
717735
# verify we may delete our module
718-
mod=self.module()
719736
ifmod.is_dirty(untracked_files=True):
720737
raiseInvalidGitRepositoryError(
721738
"Cannot delete module at %s with any modifications, unless force is specified"
@@ -747,19 +764,17 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
747764
del(remote)
748765
# END for each remote
749766

750-
# gently remove all submodule repositories
751-
forsminself.children():
752-
sm.remove(module=True,force=False,configuration=False,dry_run=dry_run)
753-
del(sm)
754-
# END for each child-submodule
755-
756767
# finally delete our own submodule
757768
ifnotdry_run:
758769
wtd=mod.working_tree_dir
759770
del(mod)# release file-handles (windows)
760771
rmtree(wtd)
761772
# END delete tree if possible
762773
# END handle force
774+
775+
ifos.path.isdir(git_dir):
776+
rmtree(git_dir)
777+
# end handle separate bare repository
763778
# END handle module deletion
764779

765780
# DELETE CONFIGURATION
@@ -786,7 +801,6 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
786801

787802
# void our data not to delay invalid access
788803
self._clear_cache()
789-
790804
returnself
791805

792806
defset_parent_commit(self,commit,check=True):

‎git/repo/base.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,18 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
131131

132132
# walk up the path to find the .git dir
133133
whilecurpath:
134+
# ABOUT os.path.NORMPATH
135+
# It's important to normalize the paths, as submodules will otherwise initialize their
136+
# repo instances with paths that depend on path-portions that will not exist after being
137+
# removed. It's just cleaner.
134138
ifis_git_dir(curpath):
135-
self.git_dir=curpath
139+
self.git_dir=os.path.normpath(curpath)
136140
self._working_tree_dir=os.path.dirname(self.git_dir)
137141
break
138142

139143
gitpath=find_git_dir(join(curpath,'.git'))
140144
ifgitpathisnotNone:
141-
self.git_dir=gitpath
145+
self.git_dir=os.path.normpath(gitpath)
142146
self._working_tree_dir=curpath
143147
break
144148

‎git/test/test_submodule.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,10 @@ def test_git_submodule_compatibility(self, rwdir):
665665
assertsm.module_exists()
666666

667667
# remove
668-
sm.remove()
669-
assertsm.exist()
670668
sm_module_path=sm.module().git_dir
671-
assertsm.module_exists()
672-
assertos.path.isdir(sm_module_path)
669+
sm.remove()
670+
assertnotsm.exists()
671+
assertnotsm.module_exists()
672+
assertnotos.path.isdir(sm_module_path)
673+
674+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp