Fossil SCM

Implement propagating settings that are sent to clients that pull. The warning-policy is used as example, but not yet applied.

preben 2023-10-16 14:33 warn-on-merging-private-branch
Commit f812fedc44d831076bc8b00f7e7f9af4c77a3c86bec774bac34795a6a2aede46
+21 -1
--- src/configure.c
+++ src/configure.c
@@ -41,10 +41,11 @@
4141
#define CONFIGSET_SCRIBER 0x000200 /* Email subscribers */
4242
#define CONFIGSET_IWIKI 0x000400 /* Interwiki codes */
4343
#define CONFIGSET_ALL 0x0007ff /* Everything */
4444
4545
#define CONFIGSET_OVERWRITE 0x100000 /* Causes overwrite instead of merge */
46
+#define CONFIGSET_PROPAGATE 0x200000 /* Propagating setting */
4647
4748
/*
4849
** This mask is used for the common TH1 configuration settings (i.e. those
4950
** that are not specific to one particular subsystem, such as the transfer
5051
** subsystem).
@@ -181,10 +182,11 @@
181182
182183
{ "xfer-common-script", CONFIGSET_XFER },
183184
{ "xfer-push-script", CONFIGSET_XFER },
184185
{ "xfer-commit-script", CONFIGSET_XFER },
185186
{ "xfer-ticket-script", CONFIGSET_XFER },
187
+ { "warning-policy", CONFIGSET_PROJ | CONFIGSET_PROPAGATE },
186188
187189
};
188190
static int iConfig = 0;
189191
190192
/*
@@ -424,11 +426,11 @@
424426
}
425427
checkMask &= ~thisMask;
426428
}
427429
428430
blob_zero(&sql);
429
- if( groupMask & CONFIGSET_OVERWRITE ){
431
+ if( groupMask & CONFIGSET_OVERWRITE || thisMask & CONFIGSET_PROPAGATE ){
430432
if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
431433
db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
432434
configHasBeenReset |= thisMask;
433435
}
434436
blob_append_sql(&sql, "REPLACE INTO ");
@@ -697,10 +699,28 @@
697699
}
698700
}
699701
db_finalize(&q);
700702
return nCard;
701703
}
704
+
705
+/*
706
+** Send the warning-policy, writing it to pOut.
707
+*/
708
+void configure_send_warning_policy(Blob *pOut){
709
+ const char *zRec;
710
+ zRec = db_text(0,
711
+ "SELECT mtime || ' ' || quote(name) || ' value ' || quote(value)"
712
+ " FROM config"
713
+ " WHERE name='warning-policy'");
714
+ if( zRec==0 ){
715
+ /* If not set, send the default value. */
716
+ zRec = db_text(0,
717
+ "SELECT now() || ' ' || quote(%Q) || ' value ' || quote(%Q)",
718
+ "warning-policy", db_get("warning-policy", 0));
719
+ }
720
+ blob_appendf(pOut, "config /config %d\n%s\n", strlen(zRec), zRec);
721
+}
702722
703723
/*
704724
** Identify a configuration group by name. Return its mask.
705725
** Throw an error if no match.
706726
*/
707727
--- src/configure.c
+++ src/configure.c
@@ -41,10 +41,11 @@
41 #define CONFIGSET_SCRIBER 0x000200 /* Email subscribers */
42 #define CONFIGSET_IWIKI 0x000400 /* Interwiki codes */
43 #define CONFIGSET_ALL 0x0007ff /* Everything */
44
45 #define CONFIGSET_OVERWRITE 0x100000 /* Causes overwrite instead of merge */
 
