Fossil SCM

Allow unversioned files to be identify by hash in addition to name. For the /uv webpage, when a file is identify by hash it has a long expiration time.

drh 2020-05-17 20:38 trunk
Commit b5ab1ebe5e7c7da06965072b505a730d9efa02287133d2bb15848bdea0872d8a
3 files changed +18 -13 +1 -1 +22 -7
+18 -13
--- src/doc.c
+++ src/doc.c
@@ -824,11 +824,12 @@
824824
** regardless of what branch it occurs on.
825825
**
826826
** FILE is the name of a file to delivered up as a webpage. FILE is relative
827827
** to the root of the source tree of the repository. The FILE must
828828
** be a part of CHECKIN, except when CHECKIN=="ckout" when FILE is read
829
-** directly from disk and need not be a managed file.
829
+** directly from disk and need not be a managed file. For /uv, FILE
830
+** can also be the hash of the unversioned file.
830831
**
831832
** The "ckout" CHECKIN is intended for development - to provide a mechanism
832833
** for looking at what a file will look like using the /doc webpage after
833834
** it gets checked in.
834835
**
@@ -931,22 +932,26 @@
931932
goto doc_not_found;
932933
}
933934
}
934935
if( isUV ){
935936
if( db_table_exists("repository","unversioned") ){
936
- Stmt q;
937
- db_prepare(&q, "SELECT hash, mtime FROM unversioned"
938
- " WHERE name=%Q", zName);
939
- if( db_step(&q)==SQLITE_ROW ){
940
- etag_check(ETAG_HASH, db_column_text(&q,0));
941
- etag_last_modified(db_column_int64(&q,1));
942
- }
943
- db_finalize(&q);
944
- if( unversioned_content(zName, &filebody)==0 ){
945
- rid = 1;
946
- zDfltTitle = zName;
947
- }
937
+ rid = unversioned_content(zName, &filebody);
938
+ if( rid==1 ){
939
+ Stmt q;
940
+ db_prepare(&q, "SELECT hash, mtime FROM unversioned"
941
+ " WHERE name=%Q", zName);
942
+ if( db_step(&q)==SQLITE_ROW ){
943
+ etag_check(ETAG_HASH, db_column_text(&q,0));
944
+ etag_last_modified(db_column_int64(&q,1));
945
+ }
946
+ db_finalize(&q);
947
+ }else if( rid==2 ){
948
+ zName = db_text(zName,
949
+ "SELECT name FROM unversioned WHERE hash=%Q", zName);
950
+ g.isConst = 1;
951
+ }
952
+ zDfltTitle = zName;
948953
}
949954
}else if( fossil_strcmp(zCheckin,"ckout")==0 ){
950955
/* Read from the local checkout */
951956
char *zFullpath;
952957
db_must_be_within_tree();
953958
--- src/doc.c
+++ src/doc.c
@@ -824,11 +824,12 @@
824 ** regardless of what branch it occurs on.
825 **
826 ** FILE is the name of a file to delivered up as a webpage. FILE is relative
827 ** to the root of the source tree of the repository. The FILE must
828 ** be a part of CHECKIN, except when CHECKIN=="ckout" when FILE is read
829 ** directly from disk and need not be a managed file.
 
830 **
831 ** The "ckout" CHECKIN is intended for development - to provide a mechanism
832 ** for looking at what a file will look like using the /doc webpage after
833 ** it gets checked in.
834 **
@@ -931,22 +932,26 @@
931 goto doc_not_found;
932 }
933 }
934 if( isUV ){
935 if( db_table_exists("repository","unversioned") ){
936 Stmt q;
937 db_prepare(&q, "SELECT hash, mtime FROM unversioned"
938 " WHERE name=%Q", zName);
939 if( db_step(&q)==SQLITE_ROW ){
940 etag_check(ETAG_HASH, db_column_text(&q,0));
941 etag_last_modified(db_column_int64(&q,1));
942 }
943 db_finalize(&q);
944 if( unversioned_content(zName, &filebody)==0 ){
945 rid = 1;
946 zDfltTitle = zName;
947 }
 
 
 
 
948 }
949 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
950 /* Read from the local checkout */
951 char *zFullpath;
952 db_must_be_within_tree();
953
--- src/doc.c
+++ src/doc.c
@@ -824,11 +824,12 @@
824 ** regardless of what branch it occurs on.
825 **
826 ** FILE is the name of a file to delivered up as a webpage. FILE is relative
827 ** to the root of the source tree of the repository. The FILE must
828 ** be a part of CHECKIN, except when CHECKIN=="ckout" when FILE is read
829 ** directly from disk and need not be a managed file. For /uv, FILE
830 ** can also be the hash of the unversioned file.
831 **
832 ** The "ckout" CHECKIN is intended for development - to provide a mechanism
833 ** for looking at what a file will look like using the /doc webpage after
834 ** it gets checked in.
835 **
@@ -931,22 +932,26 @@
932 goto doc_not_found;
933 }
934 }
935 if( isUV ){
936 if( db_table_exists("repository","unversioned") ){
937 rid = unversioned_content(zName, &filebody);
938 if( rid==1 ){
939 Stmt q;
940 db_prepare(&q, "SELECT hash, mtime FROM unversioned"
941 " WHERE name=%Q", zName);
942 if( db_step(&q)==SQLITE_ROW ){
943 etag_check(ETAG_HASH, db_column_text(&q,0));
944 etag_last_modified(db_column_int64(&q,1));
945 }
946 db_finalize(&q);
947 }else if( rid==2 ){
948 zName = db_text(zName,
949 "SELECT name FROM unversioned WHERE hash=%Q", zName);
950 g.isConst = 1;
951 }
952 zDfltTitle = zName;
953 }
954 }else if( fossil_strcmp(zCheckin,"ckout")==0 ){
955 /* Read from the local checkout */
956 char *zFullpath;
957 db_must_be_within_tree();
958
+1 -1
--- src/th_main.c
+++ src/th_main.c
@@ -1500,11 +1500,11 @@
15001500
if( argc!=3 ){
15011501
return Th_WrongNumArgs(interp, "unversioned content FILENAME");
15021502
}
15031503
if( Th_IsRepositoryOpen() ){
15041504
Blob content;
1505
- if( unversioned_content(argv[2], &content)==0 ){
1505
+ if( unversioned_content(argv[2], &content)!=0 ){
15061506
Th_SetResult(interp, blob_str(&content), blob_size(&content));
15071507
blob_reset(&content);
15081508
return TH_OK;
15091509
}else{
15101510
return TH_ERROR;
15111511
--- src/th_main.c
+++ src/th_main.c
@@ -1500,11 +1500,11 @@
1500 if( argc!=3 ){
1501 return Th_WrongNumArgs(interp, "unversioned content FILENAME");
1502 }
1503 if( Th_IsRepositoryOpen() ){
1504 Blob content;
1505 if( unversioned_content(argv[2], &content)==0 ){
1506 Th_SetResult(interp, blob_str(&content), blob_size(&content));
1507 blob_reset(&content);
1508 return TH_OK;
1509 }else{
1510 return TH_ERROR;
1511
--- src/th_main.c
+++ src/th_main.c
@@ -1500,11 +1500,11 @@
1500 if( argc!=3 ){
1501 return Th_WrongNumArgs(interp, "unversioned content FILENAME");
1502 }
1503 if( Th_IsRepositoryOpen() ){
1504 Blob content;
1505 if( unversioned_content(argv[2], &content)!=0 ){
1506 Th_SetResult(interp, blob_str(&content), blob_size(&content));
1507 blob_reset(&content);
1508 return TH_OK;
1509 }else{
1510 return TH_ERROR;
1511
--- src/unversioned.c
+++ src/unversioned.c
@@ -85,25 +85,40 @@
8585
}
8686
8787
/*
8888
** Initialize pContent to be the content of an unversioned file zName.
8989
**
90
-** Return 0 on success. Return 1 if zName is not found.
90
+** Return 0 on failures.
91
+** Return 1 if the file is found by name.
92
+** Return 2 if the file is found by hash.
9193
*/
9294
int unversioned_content(const char *zName, Blob *pContent){
9395
Stmt q;
94
- int rc = 1;
96
+ int rc = 0;
9597
blob_init(pContent, 0, 0);
96
- db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q", zName);
98
+ db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q",
99
+ zName);
97100
if( db_step(&q)==SQLITE_ROW ){
98101
db_column_blob(&q, 1, pContent);
99102
if( db_column_int(&q, 0)==1 ){
100103
blob_uncompress(pContent, pContent);
101104
}
102
- rc = 0;
105
+ rc = 1;
103106
}
104107
db_finalize(&q);
108
+ if( rc==0 && validate16(zName,-1) ){
109
+ db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE hash=%Q",
110
+ zName);
111
+ if( db_step(&q)==SQLITE_ROW ){
112
+ db_column_blob(&q, 1, pContent);
113
+ if( db_column_int(&q, 0)==1 ){
114
+ blob_uncompress(pContent, pContent);
115
+ }
116
+ rc = 2;
117
+ }
118
+ db_finalize(&q);
119
+ }
105120
return rc;
106121
}
107122
108123
/*
109124
** Write unversioned content into the database.
@@ -328,11 +343,11 @@
328343
int i;
329344
verify_all_options();
330345
db_begin_transaction();
331346
for(i=3; i<g.argc; i++){
332347
Blob content;
333
- if( unversioned_content(g.argv[i], &content)==0 ){
348
+ if( unversioned_content(g.argv[i], &content)!=0 ){
334349
blob_write_to_file(&content, "-");
335350
}
336351
blob_reset(&content);
337352
}
338353
db_end_transaction(0);
@@ -352,11 +367,11 @@
352367
}
353368
zTFile = fossil_temp_filename();
354369
if( zTFile==0 ) fossil_fatal("cannot find a temporary filename");
355370
db_begin_transaction();
356371
content_rcvid_init("#!fossil unversioned edit");
357
- if( unversioned_content(zUVFile, &content) ){
372
+ if( unversioned_content(zUVFile, &content)==0 ){
358373
fossil_fatal("no such uv-file: %Q", zUVFile);
359374
}
360375
if( looks_like_binary(&content) ){
361376
fossil_fatal("cannot edit binary content");
362377
}
@@ -381,11 +396,11 @@
381396
blob_reset(&content);
382397
}else if( memcmp(zCmd, "export", nCmd)==0 ){
383398
Blob content;
384399
verify_all_options();
385400
if( g.argc!=5 ) usage("export UVFILE OUTPUT");
386
- if( unversioned_content(g.argv[3], &content) ){
401
+ if( unversioned_content(g.argv[3], &content)==0 ){
387402
fossil_fatal("no such uv-file: %Q", g.argv[3]);
388403
}
389404
blob_write_to_file(&content, g.argv[4]);
390405
blob_reset(&content);
391406
}else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
392407
--- src/unversioned.c
+++ src/unversioned.c
@@ -85,25 +85,40 @@
85 }
86
87 /*
88 ** Initialize pContent to be the content of an unversioned file zName.
89 **
90 ** Return 0 on success. Return 1 if zName is not found.
 
 
91 */
92 int unversioned_content(const char *zName, Blob *pContent){
93 Stmt q;
94 int rc = 1;
95 blob_init(pContent, 0, 0);
96 db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q", zName);
 
97 if( db_step(&q)==SQLITE_ROW ){
98 db_column_blob(&q, 1, pContent);
99 if( db_column_int(&q, 0)==1 ){
100 blob_uncompress(pContent, pContent);
101 }
102 rc = 0;
103 }
104 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
105 return rc;
106 }
107
108 /*
109 ** Write unversioned content into the database.
@@ -328,11 +343,11 @@
328 int i;
329 verify_all_options();
330 db_begin_transaction();
331 for(i=3; i<g.argc; i++){
332 Blob content;
333 if( unversioned_content(g.argv[i], &content)==0 ){
334 blob_write_to_file(&content, "-");
335 }
336 blob_reset(&content);
337 }
338 db_end_transaction(0);
@@ -352,11 +367,11 @@
352 }
353 zTFile = fossil_temp_filename();
354 if( zTFile==0 ) fossil_fatal("cannot find a temporary filename");
355 db_begin_transaction();
356 content_rcvid_init("#!fossil unversioned edit");
357 if( unversioned_content(zUVFile, &content) ){
358 fossil_fatal("no such uv-file: %Q", zUVFile);
359 }
360 if( looks_like_binary(&content) ){
361 fossil_fatal("cannot edit binary content");
362 }
@@ -381,11 +396,11 @@
381 blob_reset(&content);
382 }else if( memcmp(zCmd, "export", nCmd)==0 ){
383 Blob content;
384 verify_all_options();
385 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
386 if( unversioned_content(g.argv[3], &content) ){
387 fossil_fatal("no such uv-file: %Q", g.argv[3]);
388 }
389 blob_write_to_file(&content, g.argv[4]);
390 blob_reset(&content);
391 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
392
--- src/unversioned.c
+++ src/unversioned.c
@@ -85,25 +85,40 @@
85 }
86
87 /*
88 ** Initialize pContent to be the content of an unversioned file zName.
89 **
90 ** Return 0 on failures.
91 ** Return 1 if the file is found by name.
92 ** Return 2 if the file is found by hash.
93 */
94 int unversioned_content(const char *zName, Blob *pContent){
95 Stmt q;
96 int rc = 0;
97 blob_init(pContent, 0, 0);
98 db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE name=%Q",
99 zName);
100 if( db_step(&q)==SQLITE_ROW ){
101 db_column_blob(&q, 1, pContent);
102 if( db_column_int(&q, 0)==1 ){
103 blob_uncompress(pContent, pContent);
104 }
105 rc = 1;
106 }
107 db_finalize(&q);
108 if( rc==0 && validate16(zName,-1) ){
109 db_prepare(&q, "SELECT encoding, content FROM unversioned WHERE hash=%Q",
110 zName);
111 if( db_step(&q)==SQLITE_ROW ){
112 db_column_blob(&q, 1, pContent);
113 if( db_column_int(&q, 0)==1 ){
114 blob_uncompress(pContent, pContent);
115 }
116 rc = 2;
117 }
118 db_finalize(&q);
119 }
120 return rc;
121 }
122
123 /*
124 ** Write unversioned content into the database.
@@ -328,11 +343,11 @@
343 int i;
344 verify_all_options();
345 db_begin_transaction();
346 for(i=3; i<g.argc; i++){
347 Blob content;
348 if( unversioned_content(g.argv[i], &content)!=0 ){
349 blob_write_to_file(&content, "-");
350 }
351 blob_reset(&content);
352 }
353 db_end_transaction(0);
@@ -352,11 +367,11 @@
367 }
368 zTFile = fossil_temp_filename();
369 if( zTFile==0 ) fossil_fatal("cannot find a temporary filename");
370 db_begin_transaction();
371 content_rcvid_init("#!fossil unversioned edit");
372 if( unversioned_content(zUVFile, &content)==0 ){
373 fossil_fatal("no such uv-file: %Q", zUVFile);
374 }
375 if( looks_like_binary(&content) ){
376 fossil_fatal("cannot edit binary content");
377 }
@@ -381,11 +396,11 @@
396 blob_reset(&content);
397 }else if( memcmp(zCmd, "export", nCmd)==0 ){
398 Blob content;
399 verify_all_options();
400 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
401 if( unversioned_content(g.argv[3], &content)==0 ){
402 fossil_fatal("no such uv-file: %Q", g.argv[3]);
403 }
404 blob_write_to_file(&content, g.argv[4]);
405 blob_reset(&content);
406 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
407

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button