10
10
static int inside_git_dir = -1 ;
11
11
static int inside_work_tree = -1 ;
12
12
static int work_tree_config_is_bogus ;
13
+ enum discovery_bare_config {
14
+ DISCOVERY_BARE_UNKNOWN = -1 ,
15
+ DISCOVERY_BARE_NEVER = 0 ,
16
+ DISCOVERY_BARE_ALWAYS ,
17
+ DISCOVERY_BARE_CWD ,
18
+ };
19
+ static enum discovery_bare_config discovery_bare_config =
20
+ DISCOVERY_BARE_UNKNOWN ;
13
21
14
22
static struct startup_info the_startup_info ;
15
23
struct startup_info * startup_info = & the_startup_info ;
@@ -1142,6 +1150,60 @@ static int ensure_valid_ownership(const char *path)
1142
1150
return data .is_safe ;
1143
1151
}
1144
1152
1153
+ static int discovery_bare_cb (const char * key , const char * value , void * d )
1154
+ {
1155
+ if (strcmp (key , "discovery.bare" ))
1156
+ return 0 ;
1157
+
1158
+ if (!strcmp (value , "never" )) {
1159
+ discovery_bare_config = DISCOVERY_BARE_NEVER ;
1160
+ return 0 ;
1161
+ }
1162
+ if (!strcmp (value , "always" )) {
1163
+ discovery_bare_config = DISCOVERY_BARE_ALWAYS ;
1164
+ return 0 ;
1165
+ }
1166
+ if (!strcmp (value , "cwd" )) {
1167
+ discovery_bare_config = DISCOVERY_BARE_CWD ;
1168
+ return 0 ;
1169
+ }
1170
+ return -1 ;
1171
+ }
1172
+
1173
+ static int check_bare_repo_allowed (const char * cwd , const char * path )
1174
+ {
1175
+ if (discovery_bare_config == DISCOVERY_BARE_UNKNOWN ) {
1176
+ read_very_early_config (discovery_bare_cb , NULL );
1177
+ /* We didn't find a value; use the default. */
1178
+ if (discovery_bare_config == DISCOVERY_BARE_UNKNOWN )
1179
+ discovery_bare_config = DISCOVERY_BARE_ALWAYS ;
1180
+ }
1181
+ switch (discovery_bare_config ) {
1182
+ case DISCOVERY_BARE_NEVER :
1183
+ return 0 ;
1184
+ case DISCOVERY_BARE_ALWAYS :
1185
+ return 1 ;
1186
+ case DISCOVERY_BARE_CWD :
1187
+ return !strcmp (cwd , path );
1188
+ default :
1189
+ BUG ("invalid discovery_bare_config %d" , discovery_bare_config );
1190
+ }
1191
+ }
1192
+
1193
+ static const char * discovery_bare_config_to_string (void )
1194
+ {
1195
+ switch (discovery_bare_config ) {
1196
+ case DISCOVERY_BARE_NEVER :
1197
+ return "never" ;
1198
+ case DISCOVERY_BARE_ALWAYS :
1199
+ return "always" ;
1200
+ case DISCOVERY_BARE_CWD :
1201
+ return "cwd" ;
1202
+ default :
1203
+ BUG ("invalid discovery_bare_config %d" , discovery_bare_config );
1204
+ }
1205
+ }
1206
+
1145
1207
enum discovery_result {
1146
1208
GIT_DIR_NONE = 0 ,
1147
1209
GIT_DIR_EXPLICIT ,
@@ -1151,7 +1213,8 @@ enum discovery_result {
1151
1213
GIT_DIR_HIT_CEILING = -1 ,
1152
1214
GIT_DIR_HIT_MOUNT_POINT = -2 ,
1153
1215
GIT_DIR_INVALID_GITFILE = -3 ,
1154
- GIT_DIR_INVALID_OWNERSHIP = -4
1216
+ GIT_DIR_INVALID_OWNERSHIP = -4 ,
1217
+ GIT_DIR_DISALLOWED_BARE = -5
1155
1218
};
1156
1219
1157
1220
/*
@@ -1167,7 +1230,8 @@ enum discovery_result {
1167
1230
* the discovered .git/ directory, if any. If `gitdir` is not absolute, it
1168
1231
* is relative to `dir` (i.e. *not* necessarily the cwd).
1169
1232
*/
1170
- static enum discovery_result setup_git_directory_gently_1 (struct strbuf * dir ,
1233
+ static enum discovery_result setup_git_directory_gently_1 (struct strbuf * cwd ,
1234
+ struct strbuf * dir ,
1171
1235
struct strbuf * gitdir ,
1172
1236
int die_on_error )
1173
1237
{
@@ -1248,6 +1312,8 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
1248
1312
}
1249
1313
1250
1314
if (is_git_directory (dir -> buf )) {
1315
+ if (!check_bare_repo_allowed (cwd -> buf , dir -> buf ))
1316
+ return GIT_DIR_DISALLOWED_BARE ;
1251
1317
if (!ensure_valid_ownership (dir -> buf ))
1252
1318
return GIT_DIR_INVALID_OWNERSHIP ;
1253
1319
strbuf_addstr (gitdir , "." );
@@ -1272,16 +1338,18 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
1272
1338
int discover_git_directory (struct strbuf * commondir ,
1273
1339
struct strbuf * gitdir )
1274
1340
{
1275
- struct strbuf dir = STRBUF_INIT , err = STRBUF_INIT ;
1341
+ struct strbuf cwd = STRBUF_INIT , dir = STRBUF_INIT , err = STRBUF_INIT ;
1276
1342
size_t gitdir_offset = gitdir -> len , cwd_len ;
1277
1343
size_t commondir_offset = commondir -> len ;
1278
1344
struct repository_format candidate = REPOSITORY_FORMAT_INIT ;
1279
1345
1280
- if (strbuf_getcwd (& dir ))
1346
+ if (strbuf_getcwd (& cwd ))
1281
1347
return -1 ;
1348
+ strbuf_addbuf (& dir , & cwd );
1282
1349
1283
1350
cwd_len = dir .len ;
1284
- if (setup_git_directory_gently_1 (& dir , gitdir , 0 ) <= 0 ) {
1351
+ if (setup_git_directory_gently_1 (& cwd , & dir , gitdir , 0 ) <= 0 ) {
1352
+ strbuf_release (& cwd );
1285
1353
strbuf_release (& dir );
1286
1354
return -1 ;
1287
1355
}
@@ -1304,6 +1372,7 @@ int discover_git_directory(struct strbuf *commondir,
1304
1372
strbuf_reset (& dir );
1305
1373
strbuf_addf (& dir , "%s/config" , commondir -> buf + commondir_offset );
1306
1374
read_repository_format (& candidate , dir .buf );
1375
+ strbuf_release (& cwd );
1307
1376
strbuf_release (& dir );
1308
1377
1309
1378
if (verify_repository_format (& candidate , & err ) < 0 ) {
@@ -1353,7 +1422,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
1353
1422
die_errno (_ ("Unable to read current working directory" ));
1354
1423
strbuf_addbuf (& dir , & cwd );
1355
1424
1356
- switch (setup_git_directory_gently_1 (& dir , & gitdir , 1 )) {
1425
+ switch (setup_git_directory_gently_1 (& cwd , & dir , & gitdir , 1 )) {
1357
1426
case GIT_DIR_EXPLICIT :
1358
1427
prefix = setup_explicit_git_dir (gitdir .buf , & cwd , & repo_fmt , nongit_ok );
1359
1428
break ;
@@ -1394,6 +1463,14 @@ const char *setup_git_directory_gently(int *nongit_ok)
1394
1463
}
1395
1464
* nongit_ok = 1 ;
1396
1465
break ;
1466
+ case GIT_DIR_DISALLOWED_BARE :
1467
+ if (!nongit_ok ) {
1468
+ die (_ ("cannot use bare repository '%s' (discovery.bare is '%s')" ),
1469
+ dir .buf ,
1470
+ discovery_bare_config_to_string ());
1471
+ }
1472
+ * nongit_ok = 1 ;
1473
+ break ;
1397
1474
case GIT_DIR_NONE :
1398
1475
/*
1399
1476
* As a safeguard against setup_git_directory_gently_1 returning
0 commit comments