Skip to content

Commit c78426b

Browse files
authored
Rollup merge of #49057 - Zoxc:fast-submodules, r=alexcrichton
Faster submodule updating For the common case when there are no submodules which need updating, this takes 0.48 seconds instead of 47 seconds. r? @alexcrichton
2 parents a2289da + 72cb109 commit c78426b

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

config.toml.example

Lines changed: 4 additions & 0 deletions
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

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -612,20 +612,55 @@ def build_triple(self):
612612
return config
613613
return default_build_triple()
614614

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

657695
def set_dev_environment(self):
658696
"""Set download URL for development environment"""

0 commit comments

Comments
 (0)