@@ -410,65 +410,13 @@ def apply_pull_changes(self, changes, temp_dir):
410410 # 'src' here is server version of file and 'dest' is locally modified
411411 if self .is_versioned_file (path ) and k == 'updated' :
412412 if path in modified :
413- self .log .info ("updating file with rebase: " + path )
414- server_diff = self .fpath (f'{ path } -server_diff' , temp_dir ) # diff between server file and local basefile
415- local_diff = self .fpath (f'{ path } -local_diff' , temp_dir )
416-
417- # temporary backup of file pulled from server for recovery
418- f_server_backup = self .fpath (f'{ path } -server_backup' , temp_dir )
419- self .geodiff .make_copy_sqlite (src , f_server_backup )
420-
421- # create temp backup (ideally with geodiff) of locally modified file if needed later
422- f_conflict_file = self .fpath (f'{ path } -local_backup' , temp_dir )
423- try :
424- self .geodiff .create_changeset (basefile , dest , local_diff )
425- self .geodiff .make_copy_sqlite (basefile , f_conflict_file )
426- self .geodiff .apply_changeset (f_conflict_file , local_diff )
427- except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ):
428- self .log .info ("backup of local file with geodiff failed - need to do hard copy" )
429- self .geodiff .make_copy_sqlite (dest , f_conflict_file )
430-
431- # in case there will be any conflicting operations found during rebase,
432- # they will be stored in a JSON file - if there are no conflicts, the file
433- # won't even be created
434- rebase_conflicts = self .fpath (f'{ path } _rebase_conflicts' )
435-
436- # try to do rebase magic
437- try :
438- self .geodiff .create_changeset (basefile , src , server_diff )
439- self .geodiff .rebase (basefile , src , dest , rebase_conflicts )
440- # make sure basefile is in the same state as remote server file (for calc of push changes)
441- self .geodiff .apply_changeset (basefile , server_diff )
442- self .log .info ("rebase successful!" )
443- except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ) as err :
444- self .log .warning ("rebase failed! going to create conflict file" )
445- # it would not be possible to commit local changes, they need to end up in new conflict file
446- self .geodiff .make_copy_sqlite (f_conflict_file , dest )
447- conflict = self .backup_file (path )
413+ conflict = self .update_with_rebase (path , src , dest , basefile , temp_dir )
414+ if conflict :
448415 conflicts .append (conflict )
449- # original file synced with server
450- self .geodiff .make_copy_sqlite (f_server_backup , basefile )
451- self .geodiff .make_copy_sqlite (f_server_backup , dest )
452416 else :
453417 # The local file is not modified -> no rebase needed.
454418 # We just apply the diff between our copy and server to both the local copy and its basefile
455- self .log .info ("updating file without rebase: " + path )
456- try :
457- server_diff = self .fpath (f'{ path } -server_diff' , temp_dir ) # diff between server file and local basefile
458- # TODO: it could happen that basefile does not exist.
459- # It was either never created (e.g. when pushing without geodiff)
460- # or it was deleted by mistake(?) by the user. We should detect that
461- # when starting pull and download it as well
462- self .geodiff .create_changeset (basefile , src , server_diff )
463- self .geodiff .apply_changeset (dest , server_diff )
464- self .geodiff .apply_changeset (basefile , server_diff )
465- self .log .info ("update successful" )
466- except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ):
467- self .log .warning ("update failed! going to copy file" )
468- # something bad happened and we have failed to patch our local files - this should not happen if there
469- # wasn't a schema change or something similar that geodiff can't handle.
470- self .geodiff .make_copy_sqlite (src , dest )
471- self .geodiff .make_copy_sqlite (src , basefile )
419+ self .update_without_rebase (path , src , dest , basefile , temp_dir )
472420 else :
473421 # backup if needed
474422 if path in modified and item ['checksum' ] != local_files_map [path ]['checksum' ]:
@@ -492,6 +440,108 @@ def apply_pull_changes(self, changes, temp_dir):
492440
493441 return conflicts
494442
443+ def update_with_rebase (self , path , src , dest , basefile , temp_dir ):
444+ """
445+ Update a versioned file with rebase.
446+
447+ Try to peform automatic rebase, create conflict file if failed.pyt
448+
449+ .. seealso:: self.update_without_rebase
450+
451+ :param path: path to geodiff file
452+ :type path: str
453+ :param src: path to the server version of the file
454+ :type src: str
455+ :param dest: path to the local version of the file
456+ :type dest: str
457+ :param basefile: path to a file in meta dir
458+ :type basefile: str
459+ :param temp_dir: directory with downloaded files from server
460+ :type temp_dir: str
461+ :returns: path to conflict file if rebase fails, empty string on success
462+ :rtype: str
463+ """
464+ self .log .info ("updating file with rebase: " + path )
465+
466+ server_diff = self .fpath (f'{ path } -server_diff' , temp_dir ) # diff between server file and local basefile
467+ local_diff = self .fpath (f'{ path } -local_diff' , temp_dir )
468+
469+ # temporary backup of file pulled from server for recovery
470+ f_server_backup = self .fpath (f'{ path } -server_backup' , temp_dir )
471+ self .geodiff .make_copy_sqlite (src , f_server_backup )
472+
473+ # create temp backup (ideally with geodiff) of locally modified file if needed later
474+ f_conflict_file = self .fpath (f'{ path } -local_backup' , temp_dir )
475+ try :
476+ self .geodiff .create_changeset (basefile , dest , local_diff )
477+ self .geodiff .make_copy_sqlite (basefile , f_conflict_file )
478+ self .geodiff .apply_changeset (f_conflict_file , local_diff )
479+ except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ):
480+ self .log .info ("backup of local file with geodiff failed - need to do hard copy" )
481+ self .geodiff .make_copy_sqlite (dest , f_conflict_file )
482+
483+ # in case there will be any conflicting operations found during rebase,
484+ # they will be stored in a JSON file - if there are no conflicts, the file
485+ # won't even be created
486+ rebase_conflicts = self .fpath (f'{ path } _rebase_conflicts' )
487+
488+ # try to do rebase magic
489+ try :
490+ self .geodiff .create_changeset (basefile , src , server_diff )
491+ self .geodiff .rebase (basefile , src , dest , rebase_conflicts )
492+ # make sure basefile is in the same state as remote server file (for calc of push changes)
493+ self .geodiff .apply_changeset (basefile , server_diff )
494+ self .log .info ("rebase successful!" )
495+ except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ) as err :
496+ self .log .warning ("rebase failed! going to create conflict file" )
497+ # it would not be possible to commit local changes, they need to end up in new conflict file
498+ self .geodiff .make_copy_sqlite (f_conflict_file , dest )
499+ conflict = self .backup_file (path )
500+ # original file synced with server
501+ self .geodiff .make_copy_sqlite (f_server_backup , basefile )
502+ self .geodiff .make_copy_sqlite (f_server_backup , dest )
503+ return conflict
504+
505+ return ''
506+
507+ def update_without_rebase (self , path , src , dest , basefile , temp_dir ):
508+ """
509+ Update a versioned file without rebase.
510+
511+ Apply the diff between local copy and server to both the local
512+ copy and its basefile.
513+
514+ .. seealso:: self.update_with_rebase
515+
516+ :param path: path to geodiff file
517+ :type path: str
518+ :param src: path to the server version of the file
519+ :type src: str
520+ :param dest: path to the local version of the file
521+ :type dest: str
522+ :param basefile: path to a file in meta dir
523+ :type basefile: str
524+ :param temp_dir: directory with downloaded files from server
525+ :type temp_dir: str
526+ """
527+ self .log .info ("updating file without rebase: " + path )
528+ try :
529+ server_diff = self .fpath (f'{ path } -server_diff' , temp_dir ) # diff between server file and local basefile
530+ # TODO: it could happen that basefile does not exist.
531+ # It was either never created (e.g. when pushing without geodiff)
532+ # or it was deleted by mistake(?) by the user. We should detect that
533+ # when starting pull and download it as well
534+ self .geodiff .create_changeset (basefile , src , server_diff )
535+ self .geodiff .apply_changeset (dest , server_diff )
536+ self .geodiff .apply_changeset (basefile , server_diff )
537+ self .log .info ("update successful" )
538+ except (pygeodiff .GeoDiffLibError , pygeodiff .GeoDiffLibConflictError ):
539+ self .log .warning ("update failed! going to copy file" )
540+ # something bad happened and we have failed to patch our local files - this should not happen if there
541+ # wasn't a schema change or something similar that geodiff can't handle.
542+ self .geodiff .make_copy_sqlite (src , dest )
543+ self .geodiff .make_copy_sqlite (src , basefile )
544+
495545 def apply_push_changes (self , changes ):
496546 """
497547 For geodiff files update basefiles according to changes pushed to server.
0 commit comments