git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "SZEDER Gábor" <szeder.dev@gmail.com>
To: Matt Roper <matthew.d.roper@intel.com>
Cc: git@vger.kernel.org
Subject: Re: [BUG REPORT] split-index behavior during interactive rebase
Date: Sun, 26 Sep 2021 23:57:03 +0200	[thread overview]
Message-ID: <20210926215703.GB3311029@szeder.dev> (raw)
In-Reply-To: <20210916055057.GT3389343@mdroper-desk1.amr.corp.intel.com>

On Wed, Sep 15, 2021 at 10:50:57PM -0700, Matt Roper wrote:
> What did you do before the bug happened? (Steps to reproduce your issue)
> 
>   I activated split index mode on a repo ("git config core.splitIndex
>   true"), performed an interactive rebase, modified a commit earlier in
>   the history.
> 
>   The steps can be reproduced via a sequence of:
>       $ mkdir tmp && cd tmp && git init
>       $ git config core.splitIndex true
>       $ for x in `seq 20`; do echo $x >> count; git add count; git commit -m "Commit $x"; done

It's important to note that this test repository has only a single
tracked file in it.

>       $ git rebase -i HEAD~10
>       
>       ## Add "x git commit --amend --no-edit" as the first command of
>       ## the todo list.
> 
> What did you expect to happen? (Expected behavior)
> 
>   My expectation was that there would still only be a single shared index
>   file in the .git directory upon completion of the rebase.
> 
> What happened instead? (Actual behavior)
> 
>   A large number of distinct sharedindex.* files were generated in the .git
>   directory during the rebase.

I think this works as intended.

A new shared index is written when the number of index entries that
would be writen to '.git/index' is higher than a given percentage of
the total number of index entries.  This percentage can be specified
with the 'splitIndex.maxPercentChange' configuration variable and it
defaults to 20%.  In your test repository above there is only a single
file and it is modified in every commit, so when switching from one
commit to the other 100% of the index entries would be written to
'.git/index', resulting in a new shared index file written for each
rebase step.

> What's different between what you expected and what actually happened?
> 
>   Rather than a single shared index file, I wound up with a huge number of
>   large shared index files.  The real repository I was working with (a Linux
>   kernel source tree) had a shared index file size of about 7MB, and I was
>   modifying a commit several hundred back in history (in case it
>   matters, these were all linear commits, no merges), so the resulting
>   collection of shared index files consumed a surprising amount of disk
>   space.

The last commit in my somewhat outdated linux repo contains ~71k
files, the 20% of that is ~14k.  Does that linear string of "several
hundred" commits modify that many files?

> Anything else you want to add:
> 
>   As an experiment, I tried setting splitIndex.sharedIndexExpire=now

I would advise against that, it's potentially dangerous, because it
can remove shared index files that are still in use by other git
processes.

>   to see
>   if it would avoid the explosion of shared index files, but it appears the
>   stale index files are still not being removed during the rebase, and I
>   still wind up with a huge number at the end of the rebase.  If I manually
>   run "git update-index --split-index" after the rebase completes it will
>   properly delete all of the stale ones at that point.
> 
>   Rebases that do not actually modify the history do _not_ trigger the
>   explosion of shared index files (e.g., "git rebase -i HEAD~10 --exec 'echo
>   foo'").
> 
>   If I do not set the core.splitIndex setting on the repository, but only
>   activate split index manually via "git update-index --split-index" there
>   is only one shared index file at the end of the rebase, but based on the
>   file size it appears the repository is no longer operating in split index
>   mode.
> 
>   Before:
>   $ ll .git | grep index
>   -rw-rw-r--   1 mdroper mdroper   149165 Sep 15 22:21 index
>   -rw-rw-r--   1 mdroper mdroper  7296080 Sep 15 22:21 sharedindex.f916dd59ccc22ca34298f557a4659aca2767dae4
> 
>   After (just amending HEAD~1 in this case):
>   $ ls -l .git | grep index
>   -rw-rw-r--   1 mdroper mdroper  7445145 Sep 15 22:22 index
>   -rw-rw-r--   1 mdroper mdroper  7296080 Sep 15 22:22 sharedindex.f916dd59ccc22ca34298f557a4659aca2767dae4

> git version 2.33.0

I could reproduce all this with v2.33.0 (except that I saw the split
index being turned off even with core.splitIndex enabled), but was
unable to do so with current master.

I think that this is a bug in the interaction between the split index
feature and 'git rebase' when using the recursive merge strategy and
when a couple of other, more subtle conditions are met.  It seems that
with the right conditions rebase only writes regular index files, and
by not entering the split index code paths it doesn't look for old
shared index files to expire.

After v2.33.0 we switched the default merge strategy from recursive to
'ort', and with that these cases appear to work as intended, i.e. old
shared index files are expired and the split index feature doesn't get
turned off.  Since the 'ort' strategy is in many ways better (faster,
more correct, etc.) than the recursive, I don't think it's worth the
effort to try to fix this issue with split index, rebase and the
recursive strategy.


  parent reply	other threads:[~2021-09-26 21:57 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-16  5:50 [BUG REPORT] split-index behavior during interactive rebase Matt Roper
2021-09-21  7:34 ` Lucas De Marchi
2021-09-26 21:57 ` SZEDER Gábor [this message]
2021-09-27  2:17   ` Matt Roper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210926215703.GB3311029@szeder.dev \
    --to=szeder.dev@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=matthew.d.roper@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).