Fossil

Check-in [dc850c9b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved robustness of the merge algorithm when merging long-running branches with many name changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: dc850c9b3b2d7e9e49413cb1a3759ad73faec86db552e4297809d8dd927abca6
User & Date: drh 2021-04-20 14:16:30
Context
2021-04-21
16:48
Remove extraneous and incomplete <span> tag from the /finfo output. ... (check-in: d115594b user: drh tags: trunk)
2021-04-20
14:16
Improved robustness of the merge algorithm when merging long-running branches with many name changes. ... (check-in: dc850c9b user: drh tags: trunk)
2021-04-17
12:23
Minor correction to finfo command comment help. ... (check-in: 8913402d user: andybradford tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/merge.c.

596
597
598
599
600
601
602




603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649

  /*
  ** Compute name changes from N to V, P, and M
  */
  add_renames("fn", vid, nid, 0, debugFlag ? "N->V" : 0);
  add_renames("fnp", pid, nid, 0, debugFlag ? "N->P" : 0);
  add_renames("fnm", mid, nid, backoutFlag, debugFlag ? "N->M" : 0);




  if( nid!=pid ){
    /* See forum thread https://fossil-scm.org/forum/forumpost/549700437b
    **
    ** If a filename changes between nid and one of the other check-ins
    ** pid, vid, or mid, then it might not have changed for all of them.
    ** try to fill in the appropriate filename in all slots where the
    ** name is missing.
    **
    ** This does not work if
    **   (1) The filename changes more than once in between nid and vid/mid
    **   (2) Two or more filenames swap places - for example if A is renamed
    **       to B and B is renamed to A.
    ** The Fossil merge algorithm breaks down in those cases.  It will need
    ** to be completely rewritten to handle such complex cases.  Such cases
    ** appear to be rare, and also confusing to humans.
    */
    db_multi_exec(
      "UPDATE fv SET fn=vfile.pathname FROM vfile"
      " WHERE fn IS NULL"
      " AND vfile.pathname IN (fv.fnm,fv.fnp,fv.fnn)"
      " AND vfile.vid=%d;",
      vid
    );
    db_multi_exec(
      "UPDATE fv SET fnp=vfile.pathname FROM vfile"
      " WHERE fnp IS NULL"
      " AND vfile.pathname IN (fv.fn,fv.fnm,fv.fnn)"
      " AND vfile.vid=%d;",
      pid
    );
    db_multi_exec(
      "UPDATE fv SET fnm=vfile.pathname FROM vfile"
      " WHERE fnm IS NULL"
      " AND vfile.pathname IN (fv.fn,fv.fnp,fv.fnn)"
      " AND vfile.vid=%d;",
      mid
    );
  }
  if( debugFlag ){
    fossil_print("******** FV after name change search *******\n");
    debug_fv_dump(1);
  }

  /*
  ** Add files found in V
  */
  db_multi_exec(







>
>
>
>

















|






|






|







|







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653

  /*
  ** Compute name changes from N to V, P, and M
  */
  add_renames("fn", vid, nid, 0, debugFlag ? "N->V" : 0);
  add_renames("fnp", pid, nid, 0, debugFlag ? "N->P" : 0);
  add_renames("fnm", mid, nid, backoutFlag, debugFlag ? "N->M" : 0);
  if( debugFlag ){
    fossil_print("******** FV after name change search *******\n");
    debug_fv_dump(1);
  }
  if( nid!=pid ){
    /* See forum thread https://fossil-scm.org/forum/forumpost/549700437b
    **
    ** If a filename changes between nid and one of the other check-ins
    ** pid, vid, or mid, then it might not have changed for all of them.
    ** try to fill in the appropriate filename in all slots where the
    ** name is missing.
    **
    ** This does not work if
    **   (1) The filename changes more than once in between nid and vid/mid
    **   (2) Two or more filenames swap places - for example if A is renamed
    **       to B and B is renamed to A.
    ** The Fossil merge algorithm breaks down in those cases.  It will need
    ** to be completely rewritten to handle such complex cases.  Such cases
    ** appear to be rare, and also confusing to humans.
    */
    db_multi_exec(
      "UPDATE OR IGNORE fv SET fn=vfile.pathname FROM vfile"
      " WHERE fn IS NULL"
      " AND vfile.pathname IN (fv.fnm,fv.fnp,fv.fnn)"
      " AND vfile.vid=%d;",
      vid
    );
    db_multi_exec(
      "UPDATE OR IGNORE fv SET fnp=vfile.pathname FROM vfile"
      " WHERE fnp IS NULL"
      " AND vfile.pathname IN (fv.fn,fv.fnm,fv.fnn)"
      " AND vfile.vid=%d;",
      pid
    );
    db_multi_exec(
      "UPDATE OR IGNORE fv SET fnm=vfile.pathname FROM vfile"
      " WHERE fnm IS NULL"
      " AND vfile.pathname IN (fv.fn,fv.fnp,fv.fnn)"
      " AND vfile.vid=%d;",
      mid
    );
  }
  if( debugFlag ){
    fossil_print("******** FV after name change fill-in *******\n");
    debug_fv_dump(1);
  }

  /*
  ** Add files found in V
  */
  db_multi_exec(