Skip to content

Commit 173749f

Browse files
committed
[update-checkout] Backport recent fixes to 3.1 branch
Add fixes for problems in the --scheme, --tag, --clean, and --dump-hashes options of update-checkout to the swift-3.1-branch. Among other fixes, this will allow users to easily switch between the 3.1 and master branch schemes and to check out 3.1 tags which postdate this commit, without risk of corrupting the state of their repositories. Also brings the 3.1 branch's update-checkout-config.json file in sync with all the recent changes in branch schemes. For update-checkout, this commit includes the following commits, in chronological order: b46ce6c 34099d4 2c65c77 631495c 07ddf07 309312d 0312579 There is also a very simple one-line fix to update_repository_to_tag(), to fix a minor bug also fixed by fecbd22: "Unnecessary setting of the cross_repo flag by the --tag argument has been removed, so repos which lack the tag are now properly rebased when updated." I have deliberately omitted any recent commits which added new features to update-checkout, to minimize the chance of introducing bugs to the 3.1 branch. I also left out the recent Python lint fixes. For update-checkout-config.json, this commit includes all changes up through the present state (commit cd6474c).
1 parent 00b540b commit 173749f

File tree

2 files changed

+95
-149
lines changed

2 files changed

+95
-149
lines changed

utils/update-checkout

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,34 +43,66 @@ def update_single_repository(args):
4343
try:
4444
print("Updating '" + repo_path + "'")
4545
with shell.pushd(repo_path, dry_run=False, echo=False):
46-
shell.run(["git", "fetch", "--recurse-submodules=yes"], echo=True)
47-
46+
# The clean option should restore a repository to pristine condition.
4847
if should_clean:
4948
shell.run(['git', 'clean', '-fdx'], echo=True)
5049
shell.run(['git', 'submodule', 'foreach', '--recursive', 'git',
5150
'clean', '-fdx'], echo=True)
5251
shell.run(['git', 'submodule', 'foreach', '--recursive', 'git',
5352
'reset', '--hard', 'HEAD'], echo=True)
54-
shell.run(['git', 'reset', '--hard', 'HEAD'],
55-
echo=True)
53+
shell.run(['git', 'reset', '--hard', 'HEAD'], echo=True)
54+
# It is possible to reset --hard and still be in the middle of a rebase.
55+
try:
56+
shell.run(['git', 'rebase', '--abort'], echo=True)
57+
except:
58+
pass
5659

5760
if branch:
5861
shell.run(['git', 'status', '--porcelain', '-uno'],
5962
echo=False)
6063
shell.run(['git', 'checkout', branch], echo=True)
6164

62-
# If we were asked to reset to the specified branch, do the hard
63-
# reset and return.
64-
if reset_to_remote and not cross_repo:
65-
shell.run(['git', 'reset', '--hard', "origin/%s" % branch],
66-
echo=True)
67-
return
65+
# It's important that we checkout, fetch, and rebase, in order.
66+
# .git/FETCH_HEAD updates the not-for-merge attributes based on which
67+
# branch was checked out during the fetch.
68+
shell.run(["git", "fetch", "--recurse-submodules=yes"], echo=True)
69+
70+
# If we were asked to reset to the specified branch, do the hard
71+
# reset and return.
72+
if branch and reset_to_remote and not cross_repo:
73+
shell.run(['git', 'reset', '--hard', "origin/%s" % branch],
74+
echo=True)
75+
return
76+
77+
# Query whether we have a "detached HEAD", which will mean that
78+
# we previously checked out a tag rather than a branch.
79+
detached_head = False
80+
try:
81+
# This git command returns error code 1 if HEAD is detached.
82+
# Otherwise there was some other error, and we need to handle
83+
# it like other command errors.
84+
shell.run(["git", "symbolic-ref", "-q", "HEAD"], echo=False)
85+
except Exception as e:
86+
if e.ret == 1:
87+
detached_head = True
88+
else:
89+
raise # Pass this error up the chain.
90+
91+
# If we have a detached HEAD in this repository, we don't want
92+
# to rebase. With a detached HEAD, the fetch will have marked
93+
# all the branches in FETCH_HEAD as not-for-merge, and the
94+
# "git rebase FETCH_HEAD" will try to rebase the tree from the
95+
# default branch's current head, making a mess.
6896

