@@ -363,31 +363,45 @@ def apply_pull_changes(self, changes, temp_dir):
363363 basefile = self .fpath_meta (path )
364364
365365 # special care is needed for geodiff files
366+ # 'src' here is server version of file and 'dest' is locally modified
366367 if self .is_versioned_file (path ) and k == 'updated' :
367368 if path in modified :
369+ server_diff = self .fpath (f'{ path } -server_diff' , temp_dir ) # diff between server file and local basefile
370+ local_diff = self .fpath (f'{ path } -local_diff' , temp_dir )
371+
372+ # temporary backup of file pulled from server for recovery
368373 f_server_backup = self .fpath (f'{ path } -server_backup' , temp_dir )
369- server_diff = self .fpath (f'{ path } -server_diff' , temp_dir ) # single origin diff from 'diffs' for use in rebase
370- rebased_diff = self .fpath (f'{ path } -rebased' , temp_dir )
371- shutil .copy (src , f_server_backup ) # temporary backup of file pulled from server for test and recovery
374+ shutil .copy (src , f_server_backup )
375+
376+ # create temp backup (ideally with geodiff) of locally modified file if needed later
377+ f_conflict_file = self .fpath (f'{ path } -local_backup' , temp_dir )
372378 try :
373- self .geodiff .create_changeset (basefile , src , server_diff )
374- self .geodiff .create_rebased_changeset (basefile , dest , server_diff , rebased_diff )
375- # update file with rebased_diff to contain both server and local changes
376- self .geodiff .apply_changeset (src , rebased_diff )
377- # try to create final changeset to be potentially committed in push
378- changeset = self .fpath (f'{ path } -local_diff' , temp_dir )
379- self .geodiff .create_changeset (f_server_backup , src , changeset )
380- # we are happy with rebase, prepare 'live' versions of files
381- shutil .copy (f_server_backup , basefile )
382- shutil .copy (src , dest )
379+ self .geodiff .create_changeset (basefile , dest , local_diff )
380+ shutil .copy (basefile , f_conflict_file )
381+ self .geodiff .apply_changeset (f_conflict_file , local_diff )
383382 except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ):
384- # it would not be possible to commit local changes
385- # local changes will end up in new conflict file
386- # for original file server wins
383+ # FIXME hard copy can lead to data loss if changes from -wal file were not flushed !!!
384+ shutil .copy (dest , f_conflict_file )
385+
386+ # try to do rebase magic
387+ try :
388+ self .geodiff .create_changeset (basefile , src , server_diff )
389+ self .geodiff .rebase (basefile , src , dest )
390+ # make sure basefile is in the same state as remote server file (for calc of push changes)
391+ self .geodiff .apply_changeset (basefile , server_diff )
392+ except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ) as err :
393+ # it would not be possible to commit local changes, they need to end up in new conflict file
394+ shutil .copy (f_conflict_file , dest ) # revert file
387395 conflict = self .backup_file (path )
388396 conflicts .append (conflict )
389- shutil . copy ( f_server_backup , dest )
397+ # original file synced with server
390398 shutil .copy (f_server_backup , basefile )
399+ shutil .copy (f_server_backup , dest )
400+ # changes in -wal have been already applied in conflict file or LOST (see above)
401+ if os .path .exists (f'{ dest } -wal' ):
402+ os .remove (f'{ dest } -wal' )
403+ if os .path .exists (f'{ dest } -shm' ):
404+ os .remove (f'{ dest } -shm' )
391405 else :
392406 # just use server version of file to update both project file and its basefile
393407 shutil .copy (src , dest )
0 commit comments