]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'js/split-index-fixes'
authorJunio C Hamano <gitster@pobox.com>
Tue, 4 Apr 2023 21:28:27 +0000 (14:28 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 4 Apr 2023 21:28:27 +0000 (14:28 -0700)
The index files can become corrupt under certain conditions when
the split-index feature is in use, especially together with
fsmonitor, which have been corrected.

* js/split-index-fixes:
  unpack-trees: take care to propagate the split-index flag
  fsmonitor: avoid overriding `cache_changed` bits
  split-index; stop abusing the `base_oid` to strip the "link" extension
  split-index & fsmonitor: demonstrate a bug

1  2 
read-cache.c
t/t7527-builtin-fsmonitor.sh
unpack-trees.c

diff --cc read-cache.c
Simple merge
index 4c0327b2bb27af53e24b4158a63f6d2aec9ae19e,9fab9a2ab3883d3f7bf6c168ff279f78e00e678f..0c241d6c148d7b5ebc9a9b3aaf44723fb1028e8b
@@@ -991,8 -999,45 +991,45 @@@ test_expect_success !UNICODE_COMPOSITIO
        # We assume UNICODE_NFD_PRESERVED.
        # We should have seen explicit NFD from OS.
        # We should have synthesized an NFC event.
 -      egrep "^event: nfd/d_${utf8_nfd}/?$" ./unicode.trace &&
 -      egrep "^event: nfd/d_${utf8_nfc}/?$" ./unicode.trace
 +      grep -E "^event: nfd/d_${utf8_nfd}/?$" ./unicode.trace &&
 +      grep -E "^event: nfd/d_${utf8_nfc}/?$" ./unicode.trace
  '
  
+ test_expect_success 'split-index and FSMonitor work well together' '
+       git init split-index &&
+       test_when_finished "git -C \"$PWD/split-index\" \
+               fsmonitor--daemon stop" &&
+       (
+               cd split-index &&
+               git config core.splitIndex true &&
+               # force split-index in most cases
+               git config splitIndex.maxPercentChange 99 &&
+               git config core.fsmonitor true &&
+               # Create the following commit topology:
+               #
+               # *   merge three
+               # |\
+               # | * three
+               # * | merge two
+               # |\|
+               # | * two
+               # * | one
+               # |/
+               # * 5a5efd7 initial
+               test_commit initial &&
+               test_commit two &&
+               test_commit three &&
+               git reset --hard initial &&
+               test_commit one &&
+               test_tick &&
+               git merge two &&
+               test_tick &&
+               git merge three &&
+               git rebase --force-rebase -r one
+       )
+ '
  test_done
diff --cc unpack-trees.c
index a75fb9f05b4775e8135436a8f915b1a310cad5b6,ca5e47c77c01313104bc3d79ba6c12bde285ceae..09d96f8ba1ae57183060fff196cb7896f8ec5bbe
@@@ -1921,23 -1911,24 +1921,25 @@@ int unpack_trees(unsigned len, struct t
        } else if (o->src_index == o->dst_index) {
                /*
                 * o->dst_index (and thus o->src_index) will be discarded
 -               * and overwritten with o->result at the end of this function,
 -               * so just use src_index's split_index to avoid having to
 -               * create a new one.
 +               * and overwritten with o->internal.result at the end of
 +               * this function, so just use src_index's split_index to
 +               * avoid having to create a new one.
                 */
 -              o->result.split_index = o->src_index->split_index;
 +              o->internal.result.split_index = o->src_index->split_index;
+               if (o->src_index->cache_changed & SPLIT_INDEX_ORDERED)
 -                      o->result.cache_changed |= SPLIT_INDEX_ORDERED;
 -              o->result.split_index->refcount++;
++                      o->internal.result.cache_changed |= SPLIT_INDEX_ORDERED;
 +              o->internal.result.split_index->refcount++;
        } else {
 -              o->result.split_index = init_split_index(&o->result);
 +              o->internal.result.split_index =
 +                      init_split_index(&o->internal.result);
        }
 -      oidcpy(&o->result.oid, &o->src_index->oid);
 -      o->merge_size = len;
 +      oidcpy(&o->internal.result.oid, &o->src_index->oid);
 +      o->internal.merge_size = len;
        mark_all_ce_unused(o->src_index);
  
 -      o->result.fsmonitor_last_update =
 +      o->internal.result.fsmonitor_last_update =
                xstrdup_or_null(o->src_index->fsmonitor_last_update);
 -      o->result.fsmonitor_has_run_once = o->src_index->fsmonitor_has_run_once;
 +      o->internal.result.fsmonitor_has_run_once = o->src_index->fsmonitor_has_run_once;
  
        if (!o->src_index->initialized &&
            !repo->settings.command_requires_full_index &&