I have updated the merge conflict code as well as config setup to allow for 
configurable notation.  The following now appears when calling "fossil set."

auto-captcha        
auto-shun           
autosync             (local)  1
binary-glob         
clearsign           
conflict-start       (local)  <<<<<<< BEGIN MERGE CONFLICT
conflict-mid         (local)  ==============
conflict-end         (local)  >>>>>>> END MERGE CONFLICT

diff-command        
dont-push           
editor              
gdiff-command       
ignore-glob         
http-port           
localauth            (local)  0
manifest            
mtime-changes       
pgp-command         
proxy               
repo-cksum          
ssh-command         
web-browser         
     

As an example, this is the output on a merge conflict.

0
1
2
3
<<<<<<< BEGIN MERGE CONFLICT 5d1cd2ac61 add testfile1
999
============== 8eaf3091c7 change testfile1
444
>>>>>>> END MERGE CONFLICT
5
6
7
8
9

Below is the diff on the Fossil source code.  Any thoughts on this?

Index: src/db.c
===================================================================
--- src/db.c
+++ src/db.c
@@ -1025,10 +1025,14 @@
   Blob hash;
   Blob manifest;
 
   db_set("content-schema", CONTENT_SCHEMA, 0);
   db_set("aux-schema", AUX_SCHEMA, 0);