6997
# Prior to Git 2.6, this is the way to do a "git pull
7098
# --rebase" that respects rebase.autostash. See
7199
# http://stackoverflow.com/a/30209750/125349
72-
if not cross_repo:
100+
if not cross_repo and not detached_head:
73101
shell.run(["git", "rebase", "FETCH_HEAD"], echo=True)
102+
elif detached_head:
103+
print(repo_path,
104+
"\nDetached HEAD; probably checked out a tag. No need to rebase.\n")
105+
74106
shell.run(["git", "submodule", "update", "--recursive"], echo=True)
75107
except:
76108
(type, value, tb) = sys.exc_info()
@@ -83,21 +115,23 @@ def update_repository_to_tag(args, repo_name, repo_path, tag_name):
83115
tag_exists = shell.capture(['git', 'ls-remote', '--tags',
84116
'origin', tag_name], echo=False)
85117
if not tag_exists:
86-
print("Skipping tagging of '" + repo_name + "', tag does not exist")
87-
return
118+
print("Tag '" + tag_name + "' does not exist for '"
119+
+ repo_name + "', just updating regularly")
120+
tag_name = None
121+
88122
return [repo_path,
89123
tag_name,
90124
args.reset_to_remote,
91125
args.clean,
92-
True]
126+
False]
93127

94128

