Fossil SCM
Add the --cherrypick option to the "merge" command.
Commit
3005080796a6d32f240e46926a0bbbfeb7641eea
Parent
ac8902beec5d8e0…
1 file changed
+34
-20
+34
-20
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -30,56 +30,68 @@ | ||
| 30 | 30 | |
| 31 | 31 | |
| 32 | 32 | /* |
| 33 | 33 | ** COMMAND: merge |
| 34 | 34 | ** |
| 35 | -** Usage: %fossil merge VERSION | |
| 35 | +** Usage: %fossil merge [--cherrypick] VERSION | |
| 36 | 36 | ** |
| 37 | 37 | ** The argument is a version that should be merged into the current |
| 38 | -** checkout. | |
| 38 | +** checkout. All changes from VERSION back to the nearest common | |
| 39 | +** ancestor are merged. Except, if the --cherrypick option is used | |
| 40 | +** only the changes associated with the single check-in VERSION are | |
| 41 | +** merged. | |
| 39 | 42 | ** |
| 40 | 43 | ** Only file content is merged. The result continues to use the |
| 41 | 44 | ** file and directory names from the current check-out even if those |
| 42 | 45 | ** names might have been changed in the branch being merged in. |
| 43 | 46 | */ |
| 44 | 47 | void merge_cmd(void){ |
| 45 | 48 | int vid; /* Current version */ |
| 46 | 49 | int mid; /* Version we are merging against */ |
| 47 | 50 | int pid; /* The pivot version - most recent common ancestor */ |
| 51 | + int detailFlag; /* True if the --detail option is present */ | |
| 52 | + int pickFlag; /* True if the --cherrypick option is present */ | |
| 48 | 53 | Stmt q; |
| 49 | - int detailFlag; | |
| 50 | 54 | |
| 51 | 55 | detailFlag = find_option("detail",0,0)!=0; |
| 56 | + pickFlag = find_option("cherrypick",0,0)!=0; | |
| 52 | 57 | if( g.argc!=3 ){ |
| 53 | 58 | usage("VERSION"); |
| 54 | 59 | } |
| 55 | 60 | db_must_be_within_tree(); |
| 56 | 61 | vid = db_lget_int("checkout", 0); |
| 57 | 62 | if( vid==0 ){ |
| 58 | - fossil_panic("nothing is checked out"); | |
| 63 | + fossil_fatal("nothing is checked out"); | |
| 59 | 64 | } |
| 60 | 65 | mid = name_to_rid(g.argv[2]); |
| 61 | 66 | if( mid==0 ){ |
| 62 | - fossil_panic("not a version: %s", g.argv[2]); | |
| 67 | + fossil_fatal("not a version: %s", g.argv[2]); | |
| 63 | 68 | } |
| 64 | 69 | if( mid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", mid) ){ |
| 65 | - fossil_panic("not a version: %s", g.argv[2]); | |
| 66 | - } | |
| 67 | - pivot_set_primary(mid); | |
| 68 | - pivot_set_secondary(vid); | |
| 69 | - db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0"); | |
| 70 | - while( db_step(&q)==SQLITE_ROW ){ | |
| 71 | - pivot_set_secondary(db_column_int(&q,0)); | |
| 72 | - } | |
| 73 | - db_finalize(&q); | |
| 74 | - pid = pivot_find(); | |
| 75 | - if( pid<=0 ){ | |
| 76 | - fossil_panic("cannot find a common ancestor between the current" | |
| 77 | - "checkout and %s", g.argv[2]); | |
| 70 | + fossil_fatal("not a version: %s", g.argv[2]); | |
| 71 | + } | |
| 72 | + if( pickFlag ){ | |
| 73 | + pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid); | |
| 74 | + if( pid<=0 ){ | |
| 75 | + fossil_fatal("cannot find an ancestor for %s", g.argv[2]); | |
| 76 | + } | |
| 77 | + }else{ | |
| 78 | + pivot_set_primary(mid); | |
| 79 | + pivot_set_secondary(vid); | |
| 80 | + db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0"); | |
| 81 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 82 | + pivot_set_secondary(db_column_int(&q,0)); | |
| 83 | + } | |
| 84 | + db_finalize(&q); | |
| 85 | + pid = pivot_find(); | |
| 86 | + if( pid<=0 ){ | |
| 87 | + fossil_fatal("cannot find a common ancestor between the current" | |
| 88 | + "checkout and %s", g.argv[2]); | |
| 89 | + } | |
| 78 | 90 | } |
| 79 | 91 | if( pid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", pid) ){ |
| 80 | - fossil_panic("not a version: record #%d", mid); | |
| 92 | + fossil_fatal("not a version: record #%d", mid); | |
| 81 | 93 | } |
| 82 | 94 | vfile_check_signature(vid, 1); |
| 83 | 95 | db_begin_transaction(); |
| 84 | 96 | undo_begin(); |
| 85 | 97 | load_vfile_from_rid(mid); |
| @@ -285,9 +297,11 @@ | ||
| 285 | 297 | |
| 286 | 298 | /* |
| 287 | 299 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 288 | 300 | */ |
| 289 | 301 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); |
| 290 | - db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid); | |
| 302 | + if( !pickFlag ){ | |
| 303 | + db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid); | |
| 304 | + } | |
| 291 | 305 | undo_finish(); |
| 292 | 306 | db_end_transaction(0); |
| 293 | 307 | } |
| 294 | 308 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -30,56 +30,68 @@ | |
| 30 | |
| 31 | |
| 32 | /* |
| 33 | ** COMMAND: merge |
| 34 | ** |
| 35 | ** Usage: %fossil merge VERSION |
| 36 | ** |
| 37 | ** The argument is a version that should be merged into the current |
| 38 | ** checkout. |
| 39 | ** |
| 40 | ** Only file content is merged. The result continues to use the |
| 41 | ** file and directory names from the current check-out even if those |
| 42 | ** names might have been changed in the branch being merged in. |
| 43 | */ |
| 44 | void merge_cmd(void){ |
| 45 | int vid; /* Current version */ |
| 46 | int mid; /* Version we are merging against */ |
| 47 | int pid; /* The pivot version - most recent common ancestor */ |
| 48 | Stmt q; |
| 49 | int detailFlag; |
| 50 | |
| 51 | detailFlag = find_option("detail",0,0)!=0; |
| 52 | if( g.argc!=3 ){ |
| 53 | usage("VERSION"); |
| 54 | } |
| 55 | db_must_be_within_tree(); |
| 56 | vid = db_lget_int("checkout", 0); |
| 57 | if( vid==0 ){ |
| 58 | fossil_panic("nothing is checked out"); |
| 59 | } |
| 60 | mid = name_to_rid(g.argv[2]); |
| 61 | if( mid==0 ){ |
| 62 | fossil_panic("not a version: %s", g.argv[2]); |
| 63 | } |
| 64 | if( mid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", mid) ){ |
| 65 | fossil_panic("not a version: %s", g.argv[2]); |
| 66 | } |
| 67 | pivot_set_primary(mid); |
| 68 | pivot_set_secondary(vid); |
| 69 | db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0"); |
| 70 | while( db_step(&q)==SQLITE_ROW ){ |
| 71 | pivot_set_secondary(db_column_int(&q,0)); |
| 72 | } |
| 73 | db_finalize(&q); |
| 74 | pid = pivot_find(); |
| 75 | if( pid<=0 ){ |
| 76 | fossil_panic("cannot find a common ancestor between the current" |
| 77 | "checkout and %s", g.argv[2]); |
| 78 | } |
| 79 | if( pid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", pid) ){ |
| 80 | fossil_panic("not a version: record #%d", mid); |
| 81 | } |
| 82 | vfile_check_signature(vid, 1); |
| 83 | db_begin_transaction(); |
| 84 | undo_begin(); |
| 85 | load_vfile_from_rid(mid); |
| @@ -285,9 +297,11 @@ | |
| 285 | |
| 286 | /* |
| 287 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 288 | */ |
| 289 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); |
| 290 | db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid); |
| 291 | undo_finish(); |
| 292 | db_end_transaction(0); |
| 293 | } |
| 294 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -30,56 +30,68 @@ | |
| 30 | |
| 31 | |
| 32 | /* |
| 33 | ** COMMAND: merge |
| 34 | ** |
| 35 | ** Usage: %fossil merge [--cherrypick] VERSION |
| 36 | ** |
| 37 | ** The argument is a version that should be merged into the current |
| 38 | ** checkout. All changes from VERSION back to the nearest common |
| 39 | ** ancestor are merged. Except, if the --cherrypick option is used |
| 40 | ** only the changes associated with the single check-in VERSION are |
| 41 | ** merged. |
| 42 | ** |
| 43 | ** Only file content is merged. The result continues to use the |
| 44 | ** file and directory names from the current check-out even if those |
| 45 | ** names might have been changed in the branch being merged in. |
| 46 | */ |
| 47 | void merge_cmd(void){ |
| 48 | int vid; /* Current version */ |
| 49 | int mid; /* Version we are merging against */ |
| 50 | int pid; /* The pivot version - most recent common ancestor */ |
| 51 | int detailFlag; /* True if the --detail option is present */ |
| 52 | int pickFlag; /* True if the --cherrypick option is present */ |
| 53 | Stmt q; |
| 54 | |
| 55 | detailFlag = find_option("detail",0,0)!=0; |
| 56 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 57 | if( g.argc!=3 ){ |
| 58 | usage("VERSION"); |
| 59 | } |
| 60 | db_must_be_within_tree(); |
| 61 | vid = db_lget_int("checkout", 0); |
| 62 | if( vid==0 ){ |
| 63 | fossil_fatal("nothing is checked out"); |
| 64 | } |
| 65 | mid = name_to_rid(g.argv[2]); |
| 66 | if( mid==0 ){ |
| 67 | fossil_fatal("not a version: %s", g.argv[2]); |
| 68 | } |
| 69 | if( mid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", mid) ){ |
| 70 | fossil_fatal("not a version: %s", g.argv[2]); |
| 71 | } |
| 72 | if( pickFlag ){ |
| 73 | pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid); |
| 74 | if( pid<=0 ){ |
| 75 | fossil_fatal("cannot find an ancestor for %s", g.argv[2]); |
| 76 | } |
| 77 | }else{ |
| 78 | pivot_set_primary(mid); |
| 79 | pivot_set_secondary(vid); |
| 80 | db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0"); |
| 81 | while( db_step(&q)==SQLITE_ROW ){ |
| 82 | pivot_set_secondary(db_column_int(&q,0)); |
| 83 | } |
| 84 | db_finalize(&q); |
| 85 | pid = pivot_find(); |
| 86 | if( pid<=0 ){ |
| 87 | fossil_fatal("cannot find a common ancestor between the current" |
| 88 | "checkout and %s", g.argv[2]); |
| 89 | } |
| 90 | } |
| 91 | if( pid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", pid) ){ |
| 92 | fossil_fatal("not a version: record #%d", mid); |
| 93 | } |
| 94 | vfile_check_signature(vid, 1); |
| 95 | db_begin_transaction(); |
| 96 | undo_begin(); |
| 97 | load_vfile_from_rid(mid); |
| @@ -285,9 +297,11 @@ | |
| 297 | |
| 298 | /* |
| 299 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 300 | */ |
| 301 | db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); |
| 302 | if( !pickFlag ){ |
| 303 | db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid); |
| 304 | } |
| 305 | undo_finish(); |
| 306 | db_end_transaction(0); |
| 307 | } |
| 308 |