Login
Check-in [ae59f86383]
Login

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

Overview
Comment:f-test-merge: fixed an incorrect if/else branch of porting which included a path we don't want (automatic selection of a fork to merge in). Fixed a NULL dereference when --help was invoked. Added some debug output.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | port-merge
Files: files | file ages | folders
SHA1: ae59f86383677294f07a6ef0da5d73d2d1e41f3c
User & Date: stephan 2021-10-16 18:48:25.812
Context
2021-10-17
10:38
Added variants of fsl_cx_exec() (fsl_db_exec() proxy) and changed error propagation semantics of fsl_cx_prepare() to be more useful. check-in: 9abdf965ac user: stephan tags: port-merge
2021-10-16
19:01
This checkin was actually caused by a "CLI misinteraction," but that gives us an excellent opportunity to move it to its own branch for use with merge testing. Closed-Leaf check-in: 3faa7222a6 user: stephan tags: mistake
18:48
f-test-merge: fixed an incorrect if/else branch of porting which included a path we don't want (automatic selection of a fork to merge in). Fixed a NULL dereference when --help was invoked. Added some debug output. check-in: ae59f86383 user: stephan tags: port-merge
16:24
Minor code reorgs and reminders to self for the continued merge porting later on. check-in: 81e6402728 user: stephan tags: port-merge
Changes
Unified Diff Ignore Whitespace Patch
Changes to f-apps/f-test-merge.c.
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  );
  if(rc) goto dberr;

  /* Mark the :rid record has having been checked.  It is not the
  ** common ancestor.
  */
  rc = fsl_db_prepare(db, &u1,
    "UPDATE " FSL__TABLE_PIVOT " SET pending=0 WHERE rid=:rid"
  );
  if(rc) goto dberr;

  /* Add to the queue all ancestors of :rid.
  */
  rc = fsl_db_prepare(db, &i1,
    "REPLACE INTO " FSL__TABLE_PIVOT " "







|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  );
  if(rc) goto dberr;

  /* Mark the :rid record has having been checked.  It is not the
  ** common ancestor.
  */
  rc = fsl_db_prepare(db, &u1,
    "UPDATE " FSL__TABLE_PIVOT " SET pending=0 WHERE rid=?1"
  );
  if(rc) goto dberr;

  /* Add to the queue all ancestors of :rid.
  */
  rc = fsl_db_prepare(db, &i1,
    "REPLACE INTO " FSL__TABLE_PIVOT " "
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  if(0==rc  && rid) *outRid = rid;
  return rc;
  dberr:
  assert(rc);
  rc = fsl_cx_uplift_db_error2(f, db, rc);
  goto end;
}
#undef FSL__TABLE_PIVOT

