Fossil SCM
Improved warning message when there alternative leaf check-outs on the current branch.
Commit
f78cba5c9994222f3ef16b4a124b281a1aaa1d49
Parent
7bef5bf1c3d43d4…
5 files changed
+1
+1
-23
+87
+87
+5
-10
+1
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -264,10 +264,11 @@ | ||
| 264 | 264 | if( vid ){ |
| 265 | 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | 266 | } |
| 267 | 267 | db_record_repository_filename(0); |
| 268 | 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | + leaf_ambiguity_warning(vid, vid); | |
| 269 | 270 | } |
| 270 | 271 | |
| 271 | 272 | /* |
| 272 | 273 | ** Take care of -r version of ls command |
| 273 | 274 | */ |
| 274 | 275 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -264,10 +264,11 @@ | |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** Take care of -r version of ls command |
| 273 | */ |
| 274 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -264,10 +264,11 @@ | |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | leaf_ambiguity_warning(vid, vid); |
| 270 | } |
| 271 | |
| 272 | /* |
| 273 | ** Take care of -r version of ls command |
| 274 | */ |
| 275 |
+1
-23
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -49,13 +49,12 @@ | ||
| 49 | 49 | ** * The UUID |
| 50 | 50 | ** * The record ID |
| 51 | 51 | ** * mtime and ctime |
| 52 | 52 | ** * who signed it |
| 53 | 53 | ** |
| 54 | -** Returns 1 when a fork was found. | |
| 55 | 54 | */ |
| 56 | -int show_common_info( | |
| 55 | +void show_common_info( | |
| 57 | 56 | int rid, /* The rid for the check-in to display info for */ |
| 58 | 57 | const char *zUuidName, /* Name of the UUID */ |
| 59 | 58 | int showComment, /* True to show the check-in comment */ |
| 60 | 59 | int showFamily /* True to show parents and children */ |
| 61 | 60 | ){ |
| @@ -62,11 +61,10 @@ | ||
| 62 | 61 | Stmt q; |
| 63 | 62 | char *zComment = 0; |
| 64 | 63 | char *zTags; |
| 65 | 64 | char *zDate; |
| 66 | 65 | char *zUuid; |
| 67 | - int isFork = 0; | |
| 68 | 66 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 69 | 67 | if( zUuid ){ |
| 70 | 68 | zDate = db_text(0, |
| 71 | 69 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 72 | 70 | rid |
| @@ -112,29 +110,10 @@ | ||
| 112 | 110 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 113 | 111 | free(zDate); |
| 114 | 112 | } |
| 115 | 113 | db_finalize(&q); |
| 116 | 114 | } |
| 117 | - if( zUuid ){ | |
| 118 | - fossil_print("%-13s ", "leaf:"); | |
| 119 | - if( is_a_leaf(rid) ){ | |
| 120 | - if( db_int(0, "SELECT 1 FROM tagxref AS tx" | |
| 121 | - " WHERE tx.rid=%d" | |
| 122 | - " AND tx.tagid=%d" | |
| 123 | - " AND tx.tagtype>0", | |
| 124 | - rid, TAG_CLOSED)){ | |
| 125 | - fossil_print("%s\n", "closed"); | |
| 126 | - }else if( fossil_find_nearest_fork(rid, db_open_local(0)) ){ | |
| 127 | - fossil_print("%s\n", "fork"); | |
| 128 | - isFork = 1; | |
| 129 | - }else{ | |
| 130 | - fossil_print("%s\n", "open"); | |
| 131 | - } | |
| 132 | - }else{ | |
| 133 | - fossil_print("no\n"); | |
| 134 | - } | |
| 135 | - } | |
| 136 | 115 | zTags = info_tags_of_checkin(rid, 0); |
| 137 | 116 | if( zTags && zTags[0] ){ |
| 138 | 117 | fossil_print("tags: %s\n", zTags); |
| 139 | 118 | } |
| 140 | 119 | free(zTags); |
| @@ -141,11 +120,10 @@ | ||
| 141 | 120 | if( zComment ){ |
| 142 | 121 | fossil_print("comment: "); |
| 143 | 122 | comment_print(zComment, 0, 14, -1, g.comFmtFlags); |
| 144 | 123 | free(zComment); |
| 145 | 124 | } |
| 146 | - return isFork; | |
| 147 | 125 | } |
| 148 | 126 | |
| 149 | 127 | /* |
| 150 | 128 | ** Print information about the URLs used to access a repository and |
| 151 | 129 | ** checkouts in a repository. |
| 152 | 130 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -49,13 +49,12 @@ | |
| 49 | ** * The UUID |
| 50 | ** * The record ID |
| 51 | ** * mtime and ctime |
| 52 | ** * who signed it |
| 53 | ** |
| 54 | ** Returns 1 when a fork was found. |
| 55 | */ |
| 56 | int show_common_info( |
| 57 | int rid, /* The rid for the check-in to display info for */ |
| 58 | const char *zUuidName, /* Name of the UUID */ |
| 59 | int showComment, /* True to show the check-in comment */ |
| 60 | int showFamily /* True to show parents and children */ |
| 61 | ){ |
| @@ -62,11 +61,10 @@ | |
| 62 | Stmt q; |
| 63 | char *zComment = 0; |
| 64 | char *zTags; |
| 65 | char *zDate; |
| 66 | char *zUuid; |
| 67 | int isFork = 0; |
| 68 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 69 | if( zUuid ){ |
| 70 | zDate = db_text(0, |
| 71 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 72 | rid |
| @@ -112,29 +110,10 @@ | |
| 112 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 113 | free(zDate); |
| 114 | } |
| 115 | db_finalize(&q); |
| 116 | } |
| 117 | if( zUuid ){ |
| 118 | fossil_print("%-13s ", "leaf:"); |
| 119 | if( is_a_leaf(rid) ){ |
| 120 | if( db_int(0, "SELECT 1 FROM tagxref AS tx" |
| 121 | " WHERE tx.rid=%d" |
| 122 | " AND tx.tagid=%d" |
| 123 | " AND tx.tagtype>0", |
| 124 | rid, TAG_CLOSED)){ |
| 125 | fossil_print("%s\n", "closed"); |
| 126 | }else if( fossil_find_nearest_fork(rid, db_open_local(0)) ){ |
| 127 | fossil_print("%s\n", "fork"); |
| 128 | isFork = 1; |
| 129 | }else{ |
| 130 | fossil_print("%s\n", "open"); |
| 131 | } |
| 132 | }else{ |
| 133 | fossil_print("no\n"); |
| 134 | } |
| 135 | } |
| 136 | zTags = info_tags_of_checkin(rid, 0); |
| 137 | if( zTags && zTags[0] ){ |
| 138 | fossil_print("tags: %s\n", zTags); |
| 139 | } |
| 140 | free(zTags); |
| @@ -141,11 +120,10 @@ | |
| 141 | if( zComment ){ |
| 142 | fossil_print("comment: "); |
| 143 | comment_print(zComment, 0, 14, -1, g.comFmtFlags); |
| 144 | free(zComment); |
| 145 | } |
| 146 | return isFork; |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | ** Print information about the URLs used to access a repository and |
| 151 | ** checkouts in a repository. |
| 152 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -49,13 +49,12 @@ | |
| 49 | ** * The UUID |
| 50 | ** * The record ID |
| 51 | ** * mtime and ctime |
| 52 | ** * who signed it |
| 53 | ** |
| 54 | */ |
| 55 | void show_common_info( |
| 56 | int rid, /* The rid for the check-in to display info for */ |
| 57 | const char *zUuidName, /* Name of the UUID */ |
| 58 | int showComment, /* True to show the check-in comment */ |
| 59 | int showFamily /* True to show parents and children */ |
| 60 | ){ |
| @@ -62,11 +61,10 @@ | |
| 61 | Stmt q; |
| 62 | char *zComment = 0; |
| 63 | char *zTags; |
| 64 | char *zDate; |
| 65 | char *zUuid; |
| 66 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 67 | if( zUuid ){ |
| 68 | zDate = db_text(0, |
| 69 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 70 | rid |
| @@ -112,29 +110,10 @@ | |
| 110 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 111 | free(zDate); |
| 112 | } |
| 113 | db_finalize(&q); |
| 114 | } |
| 115 | zTags = info_tags_of_checkin(rid, 0); |
| 116 | if( zTags && zTags[0] ){ |
| 117 | fossil_print("tags: %s\n", zTags); |
| 118 | } |
| 119 | free(zTags); |
| @@ -141,11 +120,10 @@ | |
| 120 | if( zComment ){ |
| 121 | fossil_print("comment: "); |
| 122 | comment_print(zComment, 0, 14, -1, g.comFmtFlags); |
| 123 | free(zComment); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | ** Print information about the URLs used to access a repository and |
| 129 | ** checkouts in a repository. |
| 130 |
+87
| --- src/leaf.c | ||
| +++ src/leaf.c | ||
| @@ -180,5 +180,92 @@ | ||
| 180 | 180 | for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){ |
| 181 | 181 | leaf_check(rid); |
| 182 | 182 | } |
| 183 | 183 | bag_clear(&needToCheck); |
| 184 | 184 | } |
| 185 | + | |
| 186 | +/* | |
| 187 | +** If check-in rid is an open-leaf and there exists another | |
| 188 | +** open leaf on the same branch, then return 1. | |
| 189 | +** | |
| 190 | +** If check-in rid is not an open leaf, or if it is the only open leaf | |
| 191 | +** on its branch, then return 0. | |
| 192 | +*/ | |
| 193 | +int leaf_ambiguity(int rid){ | |
| 194 | + int rc; /* Result */ | |
| 195 | + char zVal[30]; | |
| 196 | + if( !is_a_leaf(rid) ) return 0; | |
| 197 | + sqlite3_snprintf(sizeof(zVal), zVal, "%d", rid); | |
| 198 | + rc = db_exists( | |
| 199 | + "SELECT 1 FROM leaf" | |
| 200 | + " WHERE NOT %z" | |
| 201 | + " AND rid<>%d" | |
| 202 | + " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=" | |
| 203 | + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)" | |
| 204 | + " AND NOT %z", | |
| 205 | + leaf_is_closed_sql(zVal), rid, TAG_BRANCH, TAG_BRANCH, rid, | |
| 206 | + leaf_is_closed_sql("leaf.rid")); | |
| 207 | + return rc; | |
| 208 | +} | |
| 209 | + | |
| 210 | +/* | |
| 211 | +** If check-in rid is an open-leaf and there exists another open leaf | |
| 212 | +** on the same branch, then print a detailed warning showing all open | |
| 213 | +** leaves on that branch. | |
| 214 | +*/ | |
| 215 | +int leaf_ambiguity_warning(int rid, int currentCkout){ | |
| 216 | + char *zBr; | |
| 217 | + Stmt q; | |
| 218 | + int n = 0; | |
| 219 | + Blob msg; | |
| 220 | + if( leaf_ambiguity(rid)==0 ) return 0; | |
| 221 | + zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", | |
| 222 | + TAG_BRANCH, rid); | |
| 223 | + if( zBr==0 ) zBr = fossil_strdup("trunk"); | |
| 224 | + blob_init(&msg, 0, 0); | |
| 225 | + blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr); | |
| 226 | + db_prepare(&q, | |
| 227 | + "SELECT" | |
| 228 | + " (SELECT uuid FROM blob WHERE rid=leaf.rid)," | |
| 229 | + " (SELECT datetime(mtime%s) FROM event WHERE objid=leaf.rid)," | |
| 230 | + " leaf.rid" | |
| 231 | + " FROM leaf" | |
| 232 | + " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=%Q" | |
| 233 | + " AND NOT %z" | |
| 234 | + " ORDER BY 2 DESC", | |
| 235 | + timeline_utc(), TAG_BRANCH, zBr, leaf_is_closed_sql("leaf.rid") | |
| 236 | + ); | |
| 237 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 238 | + blob_appendf(&msg, "\n (%d) %s [%S]%s", | |
| 239 | + ++n, db_column_text(&q,1), db_column_text(&q,0), | |
| 240 | + db_column_int(&q,2)==currentCkout ? " (current)" : ""); | |
| 241 | + } | |
| 242 | + db_finalize(&q); | |
| 243 | + fossil_warning("%s",blob_str(&msg)); | |
| 244 | + blob_reset(&msg); | |
| 245 | + return 1; | |
| 246 | +} | |
| 247 | + | |
| 248 | +/* | |
| 249 | +** COMMAND: test-leaf-ambiguity | |
| 250 | +** | |
| 251 | +** Usage: %fossil NAME ... | |
| 252 | +** | |
| 253 | +** Resolve each name on the command line and call leaf_ambiguity_warning() | |
| 254 | +** for each resulting RID. | |
| 255 | +*/ | |
| 256 | +void leaf_ambiguity_warning_test(void){ | |
| 257 | + int i; | |
| 258 | + int rid; | |
| 259 | + int rc; | |
| 260 | + db_find_and_open_repository(0,0); | |
| 261 | + verify_all_options(); | |
| 262 | + for(i=2; i<g.argc; i++){ | |
| 263 | + char *zUuid; | |
| 264 | + rid = name_to_typed_rid(g.argv[i], "ci"); | |
| 265 | + zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); | |
| 266 | + fossil_print("%s (rid=%d) %S ", g.argv[i], rid, zUuid ? zUuid : "(none)"); | |
| 267 | + fossil_free(zUuid); | |
| 268 | + rc = leaf_ambiguity_warning(rid, rid); | |
| 269 | + if( rc==0 ) fossil_print(" ok\n"); | |
| 270 | + } | |
| 271 | +} | |
| 185 | 272 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -180,5 +180,92 @@ | |
| 180 | for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){ |
| 181 | leaf_check(rid); |
| 182 | } |
| 183 | bag_clear(&needToCheck); |
| 184 | } |
| 185 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -180,5 +180,92 @@ | |
| 180 | for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){ |
| 181 | leaf_check(rid); |
| 182 | } |
| 183 | bag_clear(&needToCheck); |
| 184 | } |
| 185 | |
| 186 | /* |
| 187 | ** If check-in rid is an open-leaf and there exists another |
| 188 | ** open leaf on the same branch, then return 1. |
| 189 | ** |
| 190 | ** If check-in rid is not an open leaf, or if it is the only open leaf |
| 191 | ** on its branch, then return 0. |
| 192 | */ |
| 193 | int leaf_ambiguity(int rid){ |
| 194 | int rc; /* Result */ |
| 195 | char zVal[30]; |
| 196 | if( !is_a_leaf(rid) ) return 0; |
| 197 | sqlite3_snprintf(sizeof(zVal), zVal, "%d", rid); |
| 198 | rc = db_exists( |
| 199 | "SELECT 1 FROM leaf" |
| 200 | " WHERE NOT %z" |
| 201 | " AND rid<>%d" |
| 202 | " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=" |
| 203 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)" |
| 204 | " AND NOT %z", |
| 205 | leaf_is_closed_sql(zVal), rid, TAG_BRANCH, TAG_BRANCH, rid, |
| 206 | leaf_is_closed_sql("leaf.rid")); |
| 207 | return rc; |
| 208 | } |
| 209 | |
| 210 | /* |
| 211 | ** If check-in rid is an open-leaf and there exists another open leaf |
| 212 | ** on the same branch, then print a detailed warning showing all open |
| 213 | ** leaves on that branch. |
| 214 | */ |
| 215 | int leaf_ambiguity_warning(int rid, int currentCkout){ |
| 216 | char *zBr; |
| 217 | Stmt q; |
| 218 | int n = 0; |
| 219 | Blob msg; |
| 220 | if( leaf_ambiguity(rid)==0 ) return 0; |
| 221 | zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 222 | TAG_BRANCH, rid); |
| 223 | if( zBr==0 ) zBr = fossil_strdup("trunk"); |
| 224 | blob_init(&msg, 0, 0); |
| 225 | blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr); |
| 226 | db_prepare(&q, |
| 227 | "SELECT" |
| 228 | " (SELECT uuid FROM blob WHERE rid=leaf.rid)," |
| 229 | " (SELECT datetime(mtime%s) FROM event WHERE objid=leaf.rid)," |
| 230 | " leaf.rid" |
| 231 | " FROM leaf" |
| 232 | " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=%Q" |
| 233 | " AND NOT %z" |
| 234 | " ORDER BY 2 DESC", |
| 235 | timeline_utc(), TAG_BRANCH, zBr, leaf_is_closed_sql("leaf.rid") |
| 236 | ); |
| 237 | while( db_step(&q)==SQLITE_ROW ){ |
| 238 | blob_appendf(&msg, "\n (%d) %s [%S]%s", |
| 239 | ++n, db_column_text(&q,1), db_column_text(&q,0), |
| 240 | db_column_int(&q,2)==currentCkout ? " (current)" : ""); |
| 241 | } |
| 242 | db_finalize(&q); |
| 243 | fossil_warning("%s",blob_str(&msg)); |
| 244 | blob_reset(&msg); |
| 245 | return 1; |
| 246 | } |
| 247 | |
| 248 | /* |
| 249 | ** COMMAND: test-leaf-ambiguity |
| 250 | ** |
| 251 | ** Usage: %fossil NAME ... |
| 252 | ** |
| 253 | ** Resolve each name on the command line and call leaf_ambiguity_warning() |
| 254 | ** for each resulting RID. |
| 255 | */ |
| 256 | void leaf_ambiguity_warning_test(void){ |
| 257 | int i; |
| 258 | int rid; |
| 259 | int rc; |
| 260 | db_find_and_open_repository(0,0); |
| 261 | verify_all_options(); |
| 262 | for(i=2; i<g.argc; i++){ |
| 263 | char *zUuid; |
| 264 | rid = name_to_typed_rid(g.argv[i], "ci"); |
| 265 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 266 | fossil_print("%s (rid=%d) %S ", g.argv[i], rid, zUuid ? zUuid : "(none)"); |
| 267 | fossil_free(zUuid); |
| 268 | rc = leaf_ambiguity_warning(rid, rid); |
| 269 | if( rc==0 ) fossil_print(" ok\n"); |
| 270 | } |
| 271 | } |
| 272 |
+87
| --- src/leaf.c | ||
| +++ src/leaf.c | ||
| @@ -180,5 +180,92 @@ | ||
| 180 | 180 | for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){ |
| 181 | 181 | leaf_check(rid); |
| 182 | 182 | } |
| 183 | 183 | bag_clear(&needToCheck); |
| 184 | 184 | } |
| 185 | + | |
| 186 | +/* | |
| 187 | +** If check-in rid is an open-leaf and there exists another | |
| 188 | +** open leaf on the same branch, then return 1. | |
| 189 | +** | |
| 190 | +** If check-in rid is not an open leaf, or if it is the only open leaf | |
| 191 | +** on its branch, then return 0. | |
| 192 | +*/ | |
| 193 | +int leaf_ambiguity(int rid){ | |
| 194 | + int rc; /* Result */ | |
| 195 | + char zVal[30]; | |
| 196 | + if( !is_a_leaf(rid) ) return 0; | |
| 197 | + sqlite3_snprintf(sizeof(zVal), zVal, "%d", rid); | |
| 198 | + rc = db_exists( | |
| 199 | + "SELECT 1 FROM leaf" | |
| 200 | + " WHERE NOT %z" | |
| 201 | + " AND rid<>%d" | |
| 202 | + " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=" | |
| 203 | + " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)" | |
| 204 | + " AND NOT %z", | |
| 205 | + leaf_is_closed_sql(zVal), rid, TAG_BRANCH, TAG_BRANCH, rid, | |
| 206 | + leaf_is_closed_sql("leaf.rid")); | |
| 207 | + return rc; | |
| 208 | +} | |
| 209 | + | |
| 210 | +/* | |
| 211 | +** If check-in rid is an open-leaf and there exists another open leaf | |
| 212 | +** on the same branch, then print a detailed warning showing all open | |
| 213 | +** leaves on that branch. | |
| 214 | +*/ | |
| 215 | +int leaf_ambiguity_warning(int rid, int currentCkout){ | |
| 216 | + char *zBr; | |
| 217 | + Stmt q; | |
| 218 | + int n = 0; | |
| 219 | + Blob msg; | |
| 220 | + if( leaf_ambiguity(rid)==0 ) return 0; | |
| 221 | + zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", | |
| 222 | + TAG_BRANCH, rid); | |
| 223 | + if( zBr==0 ) zBr = fossil_strdup("trunk"); | |
| 224 | + blob_init(&msg, 0, 0); | |
| 225 | + blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr); | |
| 226 | + db_prepare(&q, | |
| 227 | + "SELECT" | |
| 228 | + " (SELECT uuid FROM blob WHERE rid=leaf.rid)," | |
| 229 | + " (SELECT datetime(mtime%s) FROM event WHERE objid=leaf.rid)," | |
| 230 | + " leaf.rid" | |
| 231 | + " FROM leaf" | |
| 232 | + " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=%Q" | |
| 233 | + " AND NOT %z" | |
| 234 | + " ORDER BY 2 DESC", | |
| 235 | + timeline_utc(), TAG_BRANCH, zBr, leaf_is_closed_sql("leaf.rid") | |
| 236 | + ); | |
| 237 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 238 | + blob_appendf(&msg, "\n (%d) %s [%S]%s", | |
| 239 | + ++n, db_column_text(&q,1), db_column_text(&q,0), | |
| 240 | + db_column_int(&q,2)==currentCkout ? " (current)" : ""); | |
| 241 | + } | |
| 242 | + db_finalize(&q); | |
| 243 | + fossil_warning("%s",blob_str(&msg)); | |
| 244 | + blob_reset(&msg); | |
| 245 | + return 1; | |
| 246 | +} | |
| 247 | + | |
| 248 | +/* | |
| 249 | +** COMMAND: test-leaf-ambiguity | |
| 250 | +** | |
| 251 | +** Usage: %fossil NAME ... | |
| 252 | +** | |
| 253 | +** Resolve each name on the command line and call leaf_ambiguity_warning() | |
| 254 | +** for each resulting RID. | |
| 255 | +*/ | |
| 256 | +void leaf_ambiguity_warning_test(void){ | |
| 257 | + int i; | |
| 258 | + int rid; | |
| 259 | + int rc; | |
| 260 | + db_find_and_open_repository(0,0); | |
| 261 | + verify_all_options(); | |
| 262 | + for(i=2; i<g.argc; i++){ | |
| 263 | + char *zUuid; | |
| 264 | + rid = name_to_typed_rid(g.argv[i], "ci"); | |
| 265 | + zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); | |
| 266 | + fossil_print("%s (rid=%d) %S ", g.argv[i], rid, zUuid ? zUuid : "(none)"); | |
| 267 | + fossil_free(zUuid); | |
| 268 | + rc = leaf_ambiguity_warning(rid, rid); | |
| 269 | + if( rc==0 ) fossil_print(" ok\n"); | |
| 270 | + } | |
| 271 | +} | |
| 185 | 272 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -180,5 +180,92 @@ | |
| 180 | for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){ |
| 181 | leaf_check(rid); |
| 182 | } |
| 183 | bag_clear(&needToCheck); |
| 184 | } |
| 185 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -180,5 +180,92 @@ | |
| 180 | for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){ |
| 181 | leaf_check(rid); |
| 182 | } |
| 183 | bag_clear(&needToCheck); |
| 184 | } |
| 185 | |
| 186 | /* |
| 187 | ** If check-in rid is an open-leaf and there exists another |
| 188 | ** open leaf on the same branch, then return 1. |
| 189 | ** |
| 190 | ** If check-in rid is not an open leaf, or if it is the only open leaf |
| 191 | ** on its branch, then return 0. |
| 192 | */ |
| 193 | int leaf_ambiguity(int rid){ |
| 194 | int rc; /* Result */ |
| 195 | char zVal[30]; |
| 196 | if( !is_a_leaf(rid) ) return 0; |
| 197 | sqlite3_snprintf(sizeof(zVal), zVal, "%d", rid); |
| 198 | rc = db_exists( |
| 199 | "SELECT 1 FROM leaf" |
| 200 | " WHERE NOT %z" |
| 201 | " AND rid<>%d" |
| 202 | " AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=" |
| 203 | " (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)" |
| 204 | " AND NOT %z", |
| 205 | leaf_is_closed_sql(zVal), rid, TAG_BRANCH, TAG_BRANCH, rid, |
| 206 | leaf_is_closed_sql("leaf.rid")); |
| 207 | return rc; |
| 208 | } |
| 209 | |
| 210 | /* |
| 211 | ** If check-in rid is an open-leaf and there exists another open leaf |
| 212 | ** on the same branch, then print a detailed warning showing all open |
| 213 | ** leaves on that branch. |
| 214 | */ |
| 215 | int leaf_ambiguity_warning(int rid, int currentCkout){ |
| 216 | char *zBr; |
| 217 | Stmt q; |
| 218 | int n = 0; |
| 219 | Blob msg; |
| 220 | if( leaf_ambiguity(rid)==0 ) return 0; |
| 221 | zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 222 | TAG_BRANCH, rid); |
| 223 | if( zBr==0 ) zBr = fossil_strdup("trunk"); |
| 224 | blob_init(&msg, 0, 0); |
| 225 | blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr); |
| 226 | db_prepare(&q, |
| 227 | "SELECT" |
| 228 | " (SELECT uuid FROM blob WHERE rid=leaf.rid)," |
| 229 | " (SELECT datetime(mtime%s) FROM event WHERE objid=leaf.rid)," |
| 230 | " leaf.rid" |
| 231 | " FROM leaf" |
| 232 | " WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=%Q" |
| 233 | " AND NOT %z" |
| 234 | " ORDER BY 2 DESC", |
| 235 | timeline_utc(), TAG_BRANCH, zBr, leaf_is_closed_sql("leaf.rid") |
| 236 | ); |
| 237 | while( db_step(&q)==SQLITE_ROW ){ |
| 238 | blob_appendf(&msg, "\n (%d) %s [%S]%s", |
| 239 | ++n, db_column_text(&q,1), db_column_text(&q,0), |
| 240 | db_column_int(&q,2)==currentCkout ? " (current)" : ""); |
| 241 | } |
| 242 | db_finalize(&q); |
| 243 | fossil_warning("%s",blob_str(&msg)); |
| 244 | blob_reset(&msg); |
| 245 | return 1; |
| 246 | } |
| 247 | |
| 248 | /* |
| 249 | ** COMMAND: test-leaf-ambiguity |
| 250 | ** |
| 251 | ** Usage: %fossil NAME ... |
| 252 | ** |
| 253 | ** Resolve each name on the command line and call leaf_ambiguity_warning() |
| 254 | ** for each resulting RID. |
| 255 | */ |
| 256 | void leaf_ambiguity_warning_test(void){ |
| 257 | int i; |
| 258 | int rid; |
| 259 | int rc; |
| 260 | db_find_and_open_repository(0,0); |
| 261 | verify_all_options(); |
| 262 | for(i=2; i<g.argc; i++){ |
| 263 | char *zUuid; |
| 264 | rid = name_to_typed_rid(g.argv[i], "ci"); |
| 265 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 266 | fossil_print("%s (rid=%d) %S ", g.argv[i], rid, zUuid ? zUuid : "(none)"); |
| 267 | fossil_free(zUuid); |
| 268 | rc = leaf_ambiguity_warning(rid, rid); |
| 269 | if( rc==0 ) fossil_print(" ok\n"); |
| 270 | } |
| 271 | } |
| 272 |
+5
-10
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -121,11 +121,10 @@ | ||
| 121 | 121 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 122 | 122 | int nUpdate = 0; /* Number of changes of any kind */ |
| 123 | 123 | int width; /* Width of printed comment lines */ |
| 124 | 124 | Stmt mtimeXfer; /* Statement to transfer mtimes */ |
| 125 | 125 | const char *zWidth; /* Width option string value */ |
| 126 | - int isFork; | |
| 127 | 126 | |
| 128 | 127 | if( !internalUpdate ){ |
| 129 | 128 | undo_capture_command_line(); |
| 130 | 129 | url_proxy_options(); |
| 131 | 130 | } |
| @@ -176,14 +175,12 @@ | ||
| 176 | 175 | ** target as if VERSION were omitted and the --latest flag is present. |
| 177 | 176 | */ |
| 178 | 177 | latestFlag = 1; |
| 179 | 178 | }else{ |
| 180 | 179 | tid = name_to_typed_rid(g.argv[2],"ci"); |
| 181 | - if( tid==0 ){ | |
| 182 | - fossil_fatal("no such version: %s", g.argv[2]); | |
| 183 | - }else if( !is_a_version(tid) ){ | |
| 184 | - fossil_fatal("no such version: %s", g.argv[2]); | |
| 180 | + if( tid==0 || !is_a_version(tid) ){ | |
| 181 | + fossil_fatal("no such check-in: %s", g.argv[2]); | |
| 185 | 182 | } |
| 186 | 183 | } |
| 187 | 184 | } |
| 188 | 185 | |
| 189 | 186 | /* If no VERSION is specified on the command-line, then look for a |
| @@ -519,14 +516,14 @@ | ||
| 519 | 516 | } |
| 520 | 517 | db_finalize(&q); |
| 521 | 518 | db_finalize(&mtimeXfer); |
| 522 | 519 | fossil_print("%.79c\n",'-'); |
| 523 | 520 | if( nUpdate==0 ){ |
| 524 | - isFork = show_common_info(tid, "checkout:", 1, 0); | |
| 521 | + show_common_info(tid, "checkout:", 1, 0); | |
| 525 | 522 | fossil_print("%-13s None. Already up-to-date\n", "changes:"); |
| 526 | 523 | }else{ |
| 527 | - isFork = show_common_info(tid, "updated-to:", 1, 0); | |
| 524 | + show_common_info(tid, "updated-to:", 1, 0); | |
| 528 | 525 | fossil_print("%-13s %d file%s modified.\n", "changes:", |
| 529 | 526 | nUpdate, nUpdate>1 ? "s" : ""); |
| 530 | 527 | } |
| 531 | 528 | |
| 532 | 529 | /* Report on conflicts |
| @@ -545,10 +542,11 @@ | ||
| 545 | 542 | fossil_warning("uncommitted %s against %S.", |
| 546 | 543 | zLabel, db_column_text(&q, 0)); |
| 547 | 544 | nMerge++; |
| 548 | 545 | } |
| 549 | 546 | db_finalize(&q); |
| 547 | + leaf_ambiguity_warning(tid, tid); | |
| 550 | 548 | |
| 551 | 549 | if( nConflict ){ |
| 552 | 550 | if( internalUpdate ){ |
| 553 | 551 | internalConflictCnt = nConflict; |
| 554 | 552 | nConflict = 0; |
| @@ -561,13 +559,10 @@ | ||
| 561 | 559 | nOverwrite); |
| 562 | 560 | } |
| 563 | 561 | if( nMerge ){ |
| 564 | 562 | fossil_warning("WARNING: %d uncommitted prior merges", nMerge); |
| 565 | 563 | } |
| 566 | - if( isFork ){ | |
| 567 | - fossil_warning("WARNING: fork detected, please do a \"fossil merge\""); | |
| 568 | - } | |
| 569 | 564 | } |
| 570 | 565 | |
| 571 | 566 | /* |
| 572 | 567 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 573 | 568 | */ |
| 574 | 569 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -121,11 +121,10 @@ | |
| 121 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 122 | int nUpdate = 0; /* Number of changes of any kind */ |
| 123 | int width; /* Width of printed comment lines */ |
| 124 | Stmt mtimeXfer; /* Statement to transfer mtimes */ |
| 125 | const char *zWidth; /* Width option string value */ |
| 126 | int isFork; |
| 127 | |
| 128 | if( !internalUpdate ){ |
| 129 | undo_capture_command_line(); |
| 130 | url_proxy_options(); |
| 131 | } |
| @@ -176,14 +175,12 @@ | |
| 176 | ** target as if VERSION were omitted and the --latest flag is present. |
| 177 | */ |
| 178 | latestFlag = 1; |
| 179 | }else{ |
| 180 | tid = name_to_typed_rid(g.argv[2],"ci"); |
| 181 | if( tid==0 ){ |
| 182 | fossil_fatal("no such version: %s", g.argv[2]); |
| 183 | }else if( !is_a_version(tid) ){ |
| 184 | fossil_fatal("no such version: %s", g.argv[2]); |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | /* If no VERSION is specified on the command-line, then look for a |
| @@ -519,14 +516,14 @@ | |
| 519 | } |
| 520 | db_finalize(&q); |
| 521 | db_finalize(&mtimeXfer); |
| 522 | fossil_print("%.79c\n",'-'); |
| 523 | if( nUpdate==0 ){ |
| 524 | isFork = show_common_info(tid, "checkout:", 1, 0); |
| 525 | fossil_print("%-13s None. Already up-to-date\n", "changes:"); |
| 526 | }else{ |
| 527 | isFork = show_common_info(tid, "updated-to:", 1, 0); |
| 528 | fossil_print("%-13s %d file%s modified.\n", "changes:", |
| 529 | nUpdate, nUpdate>1 ? "s" : ""); |
| 530 | } |
| 531 | |
| 532 | /* Report on conflicts |
| @@ -545,10 +542,11 @@ | |
| 545 | fossil_warning("uncommitted %s against %S.", |
| 546 | zLabel, db_column_text(&q, 0)); |
| 547 | nMerge++; |
| 548 | } |
| 549 | db_finalize(&q); |
| 550 | |
| 551 | if( nConflict ){ |
| 552 | if( internalUpdate ){ |
| 553 | internalConflictCnt = nConflict; |
| 554 | nConflict = 0; |
| @@ -561,13 +559,10 @@ | |
| 561 | nOverwrite); |
| 562 | } |
| 563 | if( nMerge ){ |
| 564 | fossil_warning("WARNING: %d uncommitted prior merges", nMerge); |
| 565 | } |
| 566 | if( isFork ){ |
| 567 | fossil_warning("WARNING: fork detected, please do a \"fossil merge\""); |
| 568 | } |
| 569 | } |
| 570 | |
| 571 | /* |
| 572 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 573 | */ |
| 574 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -121,11 +121,10 @@ | |
| 121 | int nOverwrite = 0; /* Number of unmanaged files overwritten */ |
| 122 | int nUpdate = 0; /* Number of changes of any kind */ |
| 123 | int width; /* Width of printed comment lines */ |
| 124 | Stmt mtimeXfer; /* Statement to transfer mtimes */ |
| 125 | const char *zWidth; /* Width option string value */ |
| 126 | |
| 127 | if( !internalUpdate ){ |
| 128 | undo_capture_command_line(); |
| 129 | url_proxy_options(); |
| 130 | } |
| @@ -176,14 +175,12 @@ | |
| 175 | ** target as if VERSION were omitted and the --latest flag is present. |
| 176 | */ |
| 177 | latestFlag = 1; |
| 178 | }else{ |
| 179 | tid = name_to_typed_rid(g.argv[2],"ci"); |
| 180 | if( tid==0 || !is_a_version(tid) ){ |
| 181 | fossil_fatal("no such check-in: %s", g.argv[2]); |
| 182 | } |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | /* If no VERSION is specified on the command-line, then look for a |
| @@ -519,14 +516,14 @@ | |
| 516 | } |
| 517 | db_finalize(&q); |
| 518 | db_finalize(&mtimeXfer); |
| 519 | fossil_print("%.79c\n",'-'); |
| 520 | if( nUpdate==0 ){ |
| 521 | show_common_info(tid, "checkout:", 1, 0); |
| 522 | fossil_print("%-13s None. Already up-to-date\n", "changes:"); |
| 523 | }else{ |
| 524 | show_common_info(tid, "updated-to:", 1, 0); |
| 525 | fossil_print("%-13s %d file%s modified.\n", "changes:", |
| 526 | nUpdate, nUpdate>1 ? "s" : ""); |
| 527 | } |
| 528 | |
| 529 | /* Report on conflicts |
| @@ -545,10 +542,11 @@ | |
| 542 | fossil_warning("uncommitted %s against %S.", |
| 543 | zLabel, db_column_text(&q, 0)); |
| 544 | nMerge++; |
| 545 | } |
| 546 | db_finalize(&q); |
| 547 | leaf_ambiguity_warning(tid, tid); |
| 548 | |
| 549 | if( nConflict ){ |
| 550 | if( internalUpdate ){ |
| 551 | internalConflictCnt = nConflict; |
| 552 | nConflict = 0; |
| @@ -561,13 +559,10 @@ | |
| 559 | nOverwrite); |
| 560 | } |
| 561 | if( nMerge ){ |
| 562 | fossil_warning("WARNING: %d uncommitted prior merges", nMerge); |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | /* |
| 567 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 568 | */ |
| 569 |