@@ -410,65 +410,13 @@ def apply_pull_changes(self, changes, temp_dir):
410
410
# 'src' here is server version of file and 'dest' is locally modified
411
411
if self .is_versioned_file (path ) and k == 'updated' :
412
412
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 :
448
415
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 )
452
416
else :
453
417
# The local file is not modified -> no rebase needed.
454
418
# 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 )
472
420
else :
473
421
# backup if needed
474
422
if path in modified and item ['checksum' ] != local_files_map [path ]['checksum' ]:
@@ -492,6 +440,108 @@ def apply_pull_changes(self, changes, temp_dir):
492
440
493
441
return conflicts
494
442
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
+
495
545
def apply_push_changes (self , changes ):
496
546
"""
497
547
For geodiff files update basefiles according to changes pushed to server.
0 commit comments