/**
   Searches f's current repository for the nearest fork related to
   version vid.

   More specifically: this looks for the most recent leaf that is (1)
   not equal to vid and (2) has not already been merged into vid and







<







208
209
210
211
212
213
214

215
216
217
218
219
220
221
  if(0==rc  && rid) *outRid = rid;
  return rc;
  dberr:
  assert(rc);
  rc = fsl_cx_uplift_db_error2(f, db, rc);
  goto end;
}


/**
   Searches f's current repository for the nearest fork related to
   version vid.

   More specifically: this looks for the most recent leaf that is (1)
   not equal to vid and (2) has not already been merged into vid and
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
   - FSL_RC_OOM: on allocation error

   - Any number of potential other errors from the db layer.

   f's error state will contain more information about errors reported
   here.
*/
static int fsl__find_nearest_fork(fsl_cx * const f,
                                  fsl_id_t vid, bool checkVmerge,
                                  fsl_id_t * outRid){
  fsl_db * const db = checkVmerge
    ? fsl_needs_ckout(f) : fsl_needs_repo(f);
  fsl_buffer * const sql = fsl_cx_scratchpad(f);
  fsl_stmt q;
  if(!db){







|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
   - FSL_RC_OOM: on allocation error

   - Any number of potential other errors from the db layer.

   f's error state will contain more information about errors reported
   here.
*/
/*static*/ int fsl__find_nearest_fork(fsl_cx * const f,
                                  fsl_id_t vid, bool checkVmerge,
                                  fsl_id_t * outRid){
  fsl_db * const db = checkVmerge
    ? fsl_needs_ckout(f) : fsl_needs_repo(f);
  fsl_buffer * const sql = fsl_cx_scratchpad(f);
  fsl_stmt q;
  if(!db){
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
654
655
656

657


658

659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  

  end:
  return rc ? fsl_cx_uplift_db_error2(f, db, rc) : 0;
}/*fsl__renames_tweak()*/


#undef FSL__TABLE_FV

int fsl_ckout_merge(fsl_cx * const f, fsl_merge_opt const * const opt){
  /**
     Notation:

     V (vid)  The current checkout
     M (mid)  The version being merged in
     P (pid)  The "pivot" - the most recent common ancestor of V and M.
     N (nid)  The "name pivot" - for detecting renames
  */
  int rc = 0;
  fsl_db * const db = fsl_needs_ckout(f);
  bool inTrans = false;
  fsl_id_t const vid = f->ckout.rid;
  fsl_id_t pid = 0 /* pivot RID: most recent common ancestor of V and M*/;
  fsl_id_t mid = opt->mergeRid /* merge-in version */;
  fsl_id_t nid = 0 /* "name pivot" version */;
  bool doIntegrate = FSL_MERGE_TYPE_INTEGRATE==opt->mergeType;
  if(!db) return FSL_RC_NOT_A_CKOUT;
  else if(0==vid){
    return fsl_cx_err_set(f, FSL_RC_MISUSE,
                          "Cannot merge into empty top-level checkin.");
  }else if(FSL_MERGE_TYPE_CHERRYPICK==opt->mergeType
           && opt->baselineRid>0){
    return fsl_cx_err_set(f, FSL_RC_MISUSE,
                          "Cannot use the baselineRid option "
                          "with a cherry-pick merge.");
  }
  rc = fsl_db_transaction_begin(db);
  if(rc) goto end;
  inTrans = true;

  if((pid = opt->baselineRid)<=0){

    rc = fsl__find_nearest_fork(f, mid, true, &pid);


    if(rc) goto end;

  }
  if(FSL_MERGE_TYPE_CHERRYPICK==opt->mergeType
     || FSL_MERGE_TYPE_BACKOUT==opt->mergeType){
    pid = fsl_db_g_id(db, 0, "SELECT pid FROM plink WHERE cid=%"
                           FSL_ID_T_PFMT " AND isprim",
                           mid);
    if(0==pid){
      rc = fsl_cx_err_set(f, FSL_RC_NOT_FOUND, "Cannot find an ancestor "
                          "for to-merge RID #%" FSL_ID_T_PFMT ".",
                          mid);
      goto end;
    }
  }else{
    if(opt->baselineRid<=0){
      fsl_stmt q = fsl_stmt_empty;
      rc = fsl__pivot_set_primary(f, mid);
      if(0==rc) rc = fsl__pivot_set_secondary(f, vid);
      if(rc) goto end;
      rc = fsl_db_prepare(db, &q, "SELECT merge FROM vmerge WHERE id=0");
      if(rc) goto end;
      while( FSL_RC_STEP_ROW==fsl_stmt_step(&q) ){
        rc = fsl__pivot_set_secondary(f, fsl_stmt_g_id(&q, 0));
        if(rc) break;
      }
      fsl_stmt_finalize(&q);
      if(0==rc) rc = fsl__pivot_find(f, false, &pid);
      if(rc) goto end;
      else if( pid<=0 ){
        rc = fsl_cx_err_set(f, FSL_RC_NOT_FOUND,
                            "Cannot find a common ancestor between "







<
<












|
|
|
|















|
>
|
>
>
|
>



















<
|

<







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
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

679
680

681
682
683
684
685
686
687
  

  end:
  return rc ? fsl_cx_uplift_db_error2(f, db, rc) : 0;
}/*fsl__renames_tweak()*/




int fsl_ckout_merge(fsl_cx * const f, fsl_merge_opt const * const opt){
  /**
     Notation:

     V (vid)  The current checkout
     M (mid)  The version being merged in
     P (pid)  The "pivot" - the most recent common ancestor of V and M.
     N (nid)  The "name pivot" - for detecting renames
  */
  int rc = 0;
  fsl_db * const db = fsl_needs_ckout(f);
  bool inTrans = false;
  fsl_id_t const vid = f->ckout.rid /* current checkout (V) */;
  fsl_id_t pid = 0 /* pivot RID (P): most recent common ancestor of V and M*/;
  fsl_id_t mid = opt->mergeRid /* merge-in version (M) */;
  fsl_id_t nid = 0 /* "name pivot" version (N) */;
  bool doIntegrate = FSL_MERGE_TYPE_INTEGRATE==opt->mergeType;
  if(!db) return FSL_RC_NOT_A_CKOUT;
  else if(0==vid){
    return fsl_cx_err_set(f, FSL_RC_MISUSE,
                          "Cannot merge into empty top-level checkin.");
  }else if(FSL_MERGE_TYPE_CHERRYPICK==opt->mergeType
           && opt->baselineRid>0){
    return fsl_cx_err_set(f, FSL_RC_MISUSE,
                          "Cannot use the baselineRid option "
                          "with a cherry-pick merge.");
  }
  rc = fsl_db_transaction_begin(db);
  if(rc) goto end;
  inTrans = true;

  if((pid = opt->baselineRid)>0){
    if(!fsl_rid_is_version(f, pid)){
      rc = fsl_cx_err_set(f, FSL_RC_TYPE,
                          "Baseline RID #%" FSL_ID_T_PFMT
                          " does not refer to a checkin version.");
      goto end;
    }
  }
  if(FSL_MERGE_TYPE_CHERRYPICK==opt->mergeType
     || FSL_MERGE_TYPE_BACKOUT==opt->mergeType){
    pid = fsl_db_g_id(db, 0, "SELECT pid FROM plink WHERE cid=%"
                           FSL_ID_T_PFMT " AND isprim",
                           mid);
    if(0==pid){
      rc = fsl_cx_err_set(f, FSL_RC_NOT_FOUND, "Cannot find an ancestor "
                          "for to-merge RID #%" FSL_ID_T_PFMT ".",
                          mid);
      goto end;
    }
  }else{
    if(opt->baselineRid<=0){
      fsl_stmt q = fsl_stmt_empty;
      rc = fsl__pivot_set_primary(f, mid);
      if(0==rc) rc = fsl__pivot_set_secondary(f, vid);
      if(rc) goto end;
      rc = fsl_db_prepare(db, &q, "SELECT merge FROM vmerge WHERE id=0");

      while( 0==rc && FSL_RC_STEP_ROW==fsl_stmt_step(&q) ){
        rc = fsl__pivot_set_secondary(f, fsl_stmt_g_id(&q, 0));

      }
      fsl_stmt_finalize(&q);
      if(0==rc) rc = fsl__pivot_find(f, false, &pid);
      if(rc) goto end;
      else if( pid<=0 ){
        rc = fsl_cx_err_set(f, FSL_RC_NOT_FOUND,
                            "Cannot find a common ancestor between "
702
703
704
705
706
707
708
709
710
711
712
713








714
715
716
717
718
719
720
      if(0==rc) rc = fsl__pivot_find(f, true, &nid);
      if(rc) goto end;
    }
    /* ^^^ the above block is a great example of much error checking
       intrudes on the library API compared to fossil(1). */
  }
  if( FSL_MERGE_TYPE_BACKOUT == opt->mergeType ){
    fsl_id_t t = pid;
    pid = mid;
    mid = t;
  }
  if(0==nid) nid = pid;








  if(mid == pid){
    rc = fsl_cx_err_set(f, FSL_RC_RANGE, "Cowardly refusing to perform "
                        "no-op merge from/to RID #%" FSL_ID_T_PFMT ".",
                        mid);
    goto end;
  }else if(mid == vid){
    rc = fsl_cx_err_set(f, FSL_RC_RANGE, "Cowardly refusing to merge "







|




>
>
>
>
>
>
>
>







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
      if(0==rc) rc = fsl__pivot_find(f, true, &nid);
      if(rc) goto end;
    }
    /* ^^^ the above block is a great example of much error checking
       intrudes on the library API compared to fossil(1). */
  }
  if( FSL_MERGE_TYPE_BACKOUT == opt->mergeType ){
    fsl_id_t const t = pid;
    pid = mid;
    mid = t;
  }
  if(0==nid) nid = pid;
  if(1){
    MARKER(("pid=%" FSL_ID_T_PFMT
            ", mid=%" FSL_ID_T_PFMT
            ", nid=%" FSL_ID_T_PFMT
            ", vid=%" FSL_ID_T_PFMT
            " integrate=%d\n",
            pid, mid, nid, vid, doIntegrate));
  }
  if(mid == pid){
    rc = fsl_cx_err_set(f, FSL_RC_RANGE, "Cowardly refusing to perform "
                        "no-op merge from/to RID #%" FSL_ID_T_PFMT ".",
                        mid);
    goto end;
  }else if(mid == vid){
    rc = fsl_cx_err_set(f, FSL_RC_RANGE, "Cowardly refusing to merge "
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764











765
766
767
768
769
770
771
772
773
774
775
776


777
778
779
780
781
782
783
  rc = fsl__renames_tweak(f, mid, pid, vid, nid, opt);
  if(rc) goto end;
  if(1){
    MARKER(("pid=%" FSL_ID_T_PFMT
            ", mid=%" FSL_ID_T_PFMT
            ", nid=%" FSL_ID_T_PFMT
            ", vid=%" FSL_ID_T_PFMT
            "integrate=%d\n",
            pid, mid, nid, vid, doIntegrate));
  }
  MARKER(("fsl_ckout_merge() does not yet do anything useful.\n"));
  MARKER(("Still TODO are the approx. 300 lines of fossil(1)'s merge "
          "starting at:\n"
          "https://fossil-scm.org/home/file/src/merge.c?ci=e340af58a249dc09&ln=769-776\n"
          "Much of that is similar to the update process, but how much "
          "can be consolidated is still unclear.\n"));











  
  end:
  if(0==rc){
    fsl__renames_finalize(f);
    rc = fsl_vfile_unload_except(f, vid);
  }
  if(inTrans){
    fsl_db_transaction_end(db, rc!=0);
  }
  return rc;
}





int main(int argc, const char * const * argv ){
  fsl_cx * f = 0;
  int rc = 0;
  char const *zMergeSym = 0;
    







|








>
>
>
>
>
>
>
>
>
>
>












>
>







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
  rc = fsl__renames_tweak(f, mid, pid, vid, nid, opt);
  if(rc) goto end;
  if(1){
    MARKER(("pid=%" FSL_ID_T_PFMT
            ", mid=%" FSL_ID_T_PFMT
            ", nid=%" FSL_ID_T_PFMT
            ", vid=%" FSL_ID_T_PFMT
            " integrate=%d\n",
            pid, mid, nid, vid, doIntegrate));
  }
  MARKER(("fsl_ckout_merge() does not yet do anything useful.\n"));
  MARKER(("Still TODO are the approx. 300 lines of fossil(1)'s merge "
          "starting at:\n"
          "https://fossil-scm.org/home/file/src/merge.c?ci=e340af58a249dc09&ln=769-776\n"
          "Much of that is similar to the update process, but how much "
          "can be consolidated is still unclear.\n"));

  if(1){
    MARKER(("Contents of " FSL__TABLE_FV ":\n"));
    fsl_db_each(db, fsl_stmt_each_f_dump, NULL,
                "SELECT * FROM " FSL__TABLE_FV
                " ORDER BY fn, fnp, fnm");
    MARKER(("Contents of " FSL__TABLE_PIVOT ":\n"));
    fsl_db_each(db, fsl_stmt_each_f_dump, NULL,
                "SELECT * FROM " FSL__TABLE_PIVOT
                " ORDER BY rid, pending, src");
  }
  
  end:
  if(0==rc){
    fsl__renames_finalize(f);
    rc = fsl_vfile_unload_except(f, vid);
  }
  if(inTrans){
    fsl_db_transaction_end(db, rc!=0);
  }
  return rc;
}

#undef FSL__TABLE_PIVOT
#undef FSL__TABLE_FV


int main(int argc, const char * const * argv ){
  fsl_cx * f = 0;
  int rc = 0;
  char const *zMergeSym = 0;
    
870
871
872
873
874
875
876
877
878
879
880
881
882
    }
  }

  f_out("Merging [%s] into [%S]...\n", zMergeSym, App.ckout.uuid);
  rc = fsl_ckout_merge(f, &App.mopt);
  f_out("fsl_ckout_merge() rc=%s\n", fsl_rc_cstr(rc));
  end:
  if(fsl_cx_transaction_level(f)){
    f_out("Rolling back transaction.\n");
    fsl_cx_transaction_end(f, true);
  }
  return fcli_end_of_main(rc);
}







|





890
891
892
893
894
895
896
897
898
899
900
901
902
    }
  }

  f_out("Merging [%s] into [%S]...\n", zMergeSym, App.ckout.uuid);
  rc = fsl_ckout_merge(f, &App.mopt);
  f_out("fsl_ckout_merge() rc=%s\n", fsl_rc_cstr(rc));
  end:
  if(f && fsl_cx_transaction_level(f)){
    f_out("Rolling back transaction.\n");
    fsl_cx_transaction_end(f, true);
  }
  return fcli_end_of_main(rc);
}