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