46
47 /*
48 ** This mask is used for the common TH1 configuration settings (i.e. those
49 ** that are not specific to one particular subsystem, such as the transfer
50 ** subsystem).
@@ -181,10 +182,11 @@
181
182 { "xfer-common-script", CONFIGSET_XFER },
183 { "xfer-push-script", CONFIGSET_XFER },
184 { "xfer-commit-script", CONFIGSET_XFER },
185 { "xfer-ticket-script", CONFIGSET_XFER },
 
186
187 };
188 static int iConfig = 0;
189
190 /*
@@ -424,11 +426,11 @@
424 }
425 checkMask &= ~thisMask;
426 }
427
428 blob_zero(&sql);
429 if( groupMask & CONFIGSET_OVERWRITE ){
430 if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
431 db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
432 configHasBeenReset |= thisMask;
433 }
434 blob_append_sql(&sql, "REPLACE INTO ");
@@ -697,10 +699,28 @@
697 }
698 }
699 db_finalize(&q);
700 return nCard;
701 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
703 /*
704 ** Identify a configuration group by name. Return its mask.
705 ** Throw an error if no match.
706 */
707
--- src/configure.c
+++ src/configure.c
@@ -41,10 +41,11 @@
41 #define CONFIGSET_SCRIBER 0x000200 /* Email subscribers */
42 #define CONFIGSET_IWIKI 0x000400 /* Interwiki codes */
43 #define CONFIGSET_ALL 0x0007ff /* Everything */
44
45 #define CONFIGSET_OVERWRITE 0x100000 /* Causes overwrite instead of merge */
46 #define CONFIGSET_PROPAGATE 0x200000 /* Propagating setting */
47
48 /*
49 ** This mask is used for the common TH1 configuration settings (i.e. those
50 ** that are not specific to one particular subsystem, such as the transfer
51 ** subsystem).
@@ -181,10 +182,11 @@
182
183 { "xfer-common-script", CONFIGSET_XFER },
184 { "xfer-push-script", CONFIGSET_XFER },
185 { "xfer-commit-script", CONFIGSET_XFER },
186 { "xfer-ticket-script", CONFIGSET_XFER },
187 { "warning-policy", CONFIGSET_PROJ | CONFIGSET_PROPAGATE },
188
189 };
190 static int iConfig = 0;
191
192 /*
@@ -424,11 +426,11 @@
426 }
427 checkMask &= ~thisMask;
428 }
429
430 blob_zero(&sql);
431 if( groupMask & CONFIGSET_OVERWRITE || thisMask & CONFIGSET_PROPAGATE ){
432 if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){
433 db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]);
434 configHasBeenReset |= thisMask;
435 }
436 blob_append_sql(&sql, "REPLACE INTO ");
@@ -697,10 +699,28 @@
699 }
700 }
701 db_finalize(&q);
702 return nCard;
703 }
704
705 /*
706 ** Send the warning-policy, writing it to pOut.
707 */
708 void configure_send_warning_policy(Blob *pOut){
709 const char *zRec;
710 zRec = db_text(0,
711 "SELECT mtime || ' ' || quote(name) || ' value ' || quote(value)"
712 " FROM config"
713 " WHERE name='warning-policy'");
714 if( zRec==0 ){
715 /* If not set, send the default value. */
716 zRec = db_text(0,
717 "SELECT now() || ' ' || quote(%Q) || ' value ' || quote(%Q)",
718 "warning-policy", db_get("warning-policy", 0));
719 }
720 blob_appendf(pOut, "config /config %d\n%s\n", strlen(zRec), zRec);
721 }
722
723 /*
724 ** Identify a configuration group by name. Return its mask.
725 ** Throw an error if no match.
726 */
727
+17 -5
--- src/db.c
+++ src/db.c
@@ -4371,10 +4371,11 @@
43714371
const char *var; /* Internal variable name used by db_set() */
43724372
int width; /* Width of display. 0 for boolean values and
43734373
** negative for values which should not appear
43744374
** on the /setup_settings page. */
43754375
char versionable; /* Is this setting versionable? */
4376
+ char propagating; /* Is this setting propagating? */
43764377
char forceTextArea; /* Force using a text area for display? */
43774378
char sensitive; /* True if this a security-sensitive setting */
43784379
const char *def; /* Default value */
43794380
};
43804381
#endif /* INTERFACE */
@@ -5016,10 +5017,16 @@
50165017
** Fossil considers any file whose size is greater than this value
50175018
** to be a "large file". Fossil might issue warnings if you try to
50185019
** "add" or "commit" a "large file". Set this value to 0 or less
50195020
** to disable all such warnings.
50205021
*/
5022
+/*
5023
+** SETTING: warning-policy width=40 block-text propagating default={}
5024
+** Policy for showing warnings under various conditions.
5025
+**
5026
+** TODO: Applying the setting. Default reflects intended JSON syntax.
5027
+*/
50215028
50225029
/*
50235030
** Look up a control setting by its name. Return a pointer to the Setting
50245031
** object, or NULL if there is no such setting.
50255032
**
@@ -5064,10 +5071,13 @@
50645071
** With a VALUE argument it changes the property for the current repository.
50655072
**
50665073
** Settings marked as versionable are overridden by the contents of the
50675074
** file named .fossil-settings/PROPERTY in the check-out root, if that
50685075
** file exists.
5076
+**
5077
+** Settings marked as propagating will be overridden if a new value is received
5078
+** when pulling from a repository.
50695079
**
50705080
** The "unset" command clears a setting.
50715081
**
50725082
** Settings can have both a "local" repository-only value and "global" value
50735083
** that applies to all repositories. The local values are stored in the
@@ -5083,10 +5093,11 @@
50835093
** --value Only show the value of a given property (implies --exact)
50845094
**
50855095
** See also: [[configuration]]
50865096
*/
50875097
void setting_cmd(void){
5098
+ static const char *aLocalOnly[] = { "manifest", "warning-policy" };
50885099
int i;
50895100
int globalFlag = find_option("global","g",0)!=0;
50905101
int exactFlag = find_option("exact",0,0)!=0;
50915102
int valueFlag = find_option("value",0,0)!=0;
50925103
/* Undocumented "--test-for-subsystem SUBSYS" option used to test
@@ -5123,12 +5134,16 @@
51235134
int n = (int)strlen(zName);
51245135
const Setting *pSetting = db_find_setting(zName, !exactFlag);
51255136
if( pSetting==0 ){
51265137
fossil_fatal("no such setting: %s", zName);
51275138
}
5128
- if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){
5129
- fossil_fatal("cannot set 'manifest' globally");
5139
+ if( globalFlag ){
5140
+ for(i=0; i<count(aLocalOnly); i++){
5141
+ if( fossil_strcmp(pSetting->name, aLocalOnly[i])==0 ){
5142
+ fossil_fatal("cannot set '%s' globally", aLocalOnly[i]);
5143
+ }
5144
+ }
51305145
}
51315146
if( unsetFlag || g.argc==4 ){
51325147
int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
51335148
if( n!=(int)strlen(pSetting[0].name) && pSetting[1].name &&
51345149
fossil_strncmp(pSetting[1].name, zName, n)==0 ){
@@ -5140,13 +5155,10 @@
51405155
blob_appendf(&x, " %s", pSetting[i].name);
51415156
}
51425157
fossil_fatal("ambiguous setting \"%s\" - might be:%s",
51435158
zName, blob_str(&x));
51445159
}
5145
- if( globalFlag && isManifest ){
5146
- fossil_fatal("cannot set 'manifest' globally");
5147
- }
51485160
if( unsetFlag ){
51495161
db_unset(pSetting->name/*works-like:"x"*/, globalFlag);
51505162
}else{
51515163
db_protect_only(PROTECT_NONE);
51525164
db_set(pSetting->name/*works-like:"x"*/, g.argv[3], globalFlag);
51535165
--- src/db.c
+++ src/db.c
@@ -4371,10 +4371,11 @@
4371 const char *var; /* Internal variable name used by db_set() */
4372 int width; /* Width of display. 0 for boolean values and
4373 ** negative for values which should not appear
4374 ** on the /setup_settings page. */
4375 char versionable; /* Is this setting versionable? */
 
4376 char forceTextArea; /* Force using a text area for display? */
4377 char sensitive; /* True if this a security-sensitive setting */
4378 const char *def; /* Default value */
4379 };
4380 #endif /* INTERFACE */
@@ -5016,10 +5017,16 @@
5016 ** Fossil considers any file whose size is greater than this value
5017 ** to be a "large file". Fossil might issue warnings if you try to
5018 ** "add" or "commit" a "large file". Set this value to 0 or less
5019 ** to disable all such warnings.
5020 */
 
 
 
 
 
 
5021
5022 /*
5023 ** Look up a control setting by its name. Return a pointer to the Setting
5024 ** object, or NULL if there is no such setting.
5025 **
@@ -5064,10 +5071,13 @@
5064 ** With a VALUE argument it changes the property for the current repository.
5065 **
5066 ** Settings marked as versionable are overridden by the contents of the
5067 ** file named .fossil-settings/PROPERTY in the check-out root, if that
5068 ** file exists.
 
 
 
5069 **
5070 ** The "unset" command clears a setting.
5071 **
5072 ** Settings can have both a "local" repository-only value and "global" value
5073 ** that applies to all repositories. The local values are stored in the
@@ -5083,10 +5093,11 @@
5083 ** --value Only show the value of a given property (implies --exact)
5084 **
5085 ** See also: [[configuration]]
5086 */
5087 void setting_cmd(void){
 
5088 int i;
5089 int globalFlag = find_option("global","g",0)!=0;
5090 int exactFlag = find_option("exact",0,0)!=0;
5091 int valueFlag = find_option("value",0,0)!=0;
5092 /* Undocumented "--test-for-subsystem SUBSYS" option used to test
@@ -5123,12 +5134,16 @@
5123 int n = (int)strlen(zName);
5124 const Setting *pSetting = db_find_setting(zName, !exactFlag);
5125 if( pSetting==0 ){
5126 fossil_fatal("no such setting: %s", zName);
5127 }
5128 if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){
5129 fossil_fatal("cannot set 'manifest' globally");
 
 
 
 
5130 }
5131 if( unsetFlag || g.argc==4 ){
5132 int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
5133 if( n!=(int)strlen(pSetting[0].name) && pSetting[1].name &&
5134 fossil_strncmp(pSetting[1].name, zName, n)==0 ){
@@ -5140,13 +5155,10 @@
5140 blob_appendf(&x, " %s", pSetting[i].name);
5141 }
5142 fossil_fatal("ambiguous setting \"%s\" - might be:%s",
5143 zName, blob_str(&x));
5144 }
5145 if( globalFlag && isManifest ){
5146 fossil_fatal("cannot set 'manifest' globally");
5147 }
5148 if( unsetFlag ){
5149 db_unset(pSetting->name/*works-like:"x"*/, globalFlag);
5150 }else{
5151 db_protect_only(PROTECT_NONE);
5152 db_set(pSetting->name/*works-like:"x"*/, g.argv[3], globalFlag);
5153
--- src/db.c
+++ src/db.c
@@ -4371,10 +4371,11 @@
4371 const char *var; /* Internal variable name used by db_set() */
4372 int width; /* Width of display. 0 for boolean values and
4373 ** negative for values which should not appear
4374 ** on the /setup_settings page. */
4375 char versionable; /* Is this setting versionable? */
4376 char propagating; /* Is this setting propagating? */
4377 char forceTextArea; /* Force using a text area for display? */
4378 char sensitive; /* True if this a security-sensitive setting */
4379 const char *def; /* Default value */
4380 };
4381 #endif /* INTERFACE */
@@ -5016,10 +5017,16 @@
5017 ** Fossil considers any file whose size is greater than this value
5018 ** to be a "large file". Fossil might issue warnings if you try to
5019 ** "add" or "commit" a "large file". Set this value to 0 or less
5020 ** to disable all such warnings.
5021 */
5022 /*
5023 ** SETTING: warning-policy width=40 block-text propagating default={}
5024 ** Policy for showing warnings under various conditions.
5025 **
5026 ** TODO: Applying the setting. Default reflects intended JSON syntax.
5027 */
5028
5029 /*
5030 ** Look up a control setting by its name. Return a pointer to the Setting
5031 ** object, or NULL if there is no such setting.
5032 **
@@ -5064,10 +5071,13 @@
5071 ** With a VALUE argument it changes the property for the current repository.
5072 **
5073 ** Settings marked as versionable are overridden by the contents of the
5074 ** file named .fossil-settings/PROPERTY in the check-out root, if that
5075 ** file exists.
5076 **
5077 ** Settings marked as propagating will be overridden if a new value is received
5078 ** when pulling from a repository.
5079 **
5080 ** The "unset" command clears a setting.
5081 **
5082 ** Settings can have both a "local" repository-only value and "global" value
5083 ** that applies to all repositories. The local values are stored in the
@@ -5083,10 +5093,11 @@
5093 ** --value Only show the value of a given property (implies --exact)
5094 **
5095 ** See also: [[configuration]]
5096 */
5097 void setting_cmd(void){
5098 static const char *aLocalOnly[] = { "manifest", "warning-policy" };
5099 int i;
5100 int globalFlag = find_option("global","g",0)!=0;
5101 int exactFlag = find_option("exact",0,0)!=0;
5102 int valueFlag = find_option("value",0,0)!=0;
5103 /* Undocumented "--test-for-subsystem SUBSYS" option used to test
@@ -5123,12 +5134,16 @@
5134 int n = (int)strlen(zName);
5135 const Setting *pSetting = db_find_setting(zName, !exactFlag);
5136 if( pSetting==0 ){
5137 fossil_fatal("no such setting: %s", zName);
5138 }
5139 if( globalFlag ){
5140 for(i=0; i<count(aLocalOnly); i++){
5141 if( fossil_strcmp(pSetting->name, aLocalOnly[i])==0 ){
5142 fossil_fatal("cannot set '%s' globally", aLocalOnly[i]);
5143 }
5144 }
5145 }
5146 if( unsetFlag || g.argc==4 ){
5147 int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
5148 if( n!=(int)strlen(pSetting[0].name) && pSetting[1].name &&
5149 fossil_strncmp(pSetting[1].name, zName, n)==0 ){
@@ -5140,13 +5155,10 @@
5155 blob_appendf(&x, " %s", pSetting[i].name);
5156 }
5157 fossil_fatal("ambiguous setting \"%s\" - might be:%s",
5158 zName, blob_str(&x));
5159 }
 
 
 
5160 if( unsetFlag ){
5161 db_unset(pSetting->name/*works-like:"x"*/, globalFlag);
5162 }else{
5163 db_protect_only(PROTECT_NONE);
5164 db_set(pSetting->name/*works-like:"x"*/, g.argv[3], globalFlag);
5165
+11 -4
--- src/dispatch.c
+++ src/dispatch.c
@@ -54,10 +54,11 @@
5454
/* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
5555
#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
5656
#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
5757
#define CMDFLAG_ALIAS 0x2000 /* Command aliases */
5858
#define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
59
+#define CMDFLAG_PROPAGATES 0x8000 /* Propagates from server to client */
5960
/**************************************************************************/
6061
6162
/* Values for the 2nd parameter to dispatch_name_search() */
6263
#define CMDFLAG_ANY 0x0038 /* Match anything */
6364
#define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -605,14 +606,16 @@
605606
}else{
606607
Blob txt;
607608
blob_init(&txt, 0, 0);
608609
help_to_text(aCommand[i].zHelp, &txt);
609610
for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
610
- fossil_print("# %s%s\n",
611
+ fossil_print("# %s%s%s\n",
611612
aCommand[bktHelp[aCommand[i].iHelp][j]].zName,
612613
(aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ?
613
- " (versionable)" : "");
614
+ " (versionable)" : "",
615
+ (aCommand[i].eCmdFlags & CMDFLAG_PROPAGATES)!=0 ?
616
+ " (propagating)" : "");
614617
}
615618
fossil_print("%s\n\n", blob_str(&txt));
616619
blob_reset(&txt);
617620
}
618621
occHelp[aCommand[i].iHelp] = 0;
@@ -1010,10 +1013,13 @@
10101013
}else{
10111014
blob_reset(&buf);
10121015
if( e & CMDFLAG_VERSIONABLE ){
10131016
blob_appendf(&buf, "versionable ");
10141017
}
1018
+ if( e & CMDFLAG_PROPAGATES ){
1019
+ blob_appendf(&buf, "propagating ");
1020
+ }
10151021
if( e & CMDFLAG_BLOCKTEXT ){
10161022
blob_appendf(&buf, "block-text ");
10171023
}
10181024
if( e & CMDFLAG_BOOLEAN ){
10191025
blob_appendf(&buf, "boolean ");
@@ -1286,13 +1292,14 @@
12861292
const Setting *pSetting = db_find_setting(pCmd->zName, 0);
12871293
char *zDflt = 0;
12881294
if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){
12891295
zDflt = mprintf(" (default: %s)", pSetting->def);
12901296
}
1291
- fossil_print("Setting: \"%s\"%s%s\n\n",
1297
+ fossil_print("Setting: \"%s\"%s%s%s\n\n",
12921298
pCmd->zName, zDflt!=0 ? zDflt : "",
1293
- (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : ""
1299
+ (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : "",
1300
+ (pCmd->eCmdFlags & CMDFLAG_PROPAGATES)!=0 ? " (propagating)" : ""
12941301
);
12951302
fossil_free(zDflt);
12961303
}
12971304
blob_init(&txt, 0, 0);
12981305
if( useHtml ){
12991306
--- src/dispatch.c
+++ src/dispatch.c
@@ -54,10 +54,11 @@
54 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
55 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
56 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
57 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
58 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
 
59 /**************************************************************************/
60
61 /* Values for the 2nd parameter to dispatch_name_search() */
62 #define CMDFLAG_ANY 0x0038 /* Match anything */
63 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -605,14 +606,16 @@
605 }else{
606 Blob txt;
607 blob_init(&txt, 0, 0);
608 help_to_text(aCommand[i].zHelp, &txt);
609 for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
610 fossil_print("# %s%s\n",
611 aCommand[bktHelp[aCommand[i].iHelp][j]].zName,
612 (aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ?
613 " (versionable)" : "");
 
 
614 }
615 fossil_print("%s\n\n", blob_str(&txt));
616 blob_reset(&txt);
617 }
618 occHelp[aCommand[i].iHelp] = 0;
@@ -1010,10 +1013,13 @@
1010 }else{
1011 blob_reset(&buf);
1012 if( e & CMDFLAG_VERSIONABLE ){
1013 blob_appendf(&buf, "versionable ");
1014 }
 
 
 
1015 if( e & CMDFLAG_BLOCKTEXT ){
1016 blob_appendf(&buf, "block-text ");
1017 }
1018 if( e & CMDFLAG_BOOLEAN ){
1019 blob_appendf(&buf, "boolean ");
@@ -1286,13 +1292,14 @@
1286 const Setting *pSetting = db_find_setting(pCmd->zName, 0);
1287 char *zDflt = 0;
1288 if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){
1289 zDflt = mprintf(" (default: %s)", pSetting->def);
1290 }
1291 fossil_print("Setting: \"%s\"%s%s\n\n",
1292 pCmd->zName, zDflt!=0 ? zDflt : "",
1293 (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : ""
 
1294 );
1295 fossil_free(zDflt);
1296 }
1297 blob_init(&txt, 0, 0);
1298 if( useHtml ){
1299
--- src/dispatch.c
+++ src/dispatch.c
@@ -54,10 +54,11 @@
54 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
55 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
56 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
57 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
58 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
59 #define CMDFLAG_PROPAGATES 0x8000 /* Propagates from server to client */
60 /**************************************************************************/
61
62 /* Values for the 2nd parameter to dispatch_name_search() */
63 #define CMDFLAG_ANY 0x0038 /* Match anything */
64 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -605,14 +606,16 @@
606 }else{
607 Blob txt;
608 blob_init(&txt, 0, 0);
609 help_to_text(aCommand[i].zHelp, &txt);
610 for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
611 fossil_print("# %s%s%s\n",
612 aCommand[bktHelp[aCommand[i].iHelp][j]].zName,
613 (aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ?
614 " (versionable)" : "",
615 (aCommand[i].eCmdFlags & CMDFLAG_PROPAGATES)!=0 ?
616 " (propagating)" : "");
617 }
618 fossil_print("%s\n\n", blob_str(&txt));
619 blob_reset(&txt);
620 }
621 occHelp[aCommand[i].iHelp] = 0;
@@ -1010,10 +1013,13 @@
1013 }else{
1014 blob_reset(&buf);
1015 if( e & CMDFLAG_VERSIONABLE ){
1016 blob_appendf(&buf, "versionable ");
1017 }
1018 if( e & CMDFLAG_PROPAGATES ){
1019 blob_appendf(&buf, "propagating ");
1020 }
1021 if( e & CMDFLAG_BLOCKTEXT ){
1022 blob_appendf(&buf, "block-text ");
1023 }
1024 if( e & CMDFLAG_BOOLEAN ){
1025 blob_appendf(&buf, "boolean ");
@@ -1286,13 +1292,14 @@
1292 const Setting *pSetting = db_find_setting(pCmd->zName, 0);
1293 char *zDflt = 0;
1294 if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){
1295 zDflt = mprintf(" (default: %s)", pSetting->def);
1296 }
1297 fossil_print("Setting: \"%s\"%s%s%s\n\n",
1298 pCmd->zName, zDflt!=0 ? zDflt : "",
1299 (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : "",
1300 (pCmd->eCmdFlags & CMDFLAG_PROPAGATES)!=0 ? " (propagating)" : ""
1301 );
1302 fossil_free(zDflt);
1303 }
1304 blob_init(&txt, 0, 0);
1305 if( useHtml ){
1306
--- src/json_config.c
+++ src/json_config.c
@@ -258,10 +258,11 @@
258258
cson_object * jSet;
259259
cson_value * pVal = 0, * pSrc = 0;
260260
jSet = cson_new_object();
261261
cson_object_set(pay, pSet->name, cson_object_value(jSet));
262262
cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable));
263
+ cson_object_set(jSet, "propagating", cson_value_new_bool(pSet->propagating));
263264
cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive));
264265
cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0])
265266
? json_new_string(pSet->def)
266267
: cson_value_null());
267268
if( 0==pSet->sensitive || 0!=g.perm.Setup ){
268269
--- src/json_config.c
+++ src/json_config.c
@@ -258,10 +258,11 @@
258 cson_object * jSet;
259 cson_value * pVal = 0, * pSrc = 0;
260 jSet = cson_new_object();
261 cson_object_set(pay, pSet->name, cson_object_value(jSet));
262 cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable));
 
