summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules6
-rw-r--r--lib/git/objects/submodule/base.py25
-rw-r--r--test/git/test_submodule.py18
3 files changed, 36 insertions, 13 deletions
diff --git a/.gitmodules b/.gitmodules
index 3e84903d..3560dc4e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "gitdb"]
- path = lib/git/ext/gitdb
- url = git://gitorious.org/git-python/gitdb.git
+[submodule "gitdb"]
+ path = lib/git/ext/gitdb
+ url = git://gitorious.org/git-python/gitdb.git
diff --git a/lib/git/objects/submodule/base.py b/lib/git/objects/submodule/base.py
index 403b2e18..7e0444f1 100644
--- a/lib/git/objects/submodule/base.py
+++ b/lib/git/objects/submodule/base.py
@@ -24,6 +24,7 @@ import git
import os
import sys
+import time
import shutil
@@ -211,6 +212,12 @@ class Submodule(util.IndexObject, Iterable, Traversable):
path = path[:-1]
# END handle trailing slash
+ # assure we never put backslashes into the url, as some operating systems
+ # like it ...
+ if url != None:
+ url = to_native_path_linux(url)
+ #END assure url correctness
+
# INSTANTIATE INTERMEDIATE SM
sm = cls(repo, cls.NULL_BIN_SHA, cls.k_default_mode, path, name)
if sm.exists():
@@ -381,7 +388,11 @@ class Submodule(util.IndexObject, Iterable, Traversable):
# update the working tree
if mrepo.head.commit.binsha != binsha:
if is_detached:
- mrepo.git.checkout(hexsha)
+ # NOTE: for now we force, the user is no supposed to change detached
+ # submodules anyway. Maybe at some point this becomes an option, to
+ # properly handle user modifications - see below for future options
+ # regarding rebase and merge.
+ mrepo.git.checkout(hexsha, force=True)
else:
# TODO: allow to specify a rebase, merge, or reset
# TODO: Warn if the hexsha forces the tracking branch off the remote
@@ -576,16 +587,26 @@ class Submodule(util.IndexObject, Iterable, Traversable):
if num_branches_with_new_commits == len(rrefs):
raise InvalidGitRepositoryError("Cannot delete module at %s as there are new commits" % mod.working_tree_dir)
# END handle new commits
+ # have to manually delete references as python's scoping is
+ # not existing, they could keep handles open ( on windows this is a problem )
+ if len(rrefs):
+ del(rref)
+ #END handle remotes
+ del(rrefs)
+ del(remote)
# END for each remote
# gently remove all submodule repositories
for sm in self.children():
sm.remove(module=True, force=False, configuration=False, dry_run=dry_run)
+ del(sm)
# END for each child-submodule
# finally delete our own submodule
if not dry_run:
- shutil.rmtree(mod.working_tree_dir)
+ wtd = mod.working_tree_dir
+ del(mod) # release file-handles (windows)
+ shutil.rmtree(wtd)
# END delete tree if possible
# END handle force
# END handle module deletion
diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py
index 2ef45862..d922f32a 100644
--- a/test/git/test_submodule.py
+++ b/test/git/test_submodule.py
@@ -172,14 +172,16 @@ class TestSubmodule(TestBase):
# reset both heads to the previous version, verify that to_latest_revision works
- for repo in (csm.module(), sm.module()):
+ smods = (sm.module(), csm.module())
+ for repo in smods:
repo.head.reset('HEAD~1', working_tree=1)
# END for each repo to reset
sm.update(recursive=True, to_latest_revision=True)
- for repo in (sm.module(), csm.module()):
+ for repo in smods:
assert repo.head.commit == repo.head.ref.tracking_branch().commit
# END for each repo to check
+ del(smods)
# if the head is detached, it still works ( but warns )
smref = sm.module().head.ref
@@ -356,8 +358,8 @@ class TestSubmodule(TestBase):
rm.config_writer()
# deep traversal gitdb / async
- rsms = list(rm.traverse())
- assert len(rsms) == 2 # gitdb and async, async being a child of gitdb
+ rsmsp = [sm.path for sm in rm.traverse()]
+ assert len(rsmsp) == 2 # gitdb and async, async being a child of gitdb
# cannot set the parent commit as root module's path didn't exist
self.failUnlessRaises(ValueError, rm.set_parent_commit, 'HEAD')
@@ -378,7 +380,7 @@ class TestSubmodule(TestBase):
assert not sm.module_exists() # was never updated after rwrepo's clone
# assure we clone from a local source
- sm.config_writer().set_value('url', join_path_native(self.rorepo.working_tree_dir, sm.path))
+ sm.config_writer().set_value('url', to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path)))
sm.update(recursive=False)
assert sm.module_exists()
sm.config_writer().set_value('path', fp) # change path to something with prefix AFTER url change
@@ -406,9 +408,9 @@ class TestSubmodule(TestBase):
#================
nsmn = "newsubmodule"
nsmp = "submrepo"
- async_url = join_path_native(self.rorepo.working_tree_dir, rsms[0].path, rsms[1].path)
+ async_url = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, rsmsp[0], rsmsp[1]))
nsm = Submodule.add(rwrepo, nsmn, nsmp, url=async_url)
- csmadded = rwrepo.index.commit("Added submodule")
+ csmadded = rwrepo.index.commit("Added submodule").hexsha # make sure we don't keep the repo reference
nsm.set_parent_commit(csmadded)
assert nsm.module_exists()
# in our case, the module should not exist, which happens if we update a parent
@@ -439,7 +441,7 @@ class TestSubmodule(TestBase):
# to the first repository, this way we have a fast checkout, and a completely different
# repository at the different url
nsm.set_parent_commit(csmremoved)
- nsmurl = join_path_native(self.rorepo.working_tree_dir, rsms[0].path)
+ nsmurl = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, rsmsp[0]))
nsm.config_writer().set_value('url', nsmurl)
csmpathchange = rwrepo.index.commit("changed url")
nsm.set_parent_commit(csmpathchange)