Fossil SCM
For the "import --git" command, if a new commit omits the "from" field, then make it a child of the previous commit if the two are on the same branch.
Commit
25201dd86f61314215b3e575669623ad01385ab9
Parent
f7cff4ad13d06ec…
1 file changed
+37
-18
+37
-18
| --- src/import.c | ||
| +++ src/import.c | ||
| @@ -42,25 +42,40 @@ | ||
| 42 | 42 | static struct { |
| 43 | 43 | void (*xFinish)(void); /* Function to finish a prior record */ |
| 44 | 44 | int nData; /* Bytes of data */ |
| 45 | 45 | char *zTag; /* Name of a tag */ |
| 46 | 46 | char *zBranch; /* Name of a branch for a commit */ |
| 47 | + char *zPrevBranch; /* The branch of the previous check-in */ | |
| 47 | 48 | char *aData; /* Data content */ |
| 48 | 49 | char *zMark; /* The current mark */ |
| 49 | 50 | char *zDate; /* Date/time stamp */ |
| 50 | 51 | char *zUser; /* User name */ |
| 51 | 52 | char *zComment; /* Comment of a commit */ |
| 52 | 53 | char *zFrom; /* from value as a UUID */ |
| 54 | + char *zPrevCheckin; /* Name of the previous check-in */ | |
| 53 | 55 | char *zFromMark; /* The mark of the "from" field */ |
| 54 | 56 | int nMerge; /* Number of merge values */ |
| 55 | 57 | int nMergeAlloc; /* Number of slots in azMerge[] */ |
| 56 | 58 | char **azMerge; /* Merge values */ |
| 57 | 59 | int nFile; /* Number of aFile values */ |
| 58 | 60 | int nFileAlloc; /* Number of slots in aFile[] */ |
| 59 | 61 | ImportFile *aFile; /* Information about files in a commit */ |
| 60 | 62 | int fromLoaded; /* True zFrom content loaded into aFile[] */ |
| 61 | 63 | } gg; |
| 64 | + | |
| 65 | +/* | |
| 66 | +** Duplicate a string. | |
| 67 | +*/ | |
| 68 | +static char *import_strdup(const char *zOrig){ | |
| 69 | + char *z = 0; | |
| 70 | + if( zOrig ){ | |
| 71 | + int n = strlen(zOrig); | |
| 72 | + z = fossil_malloc( n+1 ); | |
| 73 | + memcpy(z, zOrig, n+1); | |
| 74 | + } | |
| 75 | + return z; | |
| 76 | +} | |
| 62 | 77 | |
| 63 | 78 | /* |
| 64 | 79 | ** A no-op "xFinish" method |
| 65 | 80 | */ |
| 66 | 81 | static void finish_noop(void){} |
| @@ -93,10 +108,12 @@ | ||
| 93 | 108 | fossil_free(gg.aFile[i].zPrior); |
| 94 | 109 | } |
| 95 | 110 | memset(gg.aFile, 0, gg.nFile*sizeof(gg.aFile[0])); |
| 96 | 111 | gg.nFile = 0; |
| 97 | 112 | if( freeAll ){ |
| 113 | + fossil_free(gg.zPrevBranch); | |
| 114 | + fossil_free(gg.zPrevCheckin); | |
| 98 | 115 | fossil_free(gg.azMerge); |
| 99 | 116 | fossil_free(gg.aFile); |
| 100 | 117 | memset(&gg, 0, sizeof(gg)); |
| 101 | 118 | } |
| 102 | 119 | gg.xFinish = finish_noop; |
| @@ -104,12 +121,15 @@ | ||
| 104 | 121 | |
| 105 | 122 | /* |
| 106 | 123 | ** Insert an artifact into the BLOB table if it isn't there already. |
| 107 | 124 | ** If zMark is not zero, create a cross-reference from that mark back |
| 108 | 125 | ** to the newly inserted artifact. |
| 126 | +** | |
| 127 | +** If saveUuid is true, then pContent is a commit record. Record its | |
| 128 | +** UUID in gg.zPrevCheckin. | |
| 109 | 129 | */ |
| 110 | -static int fast_insert_content(Blob *pContent, const char *zMark){ | |
| 130 | +static int fast_insert_content(Blob *pContent, const char *zMark, int saveUuid){ | |
| 111 | 131 | Blob hash; |
| 112 | 132 | Blob cmpr; |
| 113 | 133 | int rid; |
| 114 | 134 | |
| 115 | 135 | sha1sum_blob(pContent, &hash); |
| @@ -138,10 +158,14 @@ | ||
| 138 | 158 | "INSERT INTO xtag(tname, trid, tuuid)" |
| 139 | 159 | "VALUES(%B,%d,%B)", |
| 140 | 160 | &hash, rid, &hash |
| 141 | 161 | ); |
| 142 | 162 | } |
| 163 | + if( saveUuid ){ | |
| 164 | + fossil_free(gg.zPrevCheckin); | |
| 165 | + gg.zPrevCheckin = import_strdup(blob_str(&hash)); | |
| 166 | + } | |
| 143 | 167 | blob_reset(&hash); |
| 144 | 168 | return rid; |
| 145 | 169 | } |
| 146 | 170 | |
| 147 | 171 | /* |
| @@ -149,11 +173,11 @@ | ||
| 149 | 173 | ** to the BLOB table. |
| 150 | 174 | */ |
| 151 | 175 | static void finish_blob(void){ |
| 152 | 176 | Blob content; |
| 153 | 177 | blob_init(&content, gg.aData, gg.nData); |
| 154 | - fast_insert_content(&content, gg.zMark); | |
| 178 | + fast_insert_content(&content, gg.zMark, 0); | |
| 155 | 179 | blob_reset(&content); |
| 156 | 180 | import_reset(0); |
| 157 | 181 | } |
| 158 | 182 | |
| 159 | 183 | /* |
| @@ -167,11 +191,11 @@ | ||
| 167 | 191 | blob_appendf(&record, "D %s\n", gg.zDate); |
| 168 | 192 | blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom); |
| 169 | 193 | blob_appendf(&record, "U %F\n", gg.zUser); |
| 170 | 194 | md5sum_blob(&record, &cksum); |
| 171 | 195 | blob_appendf(&record, "Z %b\n", &cksum); |
| 172 | - fast_insert_content(&record, 0); | |
| 196 | + fast_insert_content(&record, 0, 0); | |
| 173 | 197 | blob_reset(&record); |
| 174 | 198 | blob_reset(&cksum); |
| 175 | 199 | } |
| 176 | 200 | import_reset(0); |
| 177 | 201 | } |
| @@ -194,10 +218,16 @@ | ||
| 194 | 218 | */ |
| 195 | 219 | static void finish_commit(void){ |
| 196 | 220 | int i; |
| 197 | 221 | char *zFromBranch; |
| 198 | 222 | Blob record, cksum; |
| 223 | + if( gg.zFrom==0 && gg.zPrevCheckin!=0 | |
| 224 | + && fossil_strcmp(gg.zBranch, gg.zPrevBranch)==0 | |
| 225 | + ){ | |
| 226 | + gg.zFrom = gg.zPrevCheckin; | |
| 227 | + gg.zPrevCheckin = 0; | |
| 228 | + } | |
| 199 | 229 | import_prior_files(); |
| 200 | 230 | qsort(gg.aFile, gg.nFile, sizeof(gg.aFile[0]), mfile_cmp); |
| 201 | 231 | blob_zero(&record); |
| 202 | 232 | blob_appendf(&record, "C %F\n", gg.zComment); |
| 203 | 233 | blob_appendf(&record, "D %s\n", gg.zDate); |
| @@ -236,14 +266,16 @@ | ||
| 236 | 266 | db_multi_exec("INSERT INTO xbranch(tname, brnm) VALUES(%Q,%Q)", |
| 237 | 267 | gg.zMark, gg.zBranch); |
| 238 | 268 | blob_appendf(&record, "U %F\n", gg.zUser); |
| 239 | 269 | md5sum_blob(&record, &cksum); |
| 240 | 270 | blob_appendf(&record, "Z %b\n", &cksum); |
| 241 | - fast_insert_content(&record, gg.zMark); | |
| 271 | + fast_insert_content(&record, gg.zMark, 1); | |
| 242 | 272 | blob_reset(&record); |
| 243 | 273 | blob_reset(&cksum); |
| 244 | - import_reset(0); | |
| 274 | + fossil_free(gg.zPrevBranch); | |
| 275 | + gg.zPrevBranch = gg.zBranch; | |
| 276 | + gg.zBranch = 0; | |
| 245 | 277 | import_reset(0); |
| 246 | 278 | } |
| 247 | 279 | |
| 248 | 280 | /* |
| 249 | 281 | ** Turn the first \n in the input string into a \000 |
| @@ -251,23 +283,10 @@ | ||
| 251 | 283 | static void trim_newline(char *z){ |
| 252 | 284 | while( z[0] && z[0]!='\n' ){ z++; } |
| 253 | 285 | z[0] = 0; |
| 254 | 286 | } |
| 255 | 287 | |
| 256 | -/* | |
| 257 | -** Duplicate a string. | |
| 258 | -*/ | |
| 259 | -static char *import_strdup(const char *zOrig){ | |
| 260 | - char *z = 0; | |
| 261 | - if( zOrig ){ | |
| 262 | - int n = strlen(zOrig); | |
| 263 | - z = fossil_malloc( n+1 ); | |
| 264 | - memcpy(z, zOrig, n+1); | |
| 265 | - } | |
| 266 | - return z; | |
| 267 | -} | |
| 268 | - | |
| 269 | 288 | /* |
| 270 | 289 | ** Get a token from a line of text. Return a pointer to the first |
| 271 | 290 | ** character of the token and zero-terminate the token. Make |
| 272 | 291 | ** *pzIn point to the first character past the end of the zero |
| 273 | 292 | ** terminator, or at the zero-terminator at EOL. |
| 274 | 293 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -42,25 +42,40 @@ | |
| 42 | static struct { |
| 43 | void (*xFinish)(void); /* Function to finish a prior record */ |
| 44 | int nData; /* Bytes of data */ |
| 45 | char *zTag; /* Name of a tag */ |
| 46 | char *zBranch; /* Name of a branch for a commit */ |
| 47 | char *aData; /* Data content */ |
| 48 | char *zMark; /* The current mark */ |
| 49 | char *zDate; /* Date/time stamp */ |
| 50 | char *zUser; /* User name */ |
| 51 | char *zComment; /* Comment of a commit */ |
| 52 | char *zFrom; /* from value as a UUID */ |
| 53 | char *zFromMark; /* The mark of the "from" field */ |
| 54 | int nMerge; /* Number of merge values */ |
| 55 | int nMergeAlloc; /* Number of slots in azMerge[] */ |
| 56 | char **azMerge; /* Merge values */ |
| 57 | int nFile; /* Number of aFile values */ |
| 58 | int nFileAlloc; /* Number of slots in aFile[] */ |
| 59 | ImportFile *aFile; /* Information about files in a commit */ |
| 60 | int fromLoaded; /* True zFrom content loaded into aFile[] */ |
| 61 | } gg; |
| 62 | |
| 63 | /* |
| 64 | ** A no-op "xFinish" method |
| 65 | */ |
| 66 | static void finish_noop(void){} |
| @@ -93,10 +108,12 @@ | |
| 93 | fossil_free(gg.aFile[i].zPrior); |
| 94 | } |
| 95 | memset(gg.aFile, 0, gg.nFile*sizeof(gg.aFile[0])); |
| 96 | gg.nFile = 0; |
| 97 | if( freeAll ){ |
| 98 | fossil_free(gg.azMerge); |
| 99 | fossil_free(gg.aFile); |
| 100 | memset(&gg, 0, sizeof(gg)); |
| 101 | } |
| 102 | gg.xFinish = finish_noop; |
| @@ -104,12 +121,15 @@ | |
| 104 | |
| 105 | /* |
| 106 | ** Insert an artifact into the BLOB table if it isn't there already. |
| 107 | ** If zMark is not zero, create a cross-reference from that mark back |
| 108 | ** to the newly inserted artifact. |
| 109 | */ |
| 110 | static int fast_insert_content(Blob *pContent, const char *zMark){ |
| 111 | Blob hash; |
| 112 | Blob cmpr; |
| 113 | int rid; |
| 114 | |
| 115 | sha1sum_blob(pContent, &hash); |
| @@ -138,10 +158,14 @@ | |
| 138 | "INSERT INTO xtag(tname, trid, tuuid)" |
| 139 | "VALUES(%B,%d,%B)", |
| 140 | &hash, rid, &hash |
| 141 | ); |
| 142 | } |
| 143 | blob_reset(&hash); |
| 144 | return rid; |
| 145 | } |
| 146 | |
| 147 | /* |
| @@ -149,11 +173,11 @@ | |
| 149 | ** to the BLOB table. |
| 150 | */ |
| 151 | static void finish_blob(void){ |
| 152 | Blob content; |
| 153 | blob_init(&content, gg.aData, gg.nData); |
| 154 | fast_insert_content(&content, gg.zMark); |
| 155 | blob_reset(&content); |
| 156 | import_reset(0); |
| 157 | } |
| 158 | |
| 159 | /* |
| @@ -167,11 +191,11 @@ | |
| 167 | blob_appendf(&record, "D %s\n", gg.zDate); |
| 168 | blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom); |
| 169 | blob_appendf(&record, "U %F\n", gg.zUser); |
| 170 | md5sum_blob(&record, &cksum); |
| 171 | blob_appendf(&record, "Z %b\n", &cksum); |
| 172 | fast_insert_content(&record, 0); |
| 173 | blob_reset(&record); |
| 174 | blob_reset(&cksum); |
| 175 | } |
| 176 | import_reset(0); |
| 177 | } |
| @@ -194,10 +218,16 @@ | |
| 194 | */ |
| 195 | static void finish_commit(void){ |
| 196 | int i; |
| 197 | char *zFromBranch; |
| 198 | Blob record, cksum; |
| 199 | import_prior_files(); |
| 200 | qsort(gg.aFile, gg.nFile, sizeof(gg.aFile[0]), mfile_cmp); |
| 201 | blob_zero(&record); |
| 202 | blob_appendf(&record, "C %F\n", gg.zComment); |
| 203 | blob_appendf(&record, "D %s\n", gg.zDate); |
| @@ -236,14 +266,16 @@ | |
| 236 | db_multi_exec("INSERT INTO xbranch(tname, brnm) VALUES(%Q,%Q)", |
| 237 | gg.zMark, gg.zBranch); |
| 238 | blob_appendf(&record, "U %F\n", gg.zUser); |
| 239 | md5sum_blob(&record, &cksum); |
| 240 | blob_appendf(&record, "Z %b\n", &cksum); |
| 241 | fast_insert_content(&record, gg.zMark); |
| 242 | blob_reset(&record); |
| 243 | blob_reset(&cksum); |
| 244 | import_reset(0); |
| 245 | import_reset(0); |
| 246 | } |
| 247 | |
| 248 | /* |
| 249 | ** Turn the first \n in the input string into a \000 |
| @@ -251,23 +283,10 @@ | |
| 251 | static void trim_newline(char *z){ |
| 252 | while( z[0] && z[0]!='\n' ){ z++; } |
| 253 | z[0] = 0; |
| 254 | } |
| 255 | |
| 256 | /* |
| 257 | ** Duplicate a string. |
| 258 | */ |
| 259 | static char *import_strdup(const char *zOrig){ |
| 260 | char *z = 0; |
| 261 | if( zOrig ){ |
| 262 | int n = strlen(zOrig); |
| 263 | z = fossil_malloc( n+1 ); |
| 264 | memcpy(z, zOrig, n+1); |
| 265 | } |
| 266 | return z; |
| 267 | } |
| 268 | |
| 269 | /* |
| 270 | ** Get a token from a line of text. Return a pointer to the first |
| 271 | ** character of the token and zero-terminate the token. Make |
| 272 | ** *pzIn point to the first character past the end of the zero |
| 273 | ** terminator, or at the zero-terminator at EOL. |
| 274 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -42,25 +42,40 @@ | |
| 42 | static struct { |
| 43 | void (*xFinish)(void); /* Function to finish a prior record */ |
| 44 | int nData; /* Bytes of data */ |
| 45 | char *zTag; /* Name of a tag */ |
| 46 | char *zBranch; /* Name of a branch for a commit */ |
| 47 | char *zPrevBranch; /* The branch of the previous check-in */ |
| 48 | char *aData; /* Data content */ |
| 49 | char *zMark; /* The current mark */ |
| 50 | char *zDate; /* Date/time stamp */ |
| 51 | char *zUser; /* User name */ |
| 52 | char *zComment; /* Comment of a commit */ |
| 53 | char *zFrom; /* from value as a UUID */ |
| 54 | char *zPrevCheckin; /* Name of the previous check-in */ |
| 55 | char *zFromMark; /* The mark of the "from" field */ |
| 56 | int nMerge; /* Number of merge values */ |
| 57 | int nMergeAlloc; /* Number of slots in azMerge[] */ |
| 58 | char **azMerge; /* Merge values */ |
| 59 | int nFile; /* Number of aFile values */ |
| 60 | int nFileAlloc; /* Number of slots in aFile[] */ |
| 61 | ImportFile *aFile; /* Information about files in a commit */ |
| 62 | int fromLoaded; /* True zFrom content loaded into aFile[] */ |
| 63 | } gg; |
| 64 | |
| 65 | /* |
| 66 | ** Duplicate a string. |
| 67 | */ |
| 68 | static char *import_strdup(const char *zOrig){ |
| 69 | char *z = 0; |
| 70 | if( zOrig ){ |
| 71 | int n = strlen(zOrig); |
| 72 | z = fossil_malloc( n+1 ); |
| 73 | memcpy(z, zOrig, n+1); |
| 74 | } |
| 75 | return z; |
| 76 | } |
| 77 | |
| 78 | /* |
| 79 | ** A no-op "xFinish" method |
| 80 | */ |
| 81 | static void finish_noop(void){} |
| @@ -93,10 +108,12 @@ | |
| 108 | fossil_free(gg.aFile[i].zPrior); |
| 109 | } |
| 110 | memset(gg.aFile, 0, gg.nFile*sizeof(gg.aFile[0])); |
| 111 | gg.nFile = 0; |
| 112 | if( freeAll ){ |
| 113 | fossil_free(gg.zPrevBranch); |
| 114 | fossil_free(gg.zPrevCheckin); |
| 115 | fossil_free(gg.azMerge); |
| 116 | fossil_free(gg.aFile); |
| 117 | memset(&gg, 0, sizeof(gg)); |
| 118 | } |
| 119 | gg.xFinish = finish_noop; |
| @@ -104,12 +121,15 @@ | |
| 121 | |
| 122 | /* |
| 123 | ** Insert an artifact into the BLOB table if it isn't there already. |
| 124 | ** If zMark is not zero, create a cross-reference from that mark back |
| 125 | ** to the newly inserted artifact. |
| 126 | ** |
| 127 | ** If saveUuid is true, then pContent is a commit record. Record its |
| 128 | ** UUID in gg.zPrevCheckin. |
| 129 | */ |
| 130 | static int fast_insert_content(Blob *pContent, const char *zMark, int saveUuid){ |
| 131 | Blob hash; |
| 132 | Blob cmpr; |
| 133 | int rid; |
| 134 | |
| 135 | sha1sum_blob(pContent, &hash); |
| @@ -138,10 +158,14 @@ | |
| 158 | "INSERT INTO xtag(tname, trid, tuuid)" |
| 159 | "VALUES(%B,%d,%B)", |
| 160 | &hash, rid, &hash |
| 161 | ); |
| 162 | } |
| 163 | if( saveUuid ){ |
| 164 | fossil_free(gg.zPrevCheckin); |
| 165 | gg.zPrevCheckin = import_strdup(blob_str(&hash)); |
| 166 | } |
| 167 | blob_reset(&hash); |
| 168 | return rid; |
| 169 | } |
| 170 | |
| 171 | /* |
| @@ -149,11 +173,11 @@ | |
| 173 | ** to the BLOB table. |
| 174 | */ |
| 175 | static void finish_blob(void){ |
| 176 | Blob content; |
| 177 | blob_init(&content, gg.aData, gg.nData); |
| 178 | fast_insert_content(&content, gg.zMark, 0); |
| 179 | blob_reset(&content); |
| 180 | import_reset(0); |
| 181 | } |
| 182 | |
| 183 | /* |
| @@ -167,11 +191,11 @@ | |
| 191 | blob_appendf(&record, "D %s\n", gg.zDate); |
| 192 | blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom); |
| 193 | blob_appendf(&record, "U %F\n", gg.zUser); |
| 194 | md5sum_blob(&record, &cksum); |
| 195 | blob_appendf(&record, "Z %b\n", &cksum); |
| 196 | fast_insert_content(&record, 0, 0); |
| 197 | blob_reset(&record); |
| 198 | blob_reset(&cksum); |
| 199 | } |
| 200 | import_reset(0); |
| 201 | } |
| @@ -194,10 +218,16 @@ | |
| 218 | */ |
| 219 | static void finish_commit(void){ |
| 220 | int i; |
| 221 | char *zFromBranch; |
| 222 | Blob record, cksum; |
| 223 | if( gg.zFrom==0 && gg.zPrevCheckin!=0 |
| 224 | && fossil_strcmp(gg.zBranch, gg.zPrevBranch)==0 |
| 225 | ){ |
| 226 | gg.zFrom = gg.zPrevCheckin; |
| 227 | gg.zPrevCheckin = 0; |
| 228 | } |
| 229 | import_prior_files(); |
| 230 | qsort(gg.aFile, gg.nFile, sizeof(gg.aFile[0]), mfile_cmp); |
| 231 | blob_zero(&record); |
| 232 | blob_appendf(&record, "C %F\n", gg.zComment); |
| 233 | blob_appendf(&record, "D %s\n", gg.zDate); |
| @@ -236,14 +266,16 @@ | |
| 266 | db_multi_exec("INSERT INTO xbranch(tname, brnm) VALUES(%Q,%Q)", |
| 267 | gg.zMark, gg.zBranch); |
| 268 | blob_appendf(&record, "U %F\n", gg.zUser); |
| 269 | md5sum_blob(&record, &cksum); |
| 270 | blob_appendf(&record, "Z %b\n", &cksum); |
| 271 | fast_insert_content(&record, gg.zMark, 1); |
| 272 | blob_reset(&record); |
| 273 | blob_reset(&cksum); |
| 274 | fossil_free(gg.zPrevBranch); |
| 275 | gg.zPrevBranch = gg.zBranch; |
| 276 | gg.zBranch = 0; |
| 277 | import_reset(0); |
| 278 | } |
| 279 | |
| 280 | /* |
| 281 | ** Turn the first \n in the input string into a \000 |
| @@ -251,23 +283,10 @@ | |
| 283 | static void trim_newline(char *z){ |
| 284 | while( z[0] && z[0]!='\n' ){ z++; } |
| 285 | z[0] = 0; |
| 286 | } |
| 287 | |
| 288 | /* |
| 289 | ** Get a token from a line of text. Return a pointer to the first |
| 290 | ** character of the token and zero-terminate the token. Make |
| 291 | ** *pzIn point to the first character past the end of the zero |
| 292 | ** terminator, or at the zero-terminator at EOL. |
| 293 |