@@ -1247,6 +1247,143 @@ static const char *get_super_prefix_or_empty(void)
1247
1247
return s ;
1248
1248
}
1249
1249
1250
+ static int submodule_has_dirty_index (const struct submodule * sub )
1251
+ {
1252
+ struct child_process cp = CHILD_PROCESS_INIT ;
1253
+
1254
+ prepare_submodule_repo_env_no_git_dir (& cp .env_array );
1255
+
1256
+ cp .git_cmd = 1 ;
1257
+ argv_array_pushl (& cp .args , "diff-index" , "--quiet" ,
1258
+ "--cached" , "HEAD" , NULL );
1259
+ cp .no_stdin = 1 ;
1260
+ cp .no_stdout = 1 ;
1261
+ cp .dir = sub -> path ;
1262
+ if (start_command (& cp ))
1263
+ die ("could not recurse into submodule '%s'" , sub -> path );
1264
+
1265
+ return finish_command (& cp );
1266
+ }
1267
+
1268
+ static void submodule_reset_index (const char * path )
1269
+ {
1270
+ struct child_process cp = CHILD_PROCESS_INIT ;
1271
+ prepare_submodule_repo_env_no_git_dir (& cp .env_array );
1272
+
1273
+ cp .git_cmd = 1 ;
1274
+ cp .no_stdin = 1 ;
1275
+ cp .dir = path ;
1276
+
1277
+ argv_array_pushf (& cp .args , "--super-prefix=%s%s/" ,
1278
+ get_super_prefix_or_empty (), path );
1279
+ argv_array_pushl (& cp .args , "read-tree" , "-u" , "--reset" , NULL );
1280
+
1281
+ argv_array_push (& cp .args , EMPTY_TREE_SHA1_HEX );
1282
+
1283
+ if (run_command (& cp ))
1284
+ die ("could not reset submodule index" );
1285
+ }
1286
+
1287
+ /**
1288
+ * Moves a submodule at a given path from a given head to another new head.
1289
+ * For edge cases (a submodule coming into existence or removing a submodule)
1290
+ * pass NULL for old or new respectively.
1291
+ */
1292
+ int submodule_move_head (const char * path ,
1293
+ const char * old ,
1294
+ const char * new ,
1295
+ unsigned flags )
1296
+ {
1297
+ int ret = 0 ;
1298
+ struct child_process cp = CHILD_PROCESS_INIT ;
1299
+ const struct submodule * sub ;
1300
+
1301
+ sub = submodule_from_path (null_sha1 , path );
1302
+
1303
+ if (!sub )
1304
+ die ("BUG: could not get submodule information for '%s'" , path );
1305
+
1306
+ if (old && !(flags & SUBMODULE_MOVE_HEAD_FORCE )) {
1307
+ /* Check if the submodule has a dirty index. */
1308
+ if (submodule_has_dirty_index (sub ))
1309
+ return error (_ ("submodule '%s' has dirty index" ), path );
1310
+ }
1311
+
1312
+ if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN )) {
1313
+ if (old ) {
1314
+ if (!submodule_uses_gitfile (path ))
1315
+ absorb_git_dir_into_superproject ("" , path ,
1316
+ ABSORB_GITDIR_RECURSE_SUBMODULES );
1317
+ } else {
1318
+ struct strbuf sb = STRBUF_INIT ;
1319
+ strbuf_addf (& sb , "%s/modules/%s" ,
1320
+ get_git_common_dir (), sub -> name );
1321
+ connect_work_tree_and_git_dir (path , sb .buf );
1322
+ strbuf_release (& sb );
1323
+
1324
+ /* make sure the index is clean as well */
1325
+ submodule_reset_index (path );
1326
+ }
1327
+ }
1328
+
1329
+ prepare_submodule_repo_env_no_git_dir (& cp .env_array );
1330
+
1331
+ cp .git_cmd = 1 ;
1332
+ cp .no_stdin = 1 ;
1333
+ cp .dir = path ;
1334
+
1335
+ argv_array_pushf (& cp .args , "--super-prefix=%s%s/" ,
1336
+ get_super_prefix_or_empty (), path );
1337
+ argv_array_pushl (& cp .args , "read-tree" , NULL );
1338
+
1339
+ if (flags & SUBMODULE_MOVE_HEAD_DRY_RUN )
1340
+ argv_array_push (& cp .args , "-n" );
1341
+ else
1342
+ argv_array_push (& cp .args , "-u" );
1343
+
1344
+ if (flags & SUBMODULE_MOVE_HEAD_FORCE )
1345
+ argv_array_push (& cp .args , "--reset" );
1346
+ else
1347
+ argv_array_push (& cp .args , "-m" );
1348
+
1349
+ argv_array_push (& cp .args , old ? old : EMPTY_TREE_SHA1_HEX );
1350
+ argv_array_push (& cp .args , new ? new : EMPTY_TREE_SHA1_HEX );
1351
+
1352
+ if (run_command (& cp )) {
1353
+ ret = -1 ;
1354
+ goto out ;
1355
+ }
1356
+
1357
+ if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN )) {
1358
+ if (new ) {
1359
+ struct child_process cp1 = CHILD_PROCESS_INIT ;
1360
+ /* also set the HEAD accordingly */
1361
+ cp1 .git_cmd = 1 ;
1362
+ cp1 .no_stdin = 1 ;
1363
+ cp1 .dir = path ;
1364
+
1365
+ argv_array_pushl (& cp1 .args , "update-ref" , "HEAD" ,
1366
+ new ? new : EMPTY_TREE_SHA1_HEX , NULL );
1367
+
1368
+ if (run_command (& cp1 )) {
1369
+ ret = -1 ;
1370
+ goto out ;
1371
+ }
1372
+ } else {
1373
+ struct strbuf sb = STRBUF_INIT ;
1374
+
1375
+ strbuf_addf (& sb , "%s/.git" , path );
1376
+ unlink_or_warn (sb .buf );
1377
+ strbuf_release (& sb );
1378
+
1379
+ if (is_empty_dir (path ))
1380
+ rmdir_or_warn (path );
1381
+ }
1382
+ }
1383
+ out :
1384
+ return ret ;
1385
+ }
1386
+
1250
1387
static int find_first_merges (struct object_array * result , const char * path ,
1251
1388
struct commit * a , struct commit * b )
1252
1389
{
0 commit comments