Fossil SCM
Add the --binary option to the "merge" command and a new "binary-glob" setting. These identify files that should be treated as binary files and which should not be subjected to a 3-way merge.
Commit
d327f12522c7afd718c7b752ed5eb7d3d10f7249
Parent
3555c0fc6fd0d16…
2 files changed
+5
+21
-3
M
src/db.c
+5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1438,10 +1438,14 @@ | ||
| 1438 | 1438 | ** |
| 1439 | 1439 | ** autosync If enabled, automatically pull prior to commit |
| 1440 | 1440 | ** or update and automatically push after commit or |
| 1441 | 1441 | ** tag or branch creation. If the the value is "pullonly" |
| 1442 | 1442 | ** then only pull operations occur automatically. |
| 1443 | +** | |
| 1444 | +** binary-glob The VALUE is a comma-separated list of GLOB patterns | |
| 1445 | +** that should be treated as binary files for merging | |
| 1446 | +** purposes. Example: *.xml | |
| 1443 | 1447 | ** |
| 1444 | 1448 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1445 | 1449 | ** with gpg. When disabled (the default), commits will |
| 1446 | 1450 | ** be unsigned. |
| 1447 | 1451 | ** |
| @@ -1486,10 +1490,11 @@ | ||
| 1486 | 1490 | */ |
| 1487 | 1491 | void setting_cmd(void){ |
| 1488 | 1492 | static const char *azName[] = { |
| 1489 | 1493 | "auto-captcha", |
| 1490 | 1494 | "autosync", |
| 1495 | + "binary-glob", | |
| 1491 | 1496 | "clearsign", |
| 1492 | 1497 | "diff-command", |
| 1493 | 1498 | "dont-push", |
| 1494 | 1499 | "editor", |
| 1495 | 1500 | "gdiff-command", |
| 1496 | 1501 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1438,10 +1438,14 @@ | |
| 1438 | ** |
| 1439 | ** autosync If enabled, automatically pull prior to commit |
| 1440 | ** or update and automatically push after commit or |
| 1441 | ** tag or branch creation. If the the value is "pullonly" |
| 1442 | ** then only pull operations occur automatically. |
| 1443 | ** |
| 1444 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1445 | ** with gpg. When disabled (the default), commits will |
| 1446 | ** be unsigned. |
| 1447 | ** |
| @@ -1486,10 +1490,11 @@ | |
| 1486 | */ |
| 1487 | void setting_cmd(void){ |
| 1488 | static const char *azName[] = { |
| 1489 | "auto-captcha", |
| 1490 | "autosync", |
| 1491 | "clearsign", |
| 1492 | "diff-command", |
| 1493 | "dont-push", |
| 1494 | "editor", |
| 1495 | "gdiff-command", |
| 1496 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1438,10 +1438,14 @@ | |
| 1438 | ** |
| 1439 | ** autosync If enabled, automatically pull prior to commit |
| 1440 | ** or update and automatically push after commit or |
| 1441 | ** tag or branch creation. If the the value is "pullonly" |
| 1442 | ** then only pull operations occur automatically. |
| 1443 | ** |
| 1444 | ** binary-glob The VALUE is a comma-separated list of GLOB patterns |
| 1445 | ** that should be treated as binary files for merging |
| 1446 | ** purposes. Example: *.xml |
| 1447 | ** |
| 1448 | ** clearsign When enabled, fossil will attempt to sign all commits |
| 1449 | ** with gpg. When disabled (the default), commits will |
| 1450 | ** be unsigned. |
| 1451 | ** |
| @@ -1486,10 +1490,11 @@ | |
| 1490 | */ |
| 1491 | void setting_cmd(void){ |
| 1492 | static const char *azName[] = { |
| 1493 | "auto-captcha", |
| 1494 | "autosync", |
| 1495 | "binary-glob", |
| 1496 | "clearsign", |
| 1497 | "diff-command", |
| 1498 | "dont-push", |
| 1499 | "editor", |
| 1500 | "gdiff-command", |
| 1501 |
+21
-3
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -43,27 +43,38 @@ | ||
| 43 | 43 | ** checkout rather than added. |
| 44 | 44 | ** |
| 45 | 45 | ** Only file content is merged. The result continues to use the |
| 46 | 46 | ** file and directory names from the current checkout even if those |
| 47 | 47 | ** names might have been changed in the branch being merged in. |
| 48 | +** | |
| 49 | +** Other options: | |
| 50 | +** | |
| 51 | +** --detail Show additional details of the merge | |
| 52 | +** | |
| 53 | +** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary | |
| 54 | +** and do not try to merge parallel changes. This | |
| 55 | +** option overrides the "binary-glob" setting. | |
| 48 | 56 | */ |
| 49 | 57 | void merge_cmd(void){ |
| 50 | 58 | int vid; /* Current version */ |
| 51 | 59 | int mid; /* Version we are merging against */ |
| 52 | 60 | int pid; /* The pivot version - most recent common ancestor */ |
| 53 | 61 | int detailFlag; /* True if the --detail option is present */ |
| 54 | 62 | int pickFlag; /* True if the --cherrypick option is present */ |
| 55 | 63 | int backoutFlag; /* True if the --backout optioni is present */ |
| 64 | + const char *zBinGlob; /* The value of --binary */ | |
| 56 | 65 | Stmt q; |
| 57 | 66 | |
| 58 | 67 | detailFlag = find_option("detail",0,0)!=0; |
| 59 | 68 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 60 | 69 | backoutFlag = find_option("backout",0,0)!=0; |
| 70 | + zBinGlob = find_option("binary",0,1); | |
| 61 | 71 | if( g.argc!=3 ){ |
| 62 | 72 | usage("VERSION"); |
| 63 | 73 | } |
| 64 | 74 | db_must_be_within_tree(); |
| 75 | + if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); | |
| 65 | 76 | vid = db_lget_int("checkout", 0); |
| 66 | 77 | if( vid==0 ){ |
| 67 | 78 | fossil_fatal("nothing is checked out"); |
| 68 | 79 | } |
| 69 | 80 | mid = name_to_rid(g.argv[2]); |
| @@ -238,19 +249,21 @@ | ||
| 238 | 249 | |
| 239 | 250 | /* |
| 240 | 251 | ** Do a three-way merge on files that have changes pid->mid and pid->vid |
| 241 | 252 | */ |
| 242 | 253 | db_prepare(&q, |
| 243 | - "SELECT ridm, idv, ridp, ridv FROM fv" | |
| 254 | + "SELECT ridm, idv, ridp, ridv, %s FROM fv" | |
| 244 | 255 | " WHERE idp>0 AND idv>0 AND idm>0" |
| 245 | - " AND ridm!=ridp AND (ridv!=ridp OR chnged)" | |
| 256 | + " AND ridm!=ridp AND (ridv!=ridp OR chnged)", | |
| 257 | + glob_expr("fv.fn", zBinGlob) | |
| 246 | 258 | ); |
| 247 | 259 | while( db_step(&q)==SQLITE_ROW ){ |
| 248 | 260 | int ridm = db_column_int(&q, 0); |
| 249 | 261 | int idv = db_column_int(&q, 1); |
| 250 | 262 | int ridp = db_column_int(&q, 2); |
| 251 | 263 | int ridv = db_column_int(&q, 3); |
| 264 | + int isBinary = db_column_int(&q, 4); | |
| 252 | 265 | int rc; |
| 253 | 266 | char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idv); |
| 254 | 267 | char *zFullPath; |
| 255 | 268 | Blob m, p, v, r; |
| 256 | 269 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| @@ -263,11 +276,16 @@ | ||
| 263 | 276 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 264 | 277 | content_get(ridp, &p); |
| 265 | 278 | content_get(ridm, &m); |
| 266 | 279 | blob_zero(&v); |
| 267 | 280 | blob_read_from_file(&v, zFullPath); |
| 268 | - rc = blob_merge(&p, &m, &v, &r); | |
| 281 | + if( isBinary ){ | |
| 282 | + rc = -1; | |
| 283 | + blob_zero(&r); | |
| 284 | + }else{ | |
| 285 | + rc = blob_merge(&p, &m, &v, &r); | |
| 286 | + } | |
| 269 | 287 | if( rc>=0 ){ |
| 270 | 288 | blob_write_to_file(&r, zFullPath); |
| 271 | 289 | if( rc>0 ){ |
| 272 | 290 | printf("***** %d merge conflicts in %s\n", rc, zName); |
| 273 | 291 | } |
| 274 | 292 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -43,27 +43,38 @@ | |
| 43 | ** checkout rather than added. |
| 44 | ** |
| 45 | ** Only file content is merged. The result continues to use the |
| 46 | ** file and directory names from the current checkout even if those |
| 47 | ** names might have been changed in the branch being merged in. |
| 48 | */ |
| 49 | void merge_cmd(void){ |
| 50 | int vid; /* Current version */ |
| 51 | int mid; /* Version we are merging against */ |
| 52 | int pid; /* The pivot version - most recent common ancestor */ |
| 53 | int detailFlag; /* True if the --detail option is present */ |
| 54 | int pickFlag; /* True if the --cherrypick option is present */ |
| 55 | int backoutFlag; /* True if the --backout optioni is present */ |
| 56 | Stmt q; |
| 57 | |
| 58 | detailFlag = find_option("detail",0,0)!=0; |
| 59 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 60 | backoutFlag = find_option("backout",0,0)!=0; |
| 61 | if( g.argc!=3 ){ |
| 62 | usage("VERSION"); |
| 63 | } |
| 64 | db_must_be_within_tree(); |
| 65 | vid = db_lget_int("checkout", 0); |
| 66 | if( vid==0 ){ |
| 67 | fossil_fatal("nothing is checked out"); |
| 68 | } |
| 69 | mid = name_to_rid(g.argv[2]); |
| @@ -238,19 +249,21 @@ | |
| 238 | |
| 239 | /* |
| 240 | ** Do a three-way merge on files that have changes pid->mid and pid->vid |
| 241 | */ |
| 242 | db_prepare(&q, |
| 243 | "SELECT ridm, idv, ridp, ridv FROM fv" |
| 244 | " WHERE idp>0 AND idv>0 AND idm>0" |
| 245 | " AND ridm!=ridp AND (ridv!=ridp OR chnged)" |
| 246 | ); |
| 247 | while( db_step(&q)==SQLITE_ROW ){ |
| 248 | int ridm = db_column_int(&q, 0); |
| 249 | int idv = db_column_int(&q, 1); |
| 250 | int ridp = db_column_int(&q, 2); |
| 251 | int ridv = db_column_int(&q, 3); |
| 252 | int rc; |
| 253 | char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idv); |
| 254 | char *zFullPath; |
| 255 | Blob m, p, v, r; |
| 256 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| @@ -263,11 +276,16 @@ | |
| 263 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 264 | content_get(ridp, &p); |
| 265 | content_get(ridm, &m); |
| 266 | blob_zero(&v); |
| 267 | blob_read_from_file(&v, zFullPath); |
| 268 | rc = blob_merge(&p, &m, &v, &r); |
| 269 | if( rc>=0 ){ |
| 270 | blob_write_to_file(&r, zFullPath); |
| 271 | if( rc>0 ){ |
| 272 | printf("***** %d merge conflicts in %s\n", rc, zName); |
| 273 | } |
| 274 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -43,27 +43,38 @@ | |
| 43 | ** checkout rather than added. |
| 44 | ** |
| 45 | ** Only file content is merged. The result continues to use the |
| 46 | ** file and directory names from the current checkout even if those |
| 47 | ** names might have been changed in the branch being merged in. |
| 48 | ** |
| 49 | ** Other options: |
| 50 | ** |
| 51 | ** --detail Show additional details of the merge |
| 52 | ** |
| 53 | ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary |
| 54 | ** and do not try to merge parallel changes. This |
| 55 | ** option overrides the "binary-glob" setting. |
| 56 | */ |
| 57 | void merge_cmd(void){ |
| 58 | int vid; /* Current version */ |
| 59 | int mid; /* Version we are merging against */ |
| 60 | int pid; /* The pivot version - most recent common ancestor */ |
| 61 | int detailFlag; /* True if the --detail option is present */ |
| 62 | int pickFlag; /* True if the --cherrypick option is present */ |
| 63 | int backoutFlag; /* True if the --backout optioni is present */ |
| 64 | const char *zBinGlob; /* The value of --binary */ |
| 65 | Stmt q; |
| 66 | |
| 67 | detailFlag = find_option("detail",0,0)!=0; |
| 68 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 69 | backoutFlag = find_option("backout",0,0)!=0; |
| 70 | zBinGlob = find_option("binary",0,1); |
| 71 | if( g.argc!=3 ){ |
| 72 | usage("VERSION"); |
| 73 | } |
| 74 | db_must_be_within_tree(); |
| 75 | if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); |
| 76 | vid = db_lget_int("checkout", 0); |
| 77 | if( vid==0 ){ |
| 78 | fossil_fatal("nothing is checked out"); |
| 79 | } |
| 80 | mid = name_to_rid(g.argv[2]); |
| @@ -238,19 +249,21 @@ | |
| 249 | |
| 250 | /* |
| 251 | ** Do a three-way merge on files that have changes pid->mid and pid->vid |
| 252 | */ |
| 253 | db_prepare(&q, |
| 254 | "SELECT ridm, idv, ridp, ridv, %s FROM fv" |
| 255 | " WHERE idp>0 AND idv>0 AND idm>0" |
| 256 | " AND ridm!=ridp AND (ridv!=ridp OR chnged)", |
| 257 | glob_expr("fv.fn", zBinGlob) |
| 258 | ); |
| 259 | while( db_step(&q)==SQLITE_ROW ){ |
| 260 | int ridm = db_column_int(&q, 0); |
| 261 | int idv = db_column_int(&q, 1); |
| 262 | int ridp = db_column_int(&q, 2); |
| 263 | int ridv = db_column_int(&q, 3); |
| 264 | int isBinary = db_column_int(&q, 4); |
| 265 | int rc; |
| 266 | char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idv); |
| 267 | char *zFullPath; |
| 268 | Blob m, p, v, r; |
| 269 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| @@ -263,11 +276,16 @@ | |
| 276 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 277 | content_get(ridp, &p); |
| 278 | content_get(ridm, &m); |
| 279 | blob_zero(&v); |
| 280 | blob_read_from_file(&v, zFullPath); |
| 281 | if( isBinary ){ |
| 282 | rc = -1; |
| 283 | blob_zero(&r); |
| 284 | }else{ |
| 285 | rc = blob_merge(&p, &m, &v, &r); |
| 286 | } |
| 287 | if( rc>=0 ){ |
| 288 | blob_write_to_file(&r, zFullPath); |
| 289 | if( rc>0 ){ |
| 290 | printf("***** %d merge conflicts in %s\n", rc, zName); |
| 291 | } |
| 292 |