Fossil SCM
Fail a "fossil commit" that contains a --branch option for an open branch unless there is also a --force option.
Commit
b1026f20ccc7f966dbb513f0582f97d354063466
Parent
04c6e7ee827c46a…
2 files changed
+42
-3
+7
+42
-3
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -239,20 +239,40 @@ | ||
| 239 | 239 | break; |
| 240 | 240 | } |
| 241 | 241 | } |
| 242 | 242 | } |
| 243 | 243 | |
| 244 | +/* | |
| 245 | +** If the branch named in the argument is open, return a RID for one of | |
| 246 | +** the open leaves of that branch. If the branch does not exists or is | |
| 247 | +** closed, return 0. | |
| 248 | +*/ | |
| 249 | +int branch_is_open(const char *zBrName){ | |
| 250 | + return db_int(0, | |
| 251 | + "SELECT rid FROM tagxref AS ox" | |
| 252 | + " WHERE tagid=%d" | |
| 253 | + " AND tagtype=2" | |
| 254 | + " AND value=%Q" | |
| 255 | + " AND rid IN leaf" | |
| 256 | + " AND NOT EXISTS(SELECT 1 FROM tagxref AS ix" | |
| 257 | + " WHERE tagid=%d" | |
| 258 | + " AND tagtype=1" | |
| 259 | + " AND ox.rid=ix.rid)", | |
| 260 | + TAG_BRANCH, zBrName, TAG_CLOSED | |
| 261 | + ); | |
| 262 | +} | |
| 263 | + | |
| 244 | 264 | |
| 245 | 265 | /* |
| 246 | 266 | ** COMMAND: branch |
| 247 | 267 | ** |
| 248 | 268 | ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS? |
| 249 | 269 | ** |
| 250 | 270 | ** Run various subcommands to manage branches of the open repository or |
| 251 | 271 | ** of the repository identified by the -R or --repository option. |
| 252 | 272 | ** |
| 253 | -** %fossil branch new BRANCH-NAME BASIS ?OPTIONS? | |
| 273 | +** fossil branch new BRANCH-NAME BASIS ?OPTIONS? | |
| 254 | 274 | ** |
| 255 | 275 | ** Create a new branch BRANCH-NAME off of check-in BASIS. |
| 256 | 276 | ** Supported options for this subcommand include: |
| 257 | 277 | ** --private branch is private (i.e., remains local) |
| 258 | 278 | ** --bgcolor COLOR use COLOR instead of automatic background |
| @@ -264,16 +284,20 @@ | ||
| 264 | 284 | ** year-month-day form, it may be truncated, the "T" may be |
| 265 | 285 | ** replaced by a space, and it may also name a timezone offset |
| 266 | 286 | ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward). |
| 267 | 287 | ** Either no timezone suffix or "Z" means UTC. |
| 268 | 288 | ** |
| 269 | -** %fossil branch list|ls ?-a|--all|-c|--closed? | |
| 289 | +** fossil branch list|ls ?-a|--all|-c|--closed? | |
| 270 | 290 | ** |
| 271 | 291 | ** List all branches. Use -a or --all to list all branches and |
| 272 | 292 | ** -c or --closed to list all closed branches. The default is to |
| 273 | 293 | ** show only open branches. |
| 274 | 294 | ** |
| 295 | +** fossil branch info BRANCH-NAME | |
| 296 | +** | |
| 297 | +** Print information about a branch | |
| 298 | +** | |
| 275 | 299 | ** Options: |
| 276 | 300 | ** -R|--repository FILE Run commands on repository FILE |
| 277 | 301 | */ |
| 278 | 302 | void branch_cmd(void){ |
| 279 | 303 | int n; |
| @@ -301,13 +325,28 @@ | ||
| 301 | 325 | const char *zBr = db_column_text(&q, 0); |
| 302 | 326 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 303 | 327 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 304 | 328 | } |
| 305 | 329 | db_finalize(&q); |
| 330 | + }else if( strncmp(zCmd,"info",n)==0 ){ | |
| 331 | + int i; | |
| 332 | + for(i=3; i<g.argc; i++){ | |
| 333 | + const char *zBrName = g.argv[i]; | |
| 334 | + int rid = branch_is_open(zBrName); | |
| 335 | + if( rid==0 ){ | |
| 336 | + fossil_print("%s: not an open branch\n", zBrName); | |
| 337 | + }else{ | |
| 338 | + const char *zUuid = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",rid); | |
| 339 | + const char *zDate = db_text(0, | |
| 340 | + "SELECT datetime(mtime,toLocal()) FROM event" | |
| 341 | + " WHERE objid=%d", rid); | |
| 342 | + fossil_print("%s: open as of %s on %.16s\n", zBrName, zDate, zUuid); | |
| 343 | + } | |
| 344 | + } | |
| 306 | 345 | }else{ |
| 307 | 346 | fossil_fatal("branch subcommand should be one of: " |
| 308 | - "new list ls"); | |
| 347 | + "info list ls new"); | |
| 309 | 348 | } |
| 310 | 349 | } |
| 311 | 350 | |
| 312 | 351 | static const char brlistQuery[] = |
| 313 | 352 | @ SELECT |
| 314 | 353 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -239,20 +239,40 @@ | |
| 239 | break; |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | |
| 245 | /* |
| 246 | ** COMMAND: branch |
| 247 | ** |
| 248 | ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS? |
| 249 | ** |
| 250 | ** Run various subcommands to manage branches of the open repository or |
| 251 | ** of the repository identified by the -R or --repository option. |
| 252 | ** |
| 253 | ** %fossil branch new BRANCH-NAME BASIS ?OPTIONS? |
| 254 | ** |
| 255 | ** Create a new branch BRANCH-NAME off of check-in BASIS. |
| 256 | ** Supported options for this subcommand include: |
| 257 | ** --private branch is private (i.e., remains local) |
| 258 | ** --bgcolor COLOR use COLOR instead of automatic background |
| @@ -264,16 +284,20 @@ | |
| 264 | ** year-month-day form, it may be truncated, the "T" may be |
| 265 | ** replaced by a space, and it may also name a timezone offset |
| 266 | ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward). |
| 267 | ** Either no timezone suffix or "Z" means UTC. |
| 268 | ** |
| 269 | ** %fossil branch list|ls ?-a|--all|-c|--closed? |
| 270 | ** |
| 271 | ** List all branches. Use -a or --all to list all branches and |
| 272 | ** -c or --closed to list all closed branches. The default is to |
| 273 | ** show only open branches. |
| 274 | ** |
| 275 | ** Options: |
| 276 | ** -R|--repository FILE Run commands on repository FILE |
| 277 | */ |
| 278 | void branch_cmd(void){ |
| 279 | int n; |
| @@ -301,13 +325,28 @@ | |
| 301 | const char *zBr = db_column_text(&q, 0); |
| 302 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 303 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 304 | } |
| 305 | db_finalize(&q); |
| 306 | }else{ |
| 307 | fossil_fatal("branch subcommand should be one of: " |
| 308 | "new list ls"); |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | static const char brlistQuery[] = |
| 313 | @ SELECT |
| 314 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -239,20 +239,40 @@ | |
| 239 | break; |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | /* |
| 245 | ** If the branch named in the argument is open, return a RID for one of |
| 246 | ** the open leaves of that branch. If the branch does not exists or is |
| 247 | ** closed, return 0. |
| 248 | */ |
| 249 | int branch_is_open(const char *zBrName){ |
| 250 | return db_int(0, |
| 251 | "SELECT rid FROM tagxref AS ox" |
| 252 | " WHERE tagid=%d" |
| 253 | " AND tagtype=2" |
| 254 | " AND value=%Q" |
| 255 | " AND rid IN leaf" |
| 256 | " AND NOT EXISTS(SELECT 1 FROM tagxref AS ix" |
| 257 | " WHERE tagid=%d" |
| 258 | " AND tagtype=1" |
| 259 | " AND ox.rid=ix.rid)", |
| 260 | TAG_BRANCH, zBrName, TAG_CLOSED |
| 261 | ); |
| 262 | } |
| 263 | |
| 264 | |
| 265 | /* |
| 266 | ** COMMAND: branch |
| 267 | ** |
| 268 | ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS? |
| 269 | ** |
| 270 | ** Run various subcommands to manage branches of the open repository or |
| 271 | ** of the repository identified by the -R or --repository option. |
| 272 | ** |
| 273 | ** fossil branch new BRANCH-NAME BASIS ?OPTIONS? |
| 274 | ** |
| 275 | ** Create a new branch BRANCH-NAME off of check-in BASIS. |
| 276 | ** Supported options for this subcommand include: |
| 277 | ** --private branch is private (i.e., remains local) |
| 278 | ** --bgcolor COLOR use COLOR instead of automatic background |
| @@ -264,16 +284,20 @@ | |
| 284 | ** year-month-day form, it may be truncated, the "T" may be |
| 285 | ** replaced by a space, and it may also name a timezone offset |
| 286 | ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward). |
| 287 | ** Either no timezone suffix or "Z" means UTC. |
| 288 | ** |
| 289 | ** fossil branch list|ls ?-a|--all|-c|--closed? |
| 290 | ** |
| 291 | ** List all branches. Use -a or --all to list all branches and |
| 292 | ** -c or --closed to list all closed branches. The default is to |
| 293 | ** show only open branches. |
| 294 | ** |
| 295 | ** fossil branch info BRANCH-NAME |
| 296 | ** |
| 297 | ** Print information about a branch |
| 298 | ** |
| 299 | ** Options: |
| 300 | ** -R|--repository FILE Run commands on repository FILE |
| 301 | */ |
| 302 | void branch_cmd(void){ |
| 303 | int n; |
| @@ -301,13 +325,28 @@ | |
| 325 | const char *zBr = db_column_text(&q, 0); |
| 326 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 327 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 328 | } |
| 329 | db_finalize(&q); |
| 330 | }else if( strncmp(zCmd,"info",n)==0 ){ |
| 331 | int i; |
| 332 | for(i=3; i<g.argc; i++){ |
| 333 | const char *zBrName = g.argv[i]; |
| 334 | int rid = branch_is_open(zBrName); |
| 335 | if( rid==0 ){ |
| 336 | fossil_print("%s: not an open branch\n", zBrName); |
| 337 | }else{ |
| 338 | const char *zUuid = db_text(0,"SELECT uuid FROM blob WHERE rid=%d",rid); |
| 339 | const char *zDate = db_text(0, |
| 340 | "SELECT datetime(mtime,toLocal()) FROM event" |
| 341 | " WHERE objid=%d", rid); |
| 342 | fossil_print("%s: open as of %s on %.16s\n", zBrName, zDate, zUuid); |
| 343 | } |
| 344 | } |
| 345 | }else{ |
| 346 | fossil_fatal("branch subcommand should be one of: " |
| 347 | "info list ls new"); |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | static const char brlistQuery[] = |
| 352 | @ SELECT |
| 353 |
+7
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -2112,10 +2112,17 @@ | ||
| 2112 | 2112 | noSign = db_get_boolean("omitsign", 0)|noSign; |
| 2113 | 2113 | if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; } |
| 2114 | 2114 | useCksum = db_get_boolean("repo-cksum", 1); |
| 2115 | 2115 | outputManifest = db_get_manifest_setting(); |
| 2116 | 2116 | verify_all_options(); |
| 2117 | + | |
| 2118 | + /* Do not allow the creation of a new branch using an existing open | |
| 2119 | + ** branch name unless the --force flag is used */ | |
| 2120 | + if( sCiInfo.zBranch!=0 && !forceFlag && branch_is_open(sCiInfo.zBranch) ){ | |
| 2121 | + fossil_fatal("an open branch named \"%s\" already exists - use --force" | |
| 2122 | + " to override", sCiInfo.zBranch); | |
| 2123 | + } | |
| 2117 | 2124 | |
| 2118 | 2125 | /* Escape special characters in tags and put all tags in sorted order */ |
| 2119 | 2126 | if( nTag ){ |
| 2120 | 2127 | int i; |
| 2121 | 2128 | for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]); |
| 2122 | 2129 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -2112,10 +2112,17 @@ | |
| 2112 | noSign = db_get_boolean("omitsign", 0)|noSign; |
| 2113 | if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; } |
| 2114 | useCksum = db_get_boolean("repo-cksum", 1); |
| 2115 | outputManifest = db_get_manifest_setting(); |
| 2116 | verify_all_options(); |
| 2117 | |
| 2118 | /* Escape special characters in tags and put all tags in sorted order */ |
| 2119 | if( nTag ){ |
| 2120 | int i; |
| 2121 | for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]); |
| 2122 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -2112,10 +2112,17 @@ | |
| 2112 | noSign = db_get_boolean("omitsign", 0)|noSign; |
| 2113 | if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; } |
| 2114 | useCksum = db_get_boolean("repo-cksum", 1); |
| 2115 | outputManifest = db_get_manifest_setting(); |
| 2116 | verify_all_options(); |
| 2117 | |
| 2118 | /* Do not allow the creation of a new branch using an existing open |
| 2119 | ** branch name unless the --force flag is used */ |
| 2120 | if( sCiInfo.zBranch!=0 && !forceFlag && branch_is_open(sCiInfo.zBranch) ){ |
| 2121 | fossil_fatal("an open branch named \"%s\" already exists - use --force" |
| 2122 | " to override", sCiInfo.zBranch); |
| 2123 | } |
| 2124 | |
| 2125 | /* Escape special characters in tags and put all tags in sorted order */ |
| 2126 | if( nTag ){ |
| 2127 | int i; |
| 2128 | for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]); |
| 2129 |