update-index: use the bulk-checkin infrastructure

The update-index functionality is used internally by 'git stash push' to setup the internal stashed commit. This change enables odb-transactions for update-index infrastructure to speed up adding new objects to the object database by leveraging the batch fsync functionality. There is some risk with this change, since under batch fsync, the object files will be in a tmp-objdir until update-index is complete, so callers using the --stdin option will not see them until update-index is done. This risk is mitigated by flushing the ODB transaction prior to reporting any verbose output so that objects will be visible to callers that are synchronizing with update-index by snooping its output. Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Neeraj Singh committed Apr 4, 2022 at 22:20 UTC 23a3a303ab9bfec2321ac4d1ae9f4df279f3a20c
1 file changed +20
builtin/update-index.c
+20
@@ -5,6 +5,7 @@
5 */
6 #define USE_THE_INDEX_COMPATIBILITY_MACROS
7 #include "cache.h"
8 +#include "bulk-checkin.h"
9 #include "config.h"
10 #include "lockfile.h"
11 #include "quote.h"
@@ -57,6 +58,14 @@ static void report(const char *fmt, ...)
58 if (!verbose)
59 return;
60
61 + /*
62 + * It is possible, though unlikely, that a caller could use the verbose
63 + * output to synchronize with addition of objects to the object
64 + * database. The current implementation of ODB transactions leaves
65 + * objects invisible while a transaction is active, so flush the
66 + * transaction here before reporting a change made by update-index.
67 + */
68 + flush_odb_transaction();
69 va_start(vp, fmt);
70 vprintf(fmt, vp);
71 putchar('\n');
@@ -1116,6 +1125,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
1125 */
1126 parse_options_start(&ctx, argc, argv, prefix,
1127 options, PARSE_OPT_STOP_AT_NON_OPTION);
1128 +
1129 + /*
1130 + * Allow the object layer to optimize adding multiple objects in
1131 + * a batch.
1132 + */
1133 + begin_odb_transaction();
1134 while (ctx.argc) {
1135 if (parseopt_state != PARSE_OPT_DONE)
1136 parseopt_state = parse_options_step(&ctx, options,
@@ -1190,6 +1205,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
1205 strbuf_release(&buf);
1206 }
1207
1208 + /*
1209 + * By now we have added all of the new objects
1210 + */
1211 + end_odb_transaction();
1212 +
1213 if (split_index > 0) {
1214 if (git_config_get_split_index() == 0)
1215 warning(_("core.splitIndex is set to false; "