Skip to content

Commit b29f2f7

Browse files
committed
When running gitconfig --local, run it in subdirectories as well.
Summary: The advantage of local is it doesn't pollute global state, but the disadvantage is that the settings are not inherited by submodules. (This is a misfeature, in my opinion.) So whenever we set anything --local, we need to manually do it in all submodules as well. This isn't a perfect solution, since if new submodules are added later they won't get the setting -- we'd have to hook into `git p` or something for that -- but it's better than nothing! In particular, it fixes (modulo the caveat above) https://app.asana.com/0/31965416896056/172514774666235 and also https://app.asana.com/0/31965416896056/51708574715815 Update submodules recursively, and do a better job parsing `status` output. I wasn't doing recursive submodules before because I figured they typically weren't *our* code so there was no point in using our configs on them. But there's no harm either, and they *can* be code we care about, so let's just do it. Just use no-arg `split` so we ignore leading spcae and runs of whitespace. No-arg `split` is the best. Test Plan: I ran cd /tmp ~/khan/devtools/ka-clone/bin/ka-clone -p [email protected]:Khan/webapp cd webapp/intl/translations git config -l --local --includes | grep transport and saw it say 'git-bigfile.transport=s3'. On an old version of ka-clone, it did not say that. (same) (same) Reviewers: mroth, benkraft Reviewed By: benkraft Differential Revision: https://phabricator.khanacademy.org/D34584
1 parent d06a53b commit b29f2f7

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

Diff for: bin/ka-clone

+40-3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,31 @@ def die_if_not_valid_git_repo():
8080
sys.exit(revparse_retcode)
8181

8282

83+
def _run_in_main_repo_and_subrepos(cmd):
84+
"""Run the given command in the main repo and all subrepos.
85+
86+
This is typically needed with `git config --local`, since local
87+
settings are not inherited by submodules.
88+
89+
Note this is not a perfect fix!, since if new submodules are created
90+
after the initial clone, they will not pick up the config setting.
91+
We'd have to hook into `git p` for that. But it's better than nothing!
92+
"""
93+
# We cannot use `git submodule foreach` since the submodules may
94+
# not have been checked out yet.
95+
all_submodules = subprocess.check_output(
96+
['git', 'submodule', 'status', '--recursive']
97+
)
98+
all_dirs = [l.split()[1] for l in all_submodules.splitlines()]
99+
all_dirs.append('.') # do the main repo as well!
100+
101+
for subdir in all_dirs:
102+
# For recursive submodules, the directory doesn't exist until we
103+
# do a `git submodule checkout` of the containing submodule.
104+
if os.path.exists(subdir):
105+
subprocess.check_call(cmd, cwd=subdir)
106+
107+
83108
def _default_email():
84109
try:
85110
kac_email = subprocess.check_output(["git", "config", "kaclone.email"])
@@ -89,7 +114,8 @@ def _default_email():
89114

90115

91116
def set_email(email=_default_email()):
92-
subprocess.check_call(
117+
# We have to run this in subrepos explicitly due to `--local`.
118+
_run_in_main_repo_and_subrepos(
93119
['git', 'config', '--local', 'user.email', email]
94120
)
95121
_cli_log_step_success("Set user.email to {}".format(email))
@@ -156,11 +182,15 @@ def link_gitconfig_extras():
156182

157183

158184
def _gitconfig_local_reference(config_key, location, name="reference"):
159-
"""Configure reference to userdir template, but only if exists."""
185+
"""Configure reference to userdir template, but only if exists.
186+
187+
This also updates the gitconfig reference in submodules, since
188+
`--local` does not cross submodule boundaries.
189+
"""
160190
home = os.path.expanduser("~") # safe for cross platform
161191
tmpl = os.path.join(home, location)
162192
if os.path.isfile(tmpl):
163-
subprocess.check_call(
193+
_run_in_main_repo_and_subrepos(
164194
['git', 'config', '--local', config_key, tmpl]
165195
)
166196
_cli_log_step_success("Linked {}".format(name))
@@ -189,6 +219,12 @@ def _clone_repo(src, dst, quiet=False):
189219
retcode = subprocess.call(cmds)
190220
if retcode is not 0:
191221
sys.exit(retcode)
222+
223+
# Initialize submodules, so we can set configs on them too.
224+
retcode = subprocess.call(['git', 'submodule', 'init'], cwd=dst)
225+
if retcode is not 0:
226+
sys.exit(retcode)
227+
192228
return dst
193229

194230

@@ -232,6 +268,7 @@ def _cli_process_current_dir(cli_args):
232268
if cli_args.protect_master:
233269
protect_master()
234270

271+
235272
if __name__ == '__main__':
236273
parser = _cli_parser()
237274
args = parser.parse_args()

0 commit comments

Comments
 (0)