95129
def update_repository_to_scheme(
96130
args, config, repo_name, repo_path, scheme_name, cross_repos_pr):
97131
cross_repo = False
98132
repo_branch = scheme_name
99133
# This loop is only correct, since we know that each alias set has
100-
# unique contents. This is checked by verify config. Thus the first
134+
# unique contents. This is checked by validate_config. Thus the first
101135
# branch scheme data that has scheme_name as one of its aliases is
102136
# the only possible correct answer.
103137
for v in config['branch-schemes'].values():
@@ -187,7 +221,7 @@ def obtain_all_additional_swift_sources(
187221
continue
188222

189223
if os.path.isdir(os.path.join(repo_name, ".git")):
190-
print("Skipping clone of '" + repo_name + "', directory already eixsts")
224+
print("Skipping clone of '" + repo_name + "', directory already exists")
191225
continue
192226

193227
# If we have a url override, use that url instead of
@@ -241,6 +275,14 @@ def validate_config(config):
241275
if len(scheme_names) != len(set(scheme_names)):
242276
raise RuntimeError('Configuration file has duplicate schemes?!')
243277

278+
# Ensure the branch-scheme name is also an alias
279+
# This guarantees sensible behavior of update_repository_to_scheme when
280+
# the branch-scheme is passed as the scheme name
281+
for scheme_name in config['branch-schemes'].keys():
282+
if not scheme_name in config['branch-schemes'][scheme_name]['aliases']:
283+
raise RuntimeError('branch-scheme name: "{0}" must be an alias too.'
284+
.format(scheme_name))
285+
244286
# Then make sure the alias names used by our branches are unique.
245287
#
246288
# We do this by constructing a list consisting of len(names),
@@ -323,7 +365,7 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
323365
args = parser.parse_args()
324366

325367
if args.reset_to_remote and not args.scheme:
326-
print("update-checkout usage error: --reset-to-remote must specify --branch=foo")
368+
print("update-checkout usage error: --reset-to-remote must specify --scheme=foo")
327369
exit(1)
328370

329371
clone = args.clone
@@ -338,7 +380,7 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
338380

339381
if args.dump_hashes:
340382
dump_repo_hashes(config)
341-
return 0
383+
return (None, None)
342384

343385
cross_repos_pr = {}
344386
if github_comment:

utils/update-checkout-config.json

Lines changed: 35 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
"swift-integration-tests": {
2828
"remote": { "id": "apple/swift-integration-tests" } },
2929
"swift-xcode-playground-support": {
30-
"remote": { "id": "apple/swift-xcode-playground-support" } }
30+
"remote": { "id": "apple/swift-xcode-playground-support" } },
31+
"ninja": {
32+
"remote": { "id": "ninja-build/ninja" } }
3133
},
3234
"default-branch-scheme": "master",
3335
"branch-schemes": {
@@ -37,7 +39,7 @@
3739
"llvm": "stable",
3840
"clang": "stable",
3941
"swift": "master",
40-
"lldb": "master",
42+
"lldb": "stable",
4143
"cmark": "master",
4244
"llbuild": "master",
4345
"swiftpm": "master",
@@ -46,148 +48,29 @@
4648
"swift-corelibs-foundation": "master",
4749
"swift-corelibs-libdispatch": "master",
4850
"swift-integration-tests": "master",
49-
"swift-xcode-playground-support": "master"
51+
"swift-xcode-playground-support": "master",
52+
"ninja": "release"
5053
}
5154
},
5255
"next" : {
53-
"aliases": ["master-next", "stable-next"],
54-
"repos": {
55-
"llvm": "stable-next",
56-
"clang": "stable-next",
57-
"compiler-rt": "stable-next",
58-
"swift": "master-next",
59-
"lldb": "master-next",
60-
"cmark": "master",
61-
"llbuild": "master-next",
62-
"swiftpm": "master-next",
63-
"swift-corelibs-xctest": "master-next",
64-
"swift-corelibs-foundation": "master-next",
65-
"swift-corelibs-libdispatch": "master-next",
66-
"swift-integration-tests": "master-next",
67-
"swift-xcode-playground-support": "master-next"
68-
}
69-
},
70-
"next-upstream" : {
71-
"aliases": ["next-upstream"],
56+
"aliases": ["next", "master-next",
57+
"stable-next", "upstream",
58+
"next-upstream", "upstream-with-swift"],
7259
"repos": {
7360
"llvm": "upstream-with-swift",
7461
"clang": "upstream-with-swift",
7562
"compiler-rt": "upstream-with-swift",
7663
"swift": "master-next",
77-
"lldb": "upstream",
78-
"cmark": "master",
79-
"llbuild": "master-next",
80-
"swiftpm": "master-next",
81-
"swift-corelibs-xctest": "master-next",
82-
"swift-corelibs-foundation": "master-next",
83-
"swift-corelibs-libdispatch": "master-next",
84-
"swift-integration-tests": "master-next",
85-
"swift-xcode-playground-support": "master-next"
86-
}
87-
},
88-
"upstream": {
89-
"aliases": ["upstream"],
90-
"repos": {
91-
"llvm": "upstream-with-swift",
92-
"clang": "upstream-with-swift",
93-
"compiler-rt": "upstream-with-swift",
94-
"swift": "master",
95-
"lldb": "master",
64+
"lldb": "upstream-with-swift",
9665
"cmark": "master",
9766
"llbuild": "master",
9867
"swiftpm": "master",
9968
"swift-corelibs-xctest": "master",
10069
"swift-corelibs-foundation": "master",
10170
"swift-corelibs-libdispatch": "master",
10271
"swift-integration-tests": "master",
103-
"swift-xcode-playground-support": "master"
104-
}
105-
},
106-
"swift-3.0-preview-1" : {
107-
"aliases": ["swift-3.0-preview-1-branch"],
108-
"repos": {
109-
"llvm": "swift-3.0-branch",
110-
"clang": "swift-3.0-branch",
111-
"swift": "swift-3.0-preview-1-branch",
112-
"lldb": "swift-3.0-preview-1-branch",
113-
"cmark": "swift-3.0-preview-1-branch",
114-
"llbuild": "swift-3.0-preview-1-branch",
115-
"swiftpm": "swift-3.0-preview-1-branch",
116-
"compiler-rt": "swift-3.0-branch",
117-
"swift-corelibs-xctest": "swift-3.0-preview-1-branch",
118-
"swift-corelibs-foundation": "swift-3.0-preview-1-branch",
119-
"swift-corelibs-libdispatch": "swift-3.0-preview-1-branch",
120-
"swift-integration-tests": "swift-3.0-preview-1-branch"
121-
}
122-
},
123-
"swift-3.0-preview-2" : {
124-
"aliases": ["swift-3.0-preview-2-branch"],
125-
"repos": {
126-
"llvm": "swift-3.0-branch",
127-
"clang": "swift-3.0-branch",
128-
"swift": "swift-3.0-preview-2-branch",
129-
"lldb": "swift-3.0-preview-2-branch",
130-
"cmark": "swift-3.0-preview-2-branch",
131-
"llbuild": "swift-3.0-preview-2-branch",
132-
"swiftpm": "swift-3.0-preview-2-branch",
133-
"compiler-rt": "swift-3.0-branch",
134-
"swift-corelibs-xctest": "swift-3.0-preview-2-branch",
135-
"swift-corelibs-foundation": "swift-3.0-preview-2-branch",
136-
"swift-corelibs-libdispatch": "swift-3.0-preview-2-branch",
137-
"swift-integration-tests": "swift-3.0-preview-2-branch"
138-
}
139-
},
140-
"swift-3.0-preview-3" : {
141-
"aliases": ["swift-3.0-preview-3-branch"],
142-
"repos": {
143-
"llvm": "swift-3.0-branch",
144-
"clang": "swift-3.0-branch",
145-
"swift": "swift-3.0-preview-3-branch",
146-
"lldb": "swift-3.0-preview-3-branch",
147-
"cmark": "swift-3.0-preview-3-branch",
148-
"llbuild": "swift-3.0-preview-3-branch",
149-
"swiftpm": "swift-3.0-preview-3-branch",
150-
"compiler-rt": "swift-3.0-branch",
151-
"swift-corelibs-xctest": "swift-3.0-preview-3-branch",
152-
"swift-corelibs-foundation": "swift-3.0-preview-3-branch",
153-
"swift-corelibs-libdispatch": "swift-3.0-preview-3-branch",
154-
"swift-integration-tests": "swift-3.0-preview-3-branch"
155-
}
156-
},
157-
"swift-3.0-preview-4" : {
158-
"aliases": ["swift-3.0-preview-4-branch"],
159-
"repos": {
160-
"llvm": "swift-3.0-branch",
161-
"clang": "swift-3.0-branch",
162-
"swift": "swift-3.0-preview-4-branch",
163-
"lldb": "swift-3.0-preview-4-branch",
164-
"cmark": "swift-3.0-preview-4-branch",
165-
"llbuild": "swift-3.0-preview-4-branch",
166-
"swiftpm": "swift-3.0-preview-4-branch",
167-
"compiler-rt": "swift-3.0-branch",
168-
"swift-corelibs-xctest": "swift-3.0-preview-4-branch",
169-
"swift-corelibs-foundation": "swift-3.0-preview-4-branch",
170-
"swift-corelibs-libdispatch": "swift-3.0-preview-4-branch",
171-
"swift-integration-tests": "swift-3.0-preview-4-branch",
172-
"swift-xcode-playground-support": "swift-3.0-preview-4-branch"
173-
}
174-
},
175-
"swift-3.0-preview-5" : {
176-
"aliases": ["swift-3.0-preview-5-branch"],
177-
"repos": {
178-
"llvm": "swift-3.0-branch",
179-
"clang": "swift-3.0-branch",
180-
"swift": "swift-3.0-preview-5-branch",
181-
"lldb": "swift-3.0-preview-5-branch",
182-
"cmark": "swift-3.0-preview-5-branch",
183-
"llbuild": "swift-3.0-preview-5-branch",
184-
"swiftpm": "swift-3.0-preview-5-branch",
185-
"compiler-rt": "swift-3.0-branch",
186-
"swift-corelibs-xctest": "swift-3.0-preview-5-branch",
187-
"swift-corelibs-foundation": "swift-3.0-preview-5-branch",
188-
"swift-corelibs-libdispatch": "swift-3.0-preview-5-branch",
189-
"swift-integration-tests": "swift-3.0-preview-5-branch",
190-
"swift-xcode-playground-support": "swift-3.0-preview-5-branch"
72+
"swift-xcode-playground-support": "master",
73+
"ninja": "release"
19174
}
19275
},
19376
"swift-3.0-branch" : {
@@ -205,7 +88,8 @@
20588
"swift-corelibs-foundation": "swift-3.0-branch",
20689
"swift-corelibs-libdispatch": "swift-3.0-branch",
20790
"swift-integration-tests": "swift-3.0-branch",
208-
"swift-xcode-playground-support": "swift-3.0-branch"
91+
"swift-xcode-playground-support": "swift-3.0-branch",
92+
"ninja": "release"
20993
}
21094
},
21195
"swift-3.1-branch" : {
@@ -223,7 +107,27 @@
223107
"swift-corelibs-foundation": "swift-3.1-branch",
224108
"swift-corelibs-libdispatch": "swift-3.1-branch",
225109
"swift-integration-tests": "swift-3.1-branch",
226-
"swift-xcode-playground-support": "swift-3.1-branch"
110+
"swift-xcode-playground-support": "swift-3.1-branch",
111+
"ninja": "release"
112+
}
113+
},
114+
"swift-4.0-branch" : {
115+
"aliases": ["swift-4.0-branch"],
116+
"repos": {
117+
"llvm": "swift-4.0-branch",
118+
"clang": "swift-4.0-branch",
119+
"swift": "swift-4.0-branch",
120+
"lldb": "swift-4.0-branch",
121+
"cmark": "swift-3.1-branch",
122+
"llbuild": "swift-3.1-branch",
123+
"swiftpm": "swift-3.1-branch",
124+
"compiler-rt": "swift-4.0-branch",
125+
"swift-corelibs-xctest": "swift-3.1-branch",
126+
"swift-corelibs-foundation": "swift-3.1-branch",
127+
"swift-corelibs-libdispatch": "swift-3.1-branch",
128+
"swift-integration-tests": "swift-3.1-branch",
129+
"swift-xcode-playground-support": "swift-3.1-branch",
130+
"ninja": "release"
227131
}
228132
}
229133
}

0 commit comments

Comments
 (0)