Skip to content

Commit 5fb6bb2

Browse files
authored
Merge pull request #7539 from graydon/teach-update-checkout-to-match-current-timestamp
2 parents 9f132d4 + e617d11 commit 5fb6bb2

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

utils/update-checkout

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ def confirm_tag_in_repo(tag, repo_name):
4545
return tag
4646

4747

48+
def find_rev_by_timestamp(timestamp, repo_name, refspec):
49+
base_args = ["git", "log", "-1", "--format=%H",
50+
'--before=' + timestamp]
51+
# Prefer the most-recent change _made by swift-ci_ before the timestamp,
52+
# falling back to most-recent in general if there is none by swift-ci.
53+
rev = shell.capture(base_args + [ '--author', 'swift-ci', refspec]).strip()
54+
if rev:
55+
return rev
56+
rev = shell.capture(base_args + [refspec]).strip()
57+
if rev:
58+
return rev
59+
else:
60+
raise RuntimeError('No rev in %s before timestamp %s' %
61+
(repo_name, timestamp))
62+
63+
4864
def get_branch_for_repo(config, repo_name, scheme_name, scheme_map,
4965
cross_repos_pr):
5066
cross_repo = False
@@ -68,8 +84,8 @@ def get_branch_for_repo(config, repo_name, scheme_name, scheme_map,
6884

6985

7086
def update_single_repository(args):
71-
config, repo_name, scheme_name, scheme_map, tag, reset_to_remote, \
72-
should_clean, cross_repos_pr = args
87+
config, repo_name, scheme_name, scheme_map, tag, timestamp, \
88+
reset_to_remote, should_clean, cross_repos_pr = args
7389
repo_path = os.path.join(SWIFT_SOURCE_ROOT, repo_name)
7490
if not os.path.isdir(repo_path):
7591
return
@@ -84,6 +100,13 @@ def update_single_repository(args):
84100
elif scheme_name:
85101
checkout_target, cross_repo = get_branch_for_repo(
86102
config, repo_name, scheme_name, scheme_map, cross_repos_pr)
103+
if timestamp:
104+
checkout_target = find_rev_by_timestamp(timestamp,
105+
repo_name,
106+
checkout_target)
107+
elif timestamp:
108+
checkout_target = find_rev_by_timestamp(timestamp, repo_name,
109+
"HEAD")
87110

88111
# The clean option restores a repository to pristine condition.
89112
if should_clean:
@@ -153,6 +176,14 @@ def update_single_repository(args):
153176
return value
154177

155178

179+
def get_timestamp_to_match(args):
180+
if not args.match_timestamp:
181+
return None
182+
with shell.pushd(os.path.join(SWIFT_SOURCE_ROOT, "swift"),
183+
dry_run=False, echo=False):
184+
return shell.capture(["git", "log", "-1", "--format=%cI"],
185+
echo=False).strip()
186+
156187
def update_all_repositories(args, config, scheme_name, cross_repos_pr):
157188
scheme_map = None
158189
if scheme_name:
@@ -165,6 +196,7 @@ def update_all_repositories(args, config, scheme_name, cross_repos_pr):
165196
scheme_map = v['repos']
166197
break
167198
pool_args = []
199+
timestamp = get_timestamp_to_match(args)
168200
for repo_name in config['repos'].keys():
169201
if repo_name in args.skip_repository_list:
170202
print("Skipping update of '" + repo_name + "', requested by user")
@@ -174,6 +206,7 @@ def update_all_repositories(args, config, scheme_name, cross_repos_pr):
174206
scheme_name,
175207
scheme_map,
176208
args.tag,
209+
timestamp,
177210
args.reset_to_remote,
178211
args.clean,
179212
cross_repos_pr]
@@ -385,6 +418,11 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
385418
"--tag",
386419
help="""Check out each repository to the specified tag.""",
387420
metavar='TAG-NAME')
421+
parser.add_argument(
422+
"--match-timestamp",
423+
help='Check out adjacent repositories to match timestamp of '
424+
' current swift checkout.',
425+
action='store_true')
388426
parser.add_argument(
389427
"-j", "--jobs",
390428
type=int,

0 commit comments

Comments
 (0)