@@ -22,25 +22,43 @@ const revItems = (revisions: Revision[]): RevisionItem[] =>
22
22
revision : r
23
23
} ) )
24
24
25
+ const loadRevisions = async ( uri : Uri , withRefresh = true ) => {
26
+ const service = AbapRevisionService . get ( uri . authority )
27
+ const revisions = await service . uriRevisions ( uri , withRefresh )
28
+ return revisions || [ ]
29
+ }
30
+
31
+ const pickRevision = async ( revisions : Revision [ ] , title = "Select version" ) => {
32
+ if ( ! revisions . length ) return
33
+ if ( revisions . length === 1 ) return revisions [ 0 ]
34
+ const selected = await window . showQuickPick ( revItems ( revisions ) , { placeHolder : title } )
35
+ return selected ?. revision || false
36
+ }
37
+
25
38
const selectRevision = async (
26
39
uri : Uri ,
27
40
title = "Select version" ,
28
41
withRefresh = true
29
42
) => {
30
- const service = AbapRevisionService . get ( uri . authority )
31
- const revisions = await service . uriRevisions ( uri , false )
32
- if ( ! revisions ?. length ) return
33
- if ( revisions . length === 1 ) return revisions [ 0 ]
34
- const selected = await window . showQuickPick ( revItems ( revisions ) , {
35
- placeHolder : title
36
- } )
37
- return selected ?. revision || false
43
+ const revisions = await loadRevisions ( uri , withRefresh )
44
+ return pickRevision ( revisions , title )
38
45
}
39
46
const CURRENTREV = "current"
40
47
41
48
const diffTitle = ( uri : Uri , lvers : string , rvers : string ) =>
42
49
`${ uri . path . split ( "/" ) . pop ( ) || uri . toString ( ) } ${ lvers } ->${ rvers } `
43
50
51
+ const pickCommonAncestor = ( locals : Revision [ ] , localVer : Revision , remotes : Revision [ ] , remoteVer : Revision ) => {
52
+ const localTime = new Date ( localVer . date ) . getTime ( )
53
+ const possibleLocals = locals . filter ( l => new Date ( l . date ) . getTime ( ) < localTime )
54
+ const remoteTime = new Date ( remoteVer . date ) . getTime ( )
55
+ const possibleRemotes = remotes . filter ( l => new Date ( l . date ) . getTime ( ) < remoteTime )
56
+ for ( const l of possibleLocals )
57
+ if ( possibleRemotes . find ( r => r . version && r . version === l . version ) ) return l
58
+ return pickRevision ( possibleLocals , "Unable to determine common ancestor, please select base for comparison" )
59
+ }
60
+
61
+
44
62
export const displayRevDiff = (
45
63
rightRev : Revision | undefined ,
46
64
leftRev : Revision | undefined ,
@@ -116,6 +134,52 @@ export class AbapRevisionCommands {
116
134
if ( ! rightRev ) return
117
135
displayRevDiff ( rightRev , leftRev , uri )
118
136
}
137
+
138
+ @command ( AbapFsCommands . mergeEditor )
139
+ private static async mergeConflicts ( uri : Uri ) {
140
+ if ( ! abapUri ( uri ) ) return
141
+ try {
142
+ const file = uriRoot ( uri ) . getNode ( uri . path )
143
+ if ( ! isAbapFile ( file ) ) return
144
+ const { remote, userCancel } = await RemoteManager . get ( ) . selectConnection (
145
+ undefined ,
146
+ r => r . name . toLowerCase ( ) !== uri . authority
147
+ )
148
+ if ( ! remote )
149
+ if ( userCancel ) return
150
+ else throw Error ( "No remote system available in configuration" )
151
+
152
+ const remoteRoot = await getOrCreateRoot ( formatKey ( remote . name ) )
153
+ if ( ! remoteRoot ) throw Error ( `Faild to connect to server ${ remote . name } ` )
154
+
155
+ const path = await remoteRoot . findByAdtUri ( file . object . path )
156
+ if ( ! path ) throw Error ( `Object not found in remote ${ remote . name } ` )
157
+
158
+ const remoteUri = uri . with ( { authority : remoteRoot . connId , path : path . path } )
159
+
160
+ const remotes = await loadRevisions ( remoteUri , true )
161
+ const remoteVer = await pickRevision ( remotes , "Remote version" )
162
+ if ( ! remoteVer ) return
163
+ const locals = await loadRevisions ( uri , true )
164
+ const localVer = await pickRevision ( locals , "Local version" )
165
+ if ( ! localVer ) return
166
+ const baseVer = await pickCommonAncestor ( locals , localVer , remotes , remoteVer )
167
+ if ( ! baseVer ) return
168
+ const base = revisionUri ( uri , baseVer )
169
+
170
+ const description = uri . path . replace ( / .* \/ / , "" )
171
+
172
+ const options = {
173
+ base,
174
+ input1 : { uri : revisionUri ( uri , localVer ) , title : uri . authority , description, detail : localVer . version } ,
175
+ input2 : { uri : revisionUri ( remoteUri , remoteVer ) , title : remoteUri . authority , description, detail : remoteVer . version } ,
176
+ output : uri
177
+ }
178
+ return commands . executeCommand < void > ( "_open.mergeEditor" , options )
179
+ } catch ( e ) {
180
+ window . showErrorMessage ( caughtToString ( e ) )
181
+ }
182
+ }
119
183
@command ( AbapFsCommands . clearScmGroup )
120
184
private static clearGroup ( group : AGroup ) {
121
185
group . resourceStates = [ ]
@@ -149,3 +213,4 @@ export class AbapRevisionCommands {
149
213
} )
150
214
}
151
215
}
216
+
0 commit comments