Skip to content

Commit e87854b

Browse files
authored
Merge pull request #2129 from mvanhorn/feat/2014-submodule-deinit
feat(submodule): add deinit method to Submodule (#2014)
2 parents f8b6df5 + 0c0cc8a commit e87854b

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

git/objects/submodule/base.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
Callable,
5050
Dict,
5151
Iterator,
52+
List,
5253
Mapping,
5354
Sequence,
5455
TYPE_CHECKING,
@@ -1267,6 +1268,36 @@ def remove(
12671268

12681269
return self
12691270

1271+
@unbare_repo
1272+
def deinit(self, force: bool = False) -> "Submodule":
1273+
"""Run ``git submodule deinit`` on this submodule.
1274+
1275+
This is a thin wrapper around ``git submodule deinit <path>``,
1276+
which unregisters the submodule (removes its entry from
1277+
``.git/config`` and empties the working-tree directory)
1278+
without deleting the submodule from ``.gitmodules``
1279+
or its checked-out repository under ``.git/modules/``.
1280+
A subsequent :meth:`update` will re-initialize the
1281+
submodule from the retained contents.
1282+
1283+
:param force:
1284+
If ``True``, pass ``--force`` to ``git submodule deinit``. This
1285+
allows deinitialization even when the submodule's working tree has
1286+
local modifications that would otherwise block the command.
1287+
1288+
:return:
1289+
self
1290+
1291+
:note:
1292+
Doesn't work in bare repositories.
1293+
"""
1294+
args: List[str] = []
1295+
if force:
1296+
args.append("--force")
1297+
args.extend(["--", str(self.path)])
1298+
self.repo.git.submodule("deinit", *args)
1299+
return self
1300+
12701301
def set_parent_commit(self, commit: Union[Commit_ish, str, None], check: bool = True) -> "Submodule":
12711302
"""Set this instance to use the given commit whose tree is supposed to
12721303
contain the ``.gitmodules`` blob.

test/test_submodule.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,21 @@ def test_iter_items_from_invalid_hash(self):
713713
next(it)
714714
self.assertIsNone(ctx.exception.value)
715715

716+
@with_rw_directory
717+
def test_deinit_calls_git_submodule(self, rwdir):
718+
repo = git.Repo.init(rwdir)
719+
submodule = Submodule(repo, b"\0" * 20, name="module", path="module")
720+
721+
with mock.patch.object(Git, "submodule", create=True) as git_submodule:
722+
submodule.deinit()
723+
724+
git_submodule.assert_called_once_with("deinit", "--", submodule.path)
725+
git_submodule.reset_mock()
726+
727+
submodule.deinit(force=True)
728+
729+
git_submodule.assert_called_once_with("deinit", "--force", "--", submodule.path)
730+
716731
@with_rw_repo(k_no_subm_tag, bare=False)
717732
def test_first_submodule(self, rwrepo):
718733
assert len(list(rwrepo.iter_submodules())) == 0

0 commit comments

Comments
 (0)