+  db_set("conflict-start", "<<<<<<< BEGIN MERGE CONFLICT", 0);
+  db_set("conflict-mid", "==============", 0);
+  db_set("conflict-end", ">>>>>>> END MERGE CONFLICT\n", 0);
+
   if( makeServerCodes ){
     db_multi_exec(
       "INSERT INTO config(name,value)"
       " VALUES('server-code', lower(hex(randomblob(20))));"
       "INSERT INTO config(name,value)"
@@ -1541,29 +1545,32 @@
   int width;            /* Width of display.  0 for boolean values */
   char const *def;      /* Default value */
 };
 #endif /* INTERFACE */
 struct stControlSettings const ctrlSettings[] = {
-  { "auto-captcha",  "autocaptcha",    0, "on"                  },
-  { "auto-shun",     0,                0, "on"                  },
-  { "autosync",      0,                0, "on"                  },
-  { "binary-glob",   0,               32, ""                    },
-  { "clearsign",     0,                0, "off"                 },
-  { "diff-command",  0,               16, ""                    },
-  { "dont-push",     0,                0, "off"                 },
-  { "editor",        0,               16, ""                    },
-  { "gdiff-command", 0,               16, "gdiff"               },
-  { "ignore-glob",   0,               40, ""                    },
-  { "http-port",     0,               16, "8080"                },
-  { "localauth",     0,                0, "off"                 },
-  { "manifest",      0,                0, "off"                 },
-  { "mtime-changes", 0,                0, "on"                  },
-  { "pgp-command",   0,               32, "gpg --clearsign -o " },
-  { "proxy",         0,               32, "off"                 },
-  { "repo-cksum",    0,                0, "on"                  },
-  { "ssh-command",   0,               32, ""                    },
-  { "web-browser",   0,               32, ""                    },
+  { "auto-captcha",   "autocaptcha",    0, "on"                              },
+  { "auto-shun",      0,                0, "on"                              },
+  { "autosync",       0,                0, "on"                              },
+  { "binary-glob",    0,               32, ""                                },
+  { "clearsign",      0,                0, "off"                             },
+  { "conflict-start", 0,               32, "<<<<<<< BEGIN MERGE CONFLICT"    },
+  { "conflict-mid",   0,               32, "============================"    },
+  { "conflict-end",   0,               32, ">>>>>>> END MERGE CONFLICT\\n"   },
+  { "diff-command",   0,               16, ""                                },
+  { "dont-push",      0,                0, "off"                             },
+  { "editor",         0,               16, ""                                },
+  { "gdiff-command",  0,               16, "gdiff"                           },
+  { "ignore-glob",    0,               40, ""                                },
+  { "http-port",      0,               16, "8080"                            },
+  { "localauth",      0,                0, "off"                             },
+  { "manifest",       0,                0, "off"                             },
+  { "mtime-changes",  0,                0, "on"                              },
+  { "pgp-command",    0,               32, "gpg --clearsign -o "             },
+  { "proxy",          0,               32, "off"                             },
+  { "repo-cksum",     0,                0, "on"                              },
+  { "ssh-command",    0,               32, ""                                },
+  { "web-browser",    0,               32, ""                                },
   { 0,0,0,0 }
 };
 
 /*
 ** COMMAND: settings
@@ -1596,10 +1603,16 @@
 **                     purposes.  Example:   *.xml
 **
 **    clearsign        When enabled, fossil will attempt to sign all commits
 **                     with gpg.  When disabled (the default), commits will
 **                     be unsigned.  Default: off
+**
+**    conflict-start   The characters used to denote the beginning of a merge 
conflict section.
+**
+**    conflict-mid     The characters used to denote the divider of a merge 
conflict section.
+**
+**    conflict-end     The characters used to denote the ending of a merge 
conflict section.
 **
 **    diff-command     External command to run when performing a diff.
 **                     If undefined, the internal text diff will be used.
 **
 **    dont-push        Prevent this repository from pushing from client to

Index: src/merge.c
===================================================================
--- src/merge.c
+++ src/merge.c
@@ -274,11 +274,11 @@
     blob_read_from_file(&v, zFullPath);
     if( isBinary ){
       rc = -1;
       blob_zero(&r);
     }else{
-      rc = blob_merge(&p, &m, &v, &r);
+      rc = blob_merge(&p, &m, &v, &r, vid, mid);
     }
     if( rc>=0 ){
       blob_write_to_file(&r, zFullPath);
       if( rc>0 ){
         printf("***** %d merge conflicts in %s\n", rc, zName);

Index: src/merge3.c
===================================================================
--- src/merge3.c
+++ src/merge3.c
@@ -144,20 +144,37 @@
 ** The return is 0 upon complete success. If any input file is binary,
 ** -1 is returned and pOut is unmodified.  If there are merge
 ** conflicts, the merge proceeds as best as it can and the number
 ** of conflicts is returns
 */
-int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut){
+int blob_merge(Blob *pPivot, Blob *pV1, Blob *pV2, Blob *pOut, int vid, int 
mid){
   int *aC1;              /* Changes from pPivot to pV1 */
   int *aC2;              /* Changes from pPivot to pV2 */
   int i1, i2;            /* Index into aC1[] and aC2[] */
   int nCpy, nDel, nIns;  /* Number of lines to copy, delete, or insert */
   int limit1, limit2;    /* Sizes of aC1[] and aC2[] */
   int nConflict = 0;     /* Number of merge conflicts seen so far */
-  static const char zBegin[] = "<<<<<<< BEGIN MERGE CONFLICT\n";
-  static const char zMid[]   = "============================\n";
-  static const char zEnd[]   = ">>>>>>> END MERGE CONFLICT\n";
+
+  char *zLeft       = (char*)malloc(512);
+  char *zRight      = (char*)malloc(512);
+  char *zLShortUuid = (char*)malloc(64);
+  char *zRShortUuid = (char*)malloc(64);
+
+  char *zBegin        = db_text(0, "SELECT value FROM config WHERE 
name='conflict-start'");
+  char *zMid          = db_text(0, "SELECT value FROM config WHERE 
name='conflict-mid'");
+  char *zEnd          = db_text(0, "SELECT value FROM config WHERE 
name='conflict-end'");
+
+  char *zLeftComment  = db_text(0, "SELECT comment FROM event where objid=%d", 
vid);
+  char *zRightComment = db_text(0, "SELECT comment FROM event where objid=%d", 
mid);
+  char *zLeftUuid     = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
+  char *zRightUuid    = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
+
+  shorten_uuid(zLShortUuid, zLeftUuid);
+  shorten_uuid(zRShortUuid, zRightUuid);
+
+  snprintf(zLeft,  512, "%s %s %s\n", zBegin, zLShortUuid, zLeftComment);
+  snprintf(zRight, 512, "%s %s %s\n", zMid, zRShortUuid, zRightComment);
 
   blob_zero(pOut);         /* Merge results stored in pOut */
 
   /* Compute the edits that occur from pPivot => pV1 (into aC1)
   ** and pPivot => pV2 (into aC2).  Each of the aC1 and aC2 arrays is
@@ -258,13 +275,13 @@
       nConflict++;
       while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
         sz++;
       }
       DEBUG( printf("CONFLICT %d\n", sz); )
-      blob_appendf(pOut, zBegin);
+      blob_appendf(pOut, zLeft);
       i1 = output_one_side(pOut, pV1, aC1, i1, sz);
-      blob_appendf(pOut, zMid);
+      blob_appendf(pOut, zRight);
       i2 = output_one_side(pOut, pV2, aC2, i2, sz);
       blob_appendf(pOut, zEnd);
       blob_copy_lines(0, pPivot, sz);
     }
 
@@ -290,10 +307,14 @@
     blob_copy_lines(pOut, pV2, aC2[i2+2]);
   }
 
   free(aC1);
   free(aC2);
+  free(zLeft);
+  free(zRight);
+  free(zLShortUuid);
+  free(zRShortUuid);
   return nConflict;
 }
 
 /*
 ** COMMAND:  test-3-way-merge
@@ -316,15 +337,15 @@
   }
   if( blob_read_from_file(&v2, g.argv[4])<0 ){
     fprintf(stderr,"cannot read %s\n", g.argv[4]);
     fossil_exit(1);
   }
-  blob_merge(&pivot, &v1, &v2, &merged);
+  blob_merge(&pivot, &v1, &v2, &merged, 0, 0);
   if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
     fprintf(stderr,"cannot write %s\n", g.argv[4]);
     fossil_exit(1);
   }
   blob_reset(&pivot);
   blob_reset(&v1);
   blob_reset(&v2);
   blob_reset(&merged);
 }

Index: src/timeline.c
===================================================================
--- src/timeline.c
+++ src/timeline.c
@@ -25,11 +25,11 @@
 
 /*
 ** Shorten a UUID so that is the minimum length needed to contain
 ** at least one digit in the range 'a'..'f'.  The minimum length is 10.
 */
-static void shorten_uuid(char *zDest, const char *zSrc){
+void shorten_uuid(char *zDest, const char *zSrc){
   int i;
   for(i=0; i<10 && zSrc[i]<='9'; i++){}
   memcpy(zDest, zSrc, 10);
   if( i==10 && zSrc[i] ){
     do{

Index: src/update.c
===================================================================
--- src/update.c
+++ src/update.c
@@ -263,11 +263,11 @@
       undo_save(zName);
       content_get(ridt, &t);
       content_get(ridv, &v);
       blob_zero(&e);
       blob_read_from_file(&e, zFullPath);
-      rc = blob_merge(&v, &e, &t, &r);
+      rc = blob_merge(&v, &e, &t, &r, vid, tid);
       if( rc>=0 ){
         if( !nochangeFlag ) blob_write_to_file(&r, zFullPath);
         if( rc>0 ){
           printf("***** %d merge conflicts in %s\n", rc, zName);
         }




_____________________________
From: [email protected] 
[[email protected]] On Behalf Of Remigiusz Modrzejewski 
[[email protected]]
Sent: Wednesday, December 15, 2010 10:37 AM
To: [email protected]
Subject: Re: [fossil-users] Merge conflict notation

On Dec 15, 2010, at 16:30 , Wilson, Ronald wrote:

> Sometimes I wish the conflict notation was something like:
>
> #error BEGIN MERGE CONFLICT
>
> Instead of
>
> <<<<<<< BEGIN MERGE CONFLICT
>
> But I know that would only work in C/C++/C#.  I just wish there was some way 
> that the compiler could tell me about the merge conflict more clearly instead 
> of hunting for a syntax error side effect.

Doesn't this call for configurable notation? ;)


Kind regards,
Remigiusz Modrzejewski



_______________________________________________
fossil-users mailing list
[email protected]
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users
_______________________________________________
fossil-users mailing list
[email protected]
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to