11using System ;
22using System . Collections . Generic ;
3+ using System . IO ;
34using System . Threading . Tasks ;
5+
46using Avalonia . Threading ;
57using CommunityToolkit . Mvvm . ComponentModel ;
68
@@ -26,7 +28,30 @@ public object EndPoint
2628 private set => SetProperty ( ref _endPoint , value ) ;
2729 }
2830
29- public bool CanSaveAsPatch { get ; }
31+ public string LeftSideDesc
32+ {
33+ get => GetDesc ( StartPoint ) ;
34+ }
35+
36+ public string RightSideDesc
37+ {
38+ get => GetDesc ( EndPoint ) ;
39+ }
40+
41+ public bool CanResetToLeft
42+ {
43+ get => ! _repo . IsBare && _startPoint != null ;
44+ }
45+
46+ public bool CanResetToRight
47+ {
48+ get => ! _repo . IsBare && _endPoint != null ;
49+ }
50+
51+ public bool CanSaveAsPatch
52+ {
53+ get => _startPoint != null && _endPoint != null ;
54+ }
3055
3156 public int TotalChanges
3257 {
@@ -50,7 +75,7 @@ public List<Models.Change> SelectedChanges
5075 if ( value is { Count : 1 } )
5176 {
5277 var option = new Models . DiffOption ( GetSHA ( _startPoint ) , GetSHA ( _endPoint ) , value [ 0 ] ) ;
53- DiffContext = new DiffContext ( _repo , option , _diffContext ) ;
78+ DiffContext = new DiffContext ( _repo . FullPath , option , _diffContext ) ;
5479 }
5580 else
5681 {
@@ -76,12 +101,11 @@ public DiffContext DiffContext
76101 private set => SetProperty ( ref _diffContext , value ) ;
77102 }
78103
79- public RevisionCompare ( string repo , Models . Commit startPoint , Models . Commit endPoint )
104+ public RevisionCompare ( Repository repo , Models . Commit startPoint , Models . Commit endPoint )
80105 {
81106 _repo = repo ;
82107 _startPoint = ( object ) startPoint ?? new Models . Null ( ) ;
83108 _endPoint = ( object ) endPoint ?? new Models . Null ( ) ;
84- CanSaveAsPatch = startPoint != null && endPoint != null ;
85109 Refresh ( ) ;
86110 }
87111
@@ -100,23 +124,12 @@ public void Dispose()
100124 public void OpenChangeWithExternalDiffTool ( Models . Change change )
101125 {
102126 var opt = new Models . DiffOption ( GetSHA ( _startPoint ) , GetSHA ( _endPoint ) , change ) ;
103- new Commands . DiffTool ( _repo , opt ) . Open ( ) ;
127+ new Commands . DiffTool ( _repo . FullPath , opt ) . Open ( ) ;
104128 }
105129
106130 public void NavigateTo ( string commitSHA )
107131 {
108- var launcher = App . GetLauncher ( ) ;
109- if ( launcher == null )
110- return ;
111-
112- foreach ( var page in launcher . Pages )
113- {
114- if ( page . Data is Repository repo && repo . FullPath . Equals ( _repo ) )
115- {
116- repo . NavigateToCommit ( commitSHA ) ;
117- break ;
118- }
119- }
132+ _repo ? . NavigateToCommit ( commitSHA ) ;
120133 }
121134
122135 public void Swap ( )
@@ -130,14 +143,170 @@ public void Swap()
130143
131144 public string GetAbsPath ( string path )
132145 {
133- return Native . OS . GetAbsPath ( _repo , path ) ;
146+ return Native . OS . GetAbsPath ( _repo . FullPath , path ) ;
147+ }
148+
149+ public async Task ResetToLeftAsync ( Models . Change change )
150+ {
151+ var sha = GetSHA ( _startPoint ) ;
152+ var log = _repo . CreateLog ( $ "Reset File to '{ GetDesc ( _startPoint ) } '") ;
153+
154+ if ( change . Index == Models . ChangeState . Added )
155+ {
156+ var fullpath = Native . OS . GetAbsPath ( _repo . FullPath , change . Path ) ;
157+ if ( File . Exists ( fullpath ) )
158+ await new Commands . Remove ( _repo . FullPath , [ change . Path ] )
159+ . Use ( log )
160+ . ExecAsync ( ) ;
161+ }
162+ else if ( change . Index == Models . ChangeState . Renamed )
163+ {
164+ var renamed = Native . OS . GetAbsPath ( _repo . FullPath , change . Path ) ;
165+ if ( File . Exists ( renamed ) )
166+ await new Commands . Remove ( _repo . FullPath , [ change . Path ] )
167+ . Use ( log )
168+ . ExecAsync ( ) ;
169+
170+ await new Commands . Checkout ( _repo . FullPath )
171+ . Use ( log )
172+ . FileWithRevisionAsync ( change . OriginalPath , sha ) ;
173+ }
174+ else
175+ {
176+ await new Commands . Checkout ( _repo . FullPath )
177+ . Use ( log )
178+ . FileWithRevisionAsync ( change . Path , sha ) ;
179+ }
180+
181+ log . Complete ( ) ;
182+ }
183+
184+ public async Task ResetToRightAsync ( Models . Change change )
185+ {
186+ var sha = GetSHA ( _endPoint ) ;
187+ var log = _repo . CreateLog ( $ "Reset File to '{ GetDesc ( _endPoint ) } '") ;
188+
189+ if ( change . Index == Models . ChangeState . Deleted )
190+ {
191+ var fullpath = Native . OS . GetAbsPath ( _repo . FullPath , change . Path ) ;
192+ if ( File . Exists ( fullpath ) )
193+ await new Commands . Remove ( _repo . FullPath , [ change . Path ] )
194+ . Use ( log )
195+ . ExecAsync ( ) ;
196+ }
197+ else if ( change . Index == Models . ChangeState . Renamed )
198+ {
199+ var old = Native . OS . GetAbsPath ( _repo . FullPath , change . OriginalPath ) ;
200+ if ( File . Exists ( old ) )
201+ await new Commands . Remove ( _repo . FullPath , [ change . OriginalPath ] )
202+ . Use ( log )
203+ . ExecAsync ( ) ;
204+
205+ await new Commands . Checkout ( _repo . FullPath )
206+ . Use ( log )
207+ . FileWithRevisionAsync ( change . Path , sha ) ;
208+ }
209+ else
210+ {
211+ await new Commands . Checkout ( _repo . FullPath )
212+ . Use ( log )
213+ . FileWithRevisionAsync ( change . Path , sha ) ;
214+ }
215+
216+ log . Complete ( ) ;
217+ }
218+
219+ public async Task ResetMultipleToLeftAsync ( List < Models . Change > changes )
220+ {
221+ var sha = GetSHA ( _startPoint ) ;
222+ var checkouts = new List < string > ( ) ;
223+ var removes = new List < string > ( ) ;
224+
225+ foreach ( var c in changes )
226+ {
227+ if ( c . Index == Models . ChangeState . Added )
228+ {
229+ var fullpath = Native . OS . GetAbsPath ( _repo . FullPath , c . Path ) ;
230+ if ( File . Exists ( fullpath ) )
231+ removes . Add ( c . Path ) ;
232+ }
233+ else if ( c . Index == Models . ChangeState . Renamed )
234+ {
235+ var old = Native . OS . GetAbsPath ( _repo . FullPath , c . Path ) ;
236+ if ( File . Exists ( old ) )
237+ removes . Add ( c . Path ) ;
238+
239+ checkouts . Add ( c . OriginalPath ) ;
240+ }
241+ else
242+ {
243+ checkouts . Add ( c . Path ) ;
244+ }
245+ }
246+
247+ var log = _repo . CreateLog ( $ "Reset Files to '{ GetDesc ( _startPoint ) } '") ;
248+
249+ if ( removes . Count > 0 )
250+ await new Commands . Remove ( _repo . FullPath , removes )
251+ . Use ( log )
252+ . ExecAsync ( ) ;
253+
254+ if ( checkouts . Count > 0 )
255+ await new Commands . Checkout ( _repo . FullPath )
256+ . Use ( log )
257+ . MultipleFilesWithRevisionAsync ( checkouts , sha ) ;
258+
259+ log . Complete ( ) ;
260+ }
261+
262+ public async Task ResetMultipleToRightAsync ( List < Models . Change > changes )
263+ {
264+ var sha = GetSHA ( _endPoint ) ;
265+ var checkouts = new List < string > ( ) ;
266+ var removes = new List < string > ( ) ;
267+
268+ foreach ( var c in changes )
269+ {
270+ if ( c . Index == Models . ChangeState . Deleted )
271+ {
272+ var fullpath = Native . OS . GetAbsPath ( _repo . FullPath , c . Path ) ;
273+ if ( File . Exists ( fullpath ) )
274+ removes . Add ( c . Path ) ;
275+ }
276+ else if ( c . Index == Models . ChangeState . Renamed )
277+ {
278+ var renamed = Native . OS . GetAbsPath ( _repo . FullPath , c . OriginalPath ) ;
279+ if ( File . Exists ( renamed ) )
280+ removes . Add ( c . OriginalPath ) ;
281+
282+ checkouts . Add ( c . Path ) ;
283+ }
284+ else
285+ {
286+ checkouts . Add ( c . Path ) ;
287+ }
288+ }
289+
290+ var log = _repo . CreateLog ( $ "Reset Files to '{ GetDesc ( _endPoint ) } '") ;
291+
292+ if ( removes . Count > 0 )
293+ await new Commands . Remove ( _repo . FullPath , removes )
294+ . Use ( log )
295+ . ExecAsync ( ) ;
296+
297+ if ( checkouts . Count > 0 )
298+ await new Commands . Checkout ( _repo . FullPath )
299+ . Use ( log )
300+ . MultipleFilesWithRevisionAsync ( checkouts , sha ) ;
301+
302+ log . Complete ( ) ;
134303 }
135304
136305 public async Task SaveChangesAsPatchAsync ( List < Models . Change > changes , string saveTo )
137306 {
138- var succ = await Commands . SaveChangesAsPatch . ProcessRevisionCompareChangesAsync ( _repo , changes ?? _changes , GetSHA ( _startPoint ) , GetSHA ( _endPoint ) , saveTo ) ;
307+ var succ = await Commands . SaveChangesAsPatch . ProcessRevisionCompareChangesAsync ( _repo . FullPath , changes ?? _changes , GetSHA ( _startPoint ) , GetSHA ( _endPoint ) , saveTo ) ;
139308 if ( succ )
140- App . SendNotification ( _repo , App . Text ( "SaveAsPatchSuccess" ) ) ;
309+ App . SendNotification ( _repo . FullPath , App . Text ( "SaveAsPatchSuccess" ) ) ;
141310 }
142311
143312 public void ClearSearchFilter ( )
@@ -171,7 +340,7 @@ private void Refresh()
171340 {
172341 Task . Run ( async ( ) =>
173342 {
174- _changes = await new Commands . CompareRevisions ( _repo , GetSHA ( _startPoint ) , GetSHA ( _endPoint ) )
343+ _changes = await new Commands . CompareRevisions ( _repo . FullPath , GetSHA ( _startPoint ) , GetSHA ( _endPoint ) )
175344 . ReadAsync ( )
176345 . ConfigureAwait ( false ) ;
177346
@@ -205,7 +374,12 @@ private string GetSHA(object obj)
205374 return obj is Models . Commit commit ? commit . SHA : string . Empty ;
206375 }
207376
208- private string _repo ;
377+ private string GetDesc ( object obj )
378+ {
379+ return obj is Models . Commit commit ? commit . GetFriendlyName ( ) : App . Text ( "Worktree" ) ;
380+ }
381+
382+ private Repository _repo ;
209383 private bool _isLoading = true ;
210384 private object _startPoint = null ;
211385 private object _endPoint = null ;
0 commit comments