Skip to content

Commit 72cb109

Browse files
committed
Faster submodule updating
1 parent ff2d506 commit 72cb109

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

config.toml.example

+4
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@
118118
# Indicate whether submodules are managed and updated automatically.
119119
#submodules = true
120120

121+
# Update submodules only when the checked out commit in the submodules differs
122+
# from what is committed in the main rustc repo.
123+
#fast-submodules = true
124+
121125
# The path to (or name of) the GDB executable to use. This is only used for
122126
# executing the debuginfo test suite.
123127
#gdb = "gdb"

src/bootstrap/bootstrap.py

+50-12
Original file line numberDiff line numberDiff line change
@@ -614,20 +614,55 @@ def build_triple(self):
614614
return config
615615
return default_build_triple()
616616

617+
def check_submodule(self, module, slow_submodules):
618+
if not slow_submodules:
619+
checked_out = subprocess.Popen(["git", "rev-parse", "HEAD"],
620+
cwd=os.path.join(self.rust_root, module),
621+
stdout=subprocess.PIPE)
622+
return checked_out
623+
else:
624+
return None
625+
626+
def update_submodule(self, module, checked_out, recorded_submodules):
627+
module_path = os.path.join(self.rust_root, module)
628+
629+
if checked_out != None:
630+
default_encoding = sys.getdefaultencoding()
631+
checked_out = checked_out.communicate()[0].decode(default_encoding).strip()
632+
if recorded_submodules[module] == checked_out:
633+
return
634+
635+
print("Updating submodule", module)
636+
637+
run(["git", "submodule", "-q", "sync", module],
638+
cwd=self.rust_root, verbose=self.verbose)
639+
run(["git", "submodule", "update",
640+
"--init", "--recursive", module],
641+
cwd=self.rust_root, verbose=self.verbose)
642+
run(["git", "reset", "-q", "--hard"],
643+
cwd=module_path, verbose=self.verbose)
644+
run(["git", "clean", "-qdfx"],
645+
cwd=module_path, verbose=self.verbose)
646+
617647
def update_submodules(self):
618648
"""Update submodules"""
619649
if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
620650
self.get_toml('submodules') == "false":
621651
return
622-
print('Updating submodules')
652+
slow_submodules = self.get_toml('fast-submodule') == "false"
653+
start_time = time()
654+
if slow_submodules:
655+
print('Unconditionally updating all submodules')
656+
else:
657+
print('Updating only changed submodules')
623658
default_encoding = sys.getdefaultencoding()
624-
run(["git", "submodule", "-q", "sync"], cwd=self.rust_root, verbose=self.verbose)
625659
submodules = [s.split(' ', 1)[1] for s in subprocess.check_output(
626660
["git", "config", "--file",
627661
os.path.join(self.rust_root, ".gitmodules"),
628662
"--get-regexp", "path"]
629663
).decode(default_encoding).splitlines()]
630664
filtered_submodules = []
665+
submodules_names = []
631666
for module in submodules:
632667
if module.endswith("llvm"):
633668
if self.get_toml('llvm-config'):
@@ -645,16 +680,19 @@ def update_submodules(self):
645680
config = self.get_toml('lld')
646681
if config is None or config == 'false':
647682
continue
648-
filtered_submodules.append(module)
649-
run(["git", "submodule", "update",
650-
"--init", "--recursive"] + filtered_submodules,
651-
cwd=self.rust_root, verbose=self.verbose)
652-
run(["git", "submodule", "-q", "foreach", "git",
653-
"reset", "-q", "--hard"],
654-
cwd=self.rust_root, verbose=self.verbose)
655-
run(["git", "submodule", "-q", "foreach", "git",
656-
"clean", "-qdfx"],
657-
cwd=self.rust_root, verbose=self.verbose)
683+
check = self.check_submodule(module, slow_submodules)
684+
filtered_submodules.append((module, check))
685+
submodules_names.append(module)
686+
recorded = subprocess.Popen(["git", "ls-tree", "HEAD"] + submodules_names,
687+
cwd=self.rust_root, stdout=subprocess.PIPE)
688+
recorded = recorded.communicate()[0].decode(default_encoding).strip().splitlines()
689+
recorded_submodules = {}
690+
for data in recorded:
691+
data = data.split()
692+
recorded_submodules[data[3]] = data[2]
693+
for module in filtered_submodules:
694+
self.update_submodule(module[0], module[1], recorded_submodules)
695+
print("Submodules updated in %.2f seconds" % (time() - start_time))
658696

659697
def set_dev_environment(self):
660698
"""Set download URL for development environment"""

0 commit comments

Comments
 (0)