Skip to content

Commit

Permalink
Revert "check_repository_format_gently(): refuse extensions for old r…
Browse files Browse the repository at this point in the history
…epositories"

This reverts commit 14c7fa2.

The core.repositoryFormatVersion field was introduced in ab9cb76
(Repository format version check., 2005-11-25), providing a welcome
bit of forward compatibility, thanks to some welcome analysis by
Martin Atukunda.  The semantics are simple: a repository with
core.repositoryFormatVersion set to 0 should be comprehensible by all
Git implementations in active use; and Git implementations should
error out early instead of trying to act on Git repositories with
higher core.repositoryFormatVersion values representing new formats
that they do not understand.

A new repository format did not need to be defined until 00a09d5
(introduce "extensions" form of core.repositoryformatversion,
2015-06-23).  This provided a finer-grained extension mechanism for
Git repositories.  In a repository with core.repositoryFormatVersion
set to 1, Git implementations can act on "extensions.*" settings that
modify how a repository is interpreted.  In repository format version
1, unrecognized extensions settings cause Git to error out.

What happens if a user sets an extension setting but forgets to
increase the repository format version to 1?  The extension settings
were still recognized in that case; worse, unrecognized extensions
settings do *not* cause Git to error out.  So combining repository
format version 0 with extensions settings produces in some sense the
worst of both worlds.

To improve that situation, since 14c7fa2
(check_repository_format_gently(): refuse extensions for old
repositories, 2020-06-05) Git instead ignores extensions in v0 mode.
This way, v0 repositories get the historical (pre-2015) behavior and
maintain compatibility with Git implementations that do not know about
the v1 format.  Unfortunately, users had been using this sort of
configuration and this behavior change came to many as a surprise:

- users of "git config --worktree" that had followed its advice
  to enable extensions.worktreeConfig (without also increasing the
  repository format version) would find their worktree configuration
  no longer taking effect

- tools such as copybara[*] that had set extensions.partialClone in
  existing repositories (without also increasing the repository format
  version) would find that setting no longer taking effect

The behavior introduced in 14c7fa2 might be a good behavior if we
were traveling back in time to 2015, but we're far too late.  For some
reason I thought that it was what had been originally implemented and
that it had regressed.  Apologies for not doing my research when
14c7fa2 was under development.

Let's return to the behavior we've had since 2015: always act on
extensions.* settings, regardless of repository format version.  While
we're here, include some tests to describe the effect on the "upgrade
repository version" code path.

[*] google/copybara@ca76c0b

Reported-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
jrn authored and gitster committed Jul 16, 2020
1 parent 14c7fa2 commit 1166419
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
12 changes: 3 additions & 9 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,15 +507,9 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
die("%s", err.buf);
}

if (candidate->version >= 1) {
repository_format_precious_objects = candidate->precious_objects;
set_repository_format_partial_clone(candidate->partial_clone);
repository_format_worktree_config = candidate->worktree_config;
} else {
repository_format_precious_objects = 0;
set_repository_format_partial_clone(NULL);
repository_format_worktree_config = 0;
}
repository_format_precious_objects = candidate->precious_objects;
set_repository_format_partial_clone(candidate->partial_clone);
repository_format_worktree_config = candidate->worktree_config;
string_list_clear(&candidate->unknown_extensions, 0);

if (repository_format_worktree_config) {
Expand Down
15 changes: 13 additions & 2 deletions t/t0410-partial-clone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,25 @@ test_expect_success 'convert shallow clone to partial clone' '
test_cmp_config -C client 1 core.repositoryformatversion
'

test_expect_success 'convert shallow clone to partial clone must fail with any extension' '
test_expect_success 'converting to partial clone fails with noop extension' '
rm -fr server client &&
test_create_repo server &&
test_commit -C server my_commit 1 &&
test_commit -C server my_commit2 1 &&
git clone --depth=1 "file://$(pwd)/server" client &&
test_cmp_config -C client 0 core.repositoryformatversion &&
git -C client config extensions.partialclone origin &&
git -C client config extensions.noop true &&
test_must_fail git -C client fetch --unshallow --filter="blob:none"
'

test_expect_success 'converting to partial clone fails with unrecognized extension' '
rm -fr server client &&
test_create_repo server &&
test_commit -C server my_commit 1 &&
test_commit -C server my_commit2 1 &&
git clone --depth=1 "file://$(pwd)/server" client &&
test_cmp_config -C client 0 core.repositoryformatversion &&
git -C client config extensions.nonsense true &&
test_must_fail git -C client fetch --unshallow --filter="blob:none"
'

Expand Down

0 comments on commit 1166419

Please sign in to comment.