@@ -30,6 +30,7 @@ class LandingSession extends Session {
30
30
this . lint = lint ;
31
31
this . autorebase = autorebase ;
32
32
this . fixupAll = fixupAll ;
33
+ this . expectedCommitShas = [ ] ;
33
34
}
34
35
35
36
get argv ( ) {
@@ -44,6 +45,8 @@ class LandingSession extends Session {
44
45
async start ( metadata ) {
45
46
const { cli } = this ;
46
47
this . startLanding ( ) ;
48
+ this . expectedCommitShas =
49
+ metadata . data . commits . map ( ( { commit } ) => commit . oid ) ;
47
50
const status = metadata . status ? 'should be ready' : 'is not ready' ;
48
51
// NOTE(mmarchini): default answer is yes. If --yes is given, we need to be
49
52
// more careful though, and we change the default to the result of our
@@ -78,34 +81,44 @@ class LandingSession extends Session {
78
81
}
79
82
80
83
async downloadAndPatch ( ) {
81
- const { cli, req , repo, owner, prid } = this ;
84
+ const { cli, repo, owner, prid, expectedCommitShas } = this ;
82
85
83
- // TODO(joyeecheung): restore previously downloaded patches
84
86
cli . startSpinner ( `Downloading patch for ${ prid } ` ) ;
85
- const patch = await req . text (
86
- `https://github.com/${ owner } /${ repo } /pull/${ prid } .patch` ) ;
87
- this . savePatch ( patch ) ;
88
- cli . stopSpinner ( `Downloaded patch to ${ this . patchPath } ` ) ;
87
+ await runAsync ( 'git' , [
88
+ 'fetch' , `https://github.com/${ owner } /${ repo } .git` ,
89
+ `refs/pull/${ prid } /merge` ] ) ;
90
+ const [ base , head ] = ( await runAsync ( 'git' , [
91
+ 'rev-parse' , 'FETCH_HEAD^1' , 'FETCH_HEAD^2' ] , { captureStdout : true } ) )
92
+ . split ( '\n' ) ;
93
+ const commitShas = ( await runAsync ( 'git' , [
94
+ 'rev-list' , `${ base } ..${ head } ` ] , { captureStdout : true } ) )
95
+ . trim ( ) . split ( '\n' ) ;
96
+ cli . stopSpinner ( `Fetched commits as ${ shortSha ( base ) } ..${ shortSha ( head ) } ` ) ;
89
97
cli . separator ( ) ;
90
- // TODO: check that patches downloaded match metadata.commits
98
+
99
+ const mismatchedCommits = [
100
+ ...commitShas . filter ( ( sha ) => ! expectedCommitShas . includes ( sha ) )
101
+ . map ( ( sha ) => `Unexpected commit ${ sha } ` ) ,
102
+ ...expectedCommitShas . filter ( ( sha ) => ! commitShas . includes ( sha ) )
103
+ . map ( ( sha ) => `Missing commit ${ sha } ` )
104
+ ] . join ( '\n' ) ;
105
+ if ( mismatchedCommits . length > 0 ) {
106
+ cli . error ( `Mismatched commits:\n${ mismatchedCommits } ` ) ;
107
+ process . exit ( 1 ) ;
108
+ }
109
+
110
+ const commitInfo = { base, head, shas : commitShas } ;
111
+ this . saveCommitInfo ( commitInfo ) ;
112
+
91
113
try {
92
- await forceRunAsync ( 'git' , [ 'am ' , this . patchPath ] , {
114
+ await forceRunAsync ( 'git' , [ 'cherry-pick ' , ` ${ base } .. ${ head } ` ] , {
93
115
ignoreFailure : false
94
116
} ) ;
95
117
} catch ( ex ) {
96
- const should3Way = await cli . prompt (
97
- 'The normal `git am` failed. Do you want to retry with 3-way merge?' ) ;
98
- if ( should3Way ) {
99
- await forceRunAsync ( 'git' , [ 'am' , '--abort' ] ) ;
100
- await runAsync ( 'git' , [
101
- 'am' ,
102
- '-3' ,
103
- this . patchPath
104
- ] ) ;
105
- } else {
106
- cli . error ( 'Failed to apply patches' ) ;
107
- process . exit ( 1 ) ;
108
- }
118
+ await forceRunAsync ( 'git' , [ 'cherry-pick' , '--abort' ] ) ;
119
+
120
+ cli . error ( 'Failed to apply patches' ) ;
121
+ process . exit ( 1 ) ;
109
122
}
110
123
111
124
// Check for and maybe assign any unmarked deprecations in the codebase.
@@ -126,7 +139,7 @@ class LandingSession extends Session {
126
139
}
127
140
128
141
cli . ok ( 'Patches applied' ) ;
129
- return patch ;
142
+ return commitInfo ;
130
143
}
131
144
132
145
getRebaseSuggestion ( subjects ) {
@@ -173,21 +186,13 @@ class LandingSession extends Session {
173
186
}
174
187
}
175
188
176
- async tryCompleteLanding ( patch ) {
189
+ async tryCompleteLanding ( commitInfo ) {
177
190
const { cli } = this ;
191
+ const subjects = ( await runAsync ( 'git' ,
192
+ [ 'log' , '--pretty=format:%s' , `${ commitInfo . base } ..${ commitInfo . head } ` ] ,
193
+ { captureStdout : true } ) ) . trim ( ) . split ( '\n' ) ;
178
194
179
- const subjects = patch . match ( / S u b j e c t : \[ P A T C H .* ?\] .* / g) ;
180
- if ( ! subjects ) {
181
- cli . warn ( 'Cannot get number of commits in the patch. ' +
182
- 'It seems to be malformed' ) ;
183
- return ;
184
- }
185
-
186
- // XXX(joyeecheung) we cannot guarantee that no one will put a subject
187
- // line in the commit message but that seems unlikely (some deps update
188
- // might do that).
189
- if ( subjects . length === 1 ) {
190
- // assert(subjects[0].startsWith('Subject: [PATCH]'))
195
+ if ( commitInfo . shas . length === 1 ) {
191
196
const shouldAmend = await cli . prompt (
192
197
'There is only one commit in this PR.\n' +
193
198
'do you want to amend the commit message?' ) ;
@@ -247,7 +252,7 @@ class LandingSession extends Session {
247
252
}
248
253
await this . tryResetBranch ( ) ;
249
254
250
- const patch = await this . downloadAndPatch ( ) ;
255
+ const commitInfo = await this . downloadAndPatch ( ) ;
251
256
252
257
const cleanLint = await this . validateLint ( ) ;
253
258
if ( cleanLint === LINT_RESULTS . FAILED ) {
@@ -280,7 +285,7 @@ class LandingSession extends Session {
280
285
281
286
this . startAmending ( ) ;
282
287
283
- await this . tryCompleteLanding ( patch ) ;
288
+ await this . tryCompleteLanding ( commitInfo ) ;
284
289
}
285
290
286
291
async amend ( ) {
@@ -407,13 +412,13 @@ class LandingSession extends Session {
407
412
}
408
413
if ( this . isApplying ( ) ) {
409
414
// We're still resolving conflicts.
410
- if ( this . amInProgress ( ) ) {
411
- cli . log ( 'Looks like you are resolving a `git am ` conflict' ) ;
415
+ if ( this . cherryPickInProgress ( ) ) {
416
+ cli . log ( 'Looks like you are resolving a `git cherry-pick ` conflict' ) ;
412
417
cli . log ( 'Please run `git status` for help' ) ;
413
418
} else {
414
419
// Conflicts has been resolved - amend.
415
420
this . startAmending ( ) ;
416
- return this . tryCompleteLanding ( this . patch ) ;
421
+ return this . tryCompleteLanding ( this . commitInfo ) ;
417
422
}
418
423
return ;
419
424
}
0 commit comments