263 cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive));
264 cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0])
265 ? json_new_string(pSet->def)
266 : cson_value_null());
267 if( 0==pSet->sensitive || 0!=g.perm.Setup ){
268
--- src/json_config.c
+++ src/json_config.c
@@ -258,10 +258,11 @@
258 cson_object * jSet;
259 cson_value * pVal = 0, * pSrc = 0;
260 jSet = cson_new_object();
261 cson_object_set(pay, pSet->name, cson_object_value(jSet));
262 cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable));
263 cson_object_set(jSet, "propagating", cson_value_new_bool(pSet->propagating));
264 cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive));
265 cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0])
266 ? json_new_string(pSet->def)
267 : cson_value_null());
268 if( 0==pSet->sensitive || 0!=g.perm.Setup ){
269
+10 -1
--- src/setup.c
+++ src/setup.c
@@ -962,11 +962,14 @@
962962
db_begin_transaction();
963963
@ <p>Settings marked with (v) are "versionable" and will be overridden
964964
@ by the contents of managed files named
965965
@ "<tt>.fossil-settings/</tt><i>SETTING-NAME</i>".
966966
@ If the file for a versionable setting exists, the value cannot be
967
- @ changed on this screen.</p><hr><p>
967
+ @ changed on this screen.</p>
968
+ @ <p>Settings marked with (p) are "propagating" and will be overridden
969
+ @ if a remote sends an updated setting.</p>
970
+ @ <hr><p>
968971
@
969972
@ <form action="%R/setup_settings" method="post"><div>
970973
@ <table border="0"><tr><td valign="top">
971974
login_insert_csrf_secret();
972975
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
@@ -977,10 +980,12 @@
977980
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
978981
is_truth(pSet->def), hasVersionableValue);
979982
@ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
980983
if( pSet->versionable ){
981984
@ (v)<br>
985
+ }else if( pSet->propagating ){
986
+ @ (p)<br>
982987
} else {
983988
@ <br>
984989
}
985990
}
986991
}
@@ -993,10 +998,12 @@
993998
(db_get_versioned(pSet->name, NULL)!=0);
994999
@ <tr><td>
9951000
@ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
9961001
if( pSet->versionable ){
9971002
@ (v)
1003
+ }else if( pSet->propagating ){
1004
+ @ (p)<br>
9981005
} else {
9991006
@
10001007
}
10011008
@</td><td>
10021009
entry_attribute("", /*pSet->width*/ 25, pSet->name,
@@ -1011,10 +1018,12 @@
10111018
if( pSet->width>0 && pSet->forceTextArea ){
10121019
int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
10131020
@ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
10141021
if( pSet->versionable ){
10151022
@ (v)<br>
1023
+ }else if( pSet->propagating ){
1024
+ @ (p)<br>
10161025
} else {
10171026
@ <br>
10181027
}
10191028
textarea_attribute("", /*rows*/ 2, /*cols*/ 35, pSet->name,
10201029
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
10211030
--- src/setup.c
+++ src/setup.c
@@ -962,11 +962,14 @@
962 db_begin_transaction();
963 @ <p>Settings marked with (v) are "versionable" and will be overridden
964 @ by the contents of managed files named
965 @ "<tt>.fossil-settings/</tt><i>SETTING-NAME</i>".
966 @ If the file for a versionable setting exists, the value cannot be
967 @ changed on this screen.</p><hr><p>
 
 
 
968 @
969 @ <form action="%R/setup_settings" method="post"><div>
970 @ <table border="0"><tr><td valign="top">
971 login_insert_csrf_secret();
972 for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
@@ -977,10 +980,12 @@
977 pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
978 is_truth(pSet->def), hasVersionableValue);
979 @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
980 if( pSet->versionable ){
981 @ (v)<br>
 
 
982 } else {
983 @ <br>
984 }
985 }
986 }
@@ -993,10 +998,12 @@
993 (db_get_versioned(pSet->name, NULL)!=0);
994 @ <tr><td>
995 @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
996 if( pSet->versionable ){
997 @ (v)
 
 
998 } else {
999 @
1000 }
1001 @</td><td>
1002 entry_attribute("", /*pSet->width*/ 25, pSet->name,
@@ -1011,10 +1018,12 @@
1011 if( pSet->width>0 && pSet->forceTextArea ){
1012 int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
1013 @ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
1014 if( pSet->versionable ){
1015 @ (v)<br>
 
 
1016 } else {
1017 @ <br>
1018 }
1019 textarea_attribute("", /*rows*/ 2, /*cols*/ 35, pSet->name,
1020 pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
1021
--- src/setup.c
+++ src/setup.c
@@ -962,11 +962,14 @@
962 db_begin_transaction();
963 @ <p>Settings marked with (v) are "versionable" and will be overridden
964 @ by the contents of managed files named
965 @ "<tt>.fossil-settings/</tt><i>SETTING-NAME</i>".
966 @ If the file for a versionable setting exists, the value cannot be
967 @ changed on this screen.</p>
968 @ <p>Settings marked with (p) are "propagating" and will be overridden
969 @ if a remote sends an updated setting.</p>
970 @ <hr><p>
971 @
972 @ <form action="%R/setup_settings" method="post"><div>
973 @ <table border="0"><tr><td valign="top">
974 login_insert_csrf_secret();
975 for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
@@ -977,10 +980,12 @@
980 pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
981 is_truth(pSet->def), hasVersionableValue);
982 @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
983 if( pSet->versionable ){
984 @ (v)<br>
985 }else if( pSet->propagating ){
986 @ (p)<br>
987 } else {
988 @ <br>
989 }
990 }
991 }
@@ -993,10 +998,12 @@
998 (db_get_versioned(pSet->name, NULL)!=0);
999 @ <tr><td>
1000 @ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
1001 if( pSet->versionable ){
1002 @ (v)
1003 }else if( pSet->propagating ){
1004 @ (p)<br>
1005 } else {
1006 @
1007 }
1008 @</td><td>
1009 entry_attribute("", /*pSet->width*/ 25, pSet->name,
@@ -1011,10 +1018,12 @@
1018 if( pSet->width>0 && pSet->forceTextArea ){
1019 int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
1020 @ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
1021 if( pSet->versionable ){
1022 @ (v)<br>
1023 }else if( pSet->propagating ){
1024 @ (p)<br>
1025 } else {
1026 @ <br>
1027 }
1028 textarea_attribute("", /*rows*/ 2, /*cols*/ 35, pSet->name,
1029 pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
1030
+4 -1
--- src/xfer.c
+++ src/xfer.c
@@ -1418,10 +1418,12 @@
14181418
@ error not\sauthorized\sto\sread
14191419
nErr++;
14201420
break;
14211421
}
14221422
isPull = 1;
1423
+ /* Client is pulling, so may be about to commit or merge. */
1424
+ configure_send_warning_policy(xfer.pOut);
14231425
}else{
14241426
if( !g.perm.Write ){
14251427
if( !isPull ){
14261428
cgi_reset_content();
14271429
@ error not\sauthorized\sto\swrite
@@ -2565,11 +2567,12 @@
25652567
const char *zName = blob_str(&xfer.aToken[1]);
25662568
Blob content;
25672569
blob_zero(&content);
25682570
blob_extract(xfer.pIn, size, &content);
25692571
g.perm.Admin = g.perm.RdAddr = 1;
2570
- configure_receive(zName, &content, origConfigRcvMask);
2572
+ configure_receive(zName, &content,
2573
+ origConfigRcvMask | CONFIGSET_PROPAGATE);
25712574
nCardRcvd++;
25722575
nArtifactRcvd++;
25732576
blob_reset(&content);
25742577
blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
25752578
}else
25762579
--- src/xfer.c
+++ src/xfer.c
@@ -1418,10 +1418,12 @@
1418 @ error not\sauthorized\sto\sread
1419 nErr++;
1420 break;
1421 }
1422 isPull = 1;
 
 
1423 }else{
1424 if( !g.perm.Write ){
1425 if( !isPull ){
1426 cgi_reset_content();
1427 @ error not\sauthorized\sto\swrite
@@ -2565,11 +2567,12 @@
2565 const char *zName = blob_str(&xfer.aToken[1]);
2566 Blob content;
2567 blob_zero(&content);
2568 blob_extract(xfer.pIn, size, &content);
2569 g.perm.Admin = g.perm.RdAddr = 1;
2570 configure_receive(zName, &content, origConfigRcvMask);
 
2571 nCardRcvd++;
2572 nArtifactRcvd++;
2573 blob_reset(&content);
2574 blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
2575 }else
2576
--- src/xfer.c
+++ src/xfer.c
@@ -1418,10 +1418,12 @@
1418 @ error not\sauthorized\sto\sread
1419 nErr++;
1420 break;
1421 }
1422 isPull = 1;
1423 /* Client is pulling, so may be about to commit or merge. */
1424 configure_send_warning_policy(xfer.pOut);
1425 }else{
1426 if( !g.perm.Write ){
1427 if( !isPull ){
1428 cgi_reset_content();
1429 @ error not\sauthorized\sto\swrite
@@ -2565,11 +2567,12 @@
2567 const char *zName = blob_str(&xfer.aToken[1]);
2568 Blob content;
2569 blob_zero(&content);
2570 blob_extract(xfer.pIn, size, &content);
2571 g.perm.Admin = g.perm.RdAddr = 1;
2572 configure_receive(zName, &content,
2573 origConfigRcvMask | CONFIGSET_PROPAGATE);
2574 nCardRcvd++;
2575 nArtifactRcvd++;
2576 blob_reset(&content);
2577 blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
2578 }else
2579
+5 -1
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -100,10 +100,11 @@
100100
#define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
101101
#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
102102
#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
103103
#define CMDFLAG_ALIAS 0x2000 /* Command aliases */
104104
#define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
105
+#define CMDFLAG_PROPAGATES 0x8000 /* Propagates from server to client */
105106
/**************************************************************************/
106107
107108
/*
108109
** Each entry looks like this:
109110
*/
@@ -280,10 +281,12 @@
280281
aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
281282
}else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
282283
aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
283284
}else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
284285
aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
286
+ }else if( j==11 && strncmp(&zLine[i], "propagating", 11)==0 ){
287
+ aEntry[nUsed].eType |= CMDFLAG_PROPAGATES;
285288
}else{
286289
fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
287290
zFile, nLine, j, &zLine[i]);
288291
nErr++;
289292
}
@@ -507,13 +510,14 @@
507510
if( zVar ){
508511
printf(" \"%s\",%*s", zVar, (int)(15-strlen(zVar)), "");
509512
}else{
510513
printf(" 0,%*s", 16, "");
511514
}
512
- printf(" %3d, %d, %d, %d, \"%s\"%*s },\n",
515
+ printf(" %3d, %d, %d, %d, %d, \"%s\"%*s },\n",
513516
aEntry[i].iWidth,
514517
(aEntry[i].eType & CMDFLAG_VERSIONABLE)!=0,
518
+ (aEntry[i].eType & CMDFLAG_PROPAGATES)!=0,
515519
(aEntry[i].eType & CMDFLAG_BLOCKTEXT)!=0,
516520
(aEntry[i].eType & CMDFLAG_SENSITIVE)!=0,
517521
zDef, (int)(10-strlen(zDef)), ""
518522
);
519523
if( aEntry[i].zIf ){
520524
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -100,10 +100,11 @@
100 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
101 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
102 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
103 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
104 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
 
105 /**************************************************************************/
106
107 /*
108 ** Each entry looks like this:
109 */
@@ -280,10 +281,12 @@
280 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
281 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
282 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
283 }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
284 aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
 
 
285 }else{
286 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
287 zFile, nLine, j, &zLine[i]);
288 nErr++;
289 }
@@ -507,13 +510,14 @@
507 if( zVar ){
508 printf(" \"%s\",%*s", zVar, (int)(15-strlen(zVar)), "");
509 }else{
510 printf(" 0,%*s", 16, "");
511 }
512 printf(" %3d, %d, %d, %d, \"%s\"%*s },\n",
513 aEntry[i].iWidth,
514 (aEntry[i].eType & CMDFLAG_VERSIONABLE)!=0,
 
515 (aEntry[i].eType & CMDFLAG_BLOCKTEXT)!=0,
516 (aEntry[i].eType & CMDFLAG_SENSITIVE)!=0,
517 zDef, (int)(10-strlen(zDef)), ""
518 );
519 if( aEntry[i].zIf ){
520
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -100,10 +100,11 @@
100 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
101 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
102 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
103 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
104 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
105 #define CMDFLAG_PROPAGATES 0x8000 /* Propagates from server to client */
106 /**************************************************************************/
107
108 /*
109 ** Each entry looks like this:
110 */
@@ -280,10 +281,12 @@
281 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
282 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
283 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
284 }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
285 aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
286 }else if( j==11 && strncmp(&zLine[i], "propagating", 11)==0 ){
287 aEntry[nUsed].eType |= CMDFLAG_PROPAGATES;
288 }else{
289 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
290 zFile, nLine, j, &zLine[i]);
291 nErr++;
292 }
@@ -507,13 +510,14 @@
510 if( zVar ){
511 printf(" \"%s\",%*s", zVar, (int)(15-strlen(zVar)), "");
512 }else{
513 printf(" 0,%*s", 16, "");
514 }
515 printf(" %3d, %d, %d, %d, %d, \"%s\"%*s },\n",
516 aEntry[i].iWidth,
517 (aEntry[i].eType & CMDFLAG_VERSIONABLE)!=0,
518 (aEntry[i].eType & CMDFLAG_PROPAGATES)!=0,
519 (aEntry[i].eType & CMDFLAG_BLOCKTEXT)!=0,
520 (aEntry[i].eType & CMDFLAG_SENSITIVE)!=0,
521 zDef, (int)(10-strlen(zDef)), ""
522 );
523 if( aEntry[i].zIf ){
524

Keyboard Shortcuts

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