[ACCEPTED]-what are the different repository format versions (for the core.repositoryFormatVersion setting) in git?-rcs

Accepted answer
Score: 30

It's for future compatibility -- if the 11 git developers ever find it necessary to 10 change the way that repos are stored on 9 disk to enable some new feature, then they 8 can make upgraded repos have a core.repositoryformatversion of 1. Then 7 newer versions of git that know about that 6 new format will trigger the code to deal 5 with it, and older versions of git that 4 don't will gracefully error with "Expected git repo version <= 0, found 1. Please upgrade Git".

As of 3 now, the only repo format version defined 2 or recognized is 0, which denotes the format 1 that every public release of git has used.

Score: 17

git 2.7 (Nov. 2015) adds a lot more information 180 in the new Documentation/technical/repository-version.txt.
See commit 067fbd4, commit 00a09d5 (23 Jun 2015) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit fa46579, 26 Oct 2015)

You 179 now can define "extensions", and 178 use core.repositoryformatversion as a "marker" to signal the 177 existence of said extensions, instead of 176 having to bump the Git version number itself:

If 175 we were to bump the repository version for 174 every such change, then any implementation 173 understanding version X would also have to 172 understand X-1, X-2, and so forth, even though 171 the incompatibilities may be in orthogonal 170 parts of the system, and there is otherwise 169 no reason we cannot implement one without 168 the other (or more importantly, that the 167 user cannot choose to use one feature without 166 the other, weighing the tradeoff in compatibility 165 only for that particular feature).

This patch 164 documents the existing repositoryformatversion strategy and introduces a new format, "1", which lets a repository specify that it must run with an arbitrary set of extensions.

Extracts from the doc:

Every git repository 163 is marked with a numeric version in the core.repositoryformatversion key 162 of its config file. This version specifies the 161 rules for operating on the on-disk repository 160 data.

Note that this applies only to accessing 159 the repository's disk contents directly.
An 158 older client which understands only format 157 0 may still connect via git:// to a repository 156 using format 1, as long as the server process 155 understands format 1.

Version 0

This is the format defined 154 by the initial version of git, including 153 but not limited to the format of the repository 152 directory, the repository configuration 151 file, and the object and ref storage.

Version 1

This 150 format is identical to version 0, with the 149 following exceptions:

  1. When reading the core.repositoryformatversion variable, a git implementation which supports version 1 MUST also read any configuration keys found in the extensions section of the configuration file.
  1. If a version-1 repository specifies any extensions.* keys that the running git has not implemented, the operation MUST NOT proceed. Similarly, if the value of any known key is not understood by the implementation, the operation MUST NOT proceed.

This can be used, for 148 example:

  • to inform git that the objects should not be pruned based only on the reachability of the ref tips (e.g, because it has "clone --shared" children)
  • that the refs are stored in a format besides the usual "refs" and "packed-refs" directories

Now that is really an original approach 147 to all the release version number policy and its semver policy.

Because we bump to 146 format "1", and because format 145 "1" requires that a running git 144 knows about any extensions mentioned, we 143 know that older versions of the code will 142 not do something dangerous when confronted 141 with these new formats.

For example, if the 140 user chooses to use database storage for 139 refs, they may set the "extensions.refbackend" config 138 to "db".
Older versions of git 137 will not understand format "1" and 136 bail.
Versions of git which understand "1" but 135 do not know about "refbackend", or 134 which know about "refbackend" but 133 not about the "db" backend, will 132 refuse to run.
This is annoying, of course, but 131 much better than the alternative of claiming 130 that there are no refs in the repository, or 129 writing to a location that other implementations 128 will not read.

Note that we are only defining 127 the rules for format 1 here.
We do not ever 126 write format 1 ourselves; it is a tool that is meant to be used by users and future extensions to provide safety with older implementations.


As a first extension, you 125 will have with git 2.7 preciousObjects:

If this extension 124 is used in a repository, then no operations 123 should run which may drop objects from the 122 object storage. This can be useful if you 121 are sharing that storage with other repositories 120 whose refs you cannot see.

The doc mentions:

When 119 the config key extensions.preciousObjects is set to true, objects in the 118 repository MUST NOT be deleted (e.g., by 117 git-prune or git repack -d).

That is:

For instance, if you do:

$ git clone -s parent child
$ git -C parent config extensions.preciousObjects true
$ git -C parent config core.repositoryformatversion 1

you 116 now have additional safety when running 115 git in the parent repository.
Prunes and 114 repacks will bail with an error, and git gc will 113 skip those operations (it will continue 112 to pack refs and do other non-object operations).
Older 111 versions of git, when run in the repository, will 110 fail on every operation.

Note that we do 109 not set the preciousObjects extension by default when doing 108 a "clone -s", as doing so breaks backwards 107 compatibility. It is a decision the user 106 should make explicitly.


Note that this core.repositoryformatversion business 105 is old. Really old. commit ab9cb76, Nov. 2005, Git 0.99.9l.
It was done initially for the db version:

This makes 104 init-db repository version aware.

It checks if an 103 existing config file says the repository 102 being reinitialized is of a wrong version 101 and aborts before doing further harm.


Git 100 2.22 (Q2 2019) will avoid leaks around the repository_format structure.

See 99 commit e8805af (28 Feb 2019), and commit 1301997 (22 Jan 2019) by Martin Ågren (``).
(Merged by Junio C Hamano -- gitster -- in commit 6b5688b, 20 Mar 2019)

setup: fix memory leaks with struct repository_format

After 98 we set up a struct repository_format, it owns various pieces of allocated 97 memory. We then either use those members, because 96 we decide we want to use the "candidate" repository 95 format, or we discard the candidate / scratch 94 space.
In the first case, we transfer ownership 93 of the memory to a few global variables. In 92 the latter case, we just silently drop the 91 struct and end up leaking memory.

Introduce 90 an initialization macro REPOSITORY_FORMAT_INIT and a function 89 clear_repository_format(), to be used on each side of read_repository_format(). To have a 88 clear and simple memory ownership, let all 87 users of struct repository_format duplicate the strings that they 86 take from it, rather than stealing the pointers.

Call 85 clear_...() at the start of read_...() instead of just zeroing the 84 struct, since we sometimes enter the function 83 multiple times.
Thus, it is important to 82 initialize the struct before calling read_...(), so document 81 that.
It's also important because we might 80 not even call read_...() before we call clear_...(), see, e.g., builtin/init-db.c.

Teach 79 read_...() to clear the struct on error, so that it 78 is reset to a safe state, and document this. (In 77 setup_git_directory_gently(), we look at repo_fmt.hash_algo even if repo_fmt.version is -1, which we weren't 76 actually supposed to do per the API. After 75 this commit, that's ok.)


With Git 2.28 (Q3 74 2020), the runtime itself can upgrade the 73 repository format version automatically, for 72 example on an unshallow fetch.

See commit 14c7fa2, commit 98564d8, commit 01bbbbd, commit 16af5f1 (05 71 Jun 2020) by Xin Li (livid).
(Merged by Junio C Hamano -- gitster -- in commit 1033b98, 29 Jun 2020)

fetch: allow adding a filter after initial clone

Signed-off-by: Xin Li

Retroactively adding a filter 70 can be useful for existing shallow clones 69 as they allow users to see earlier change 68 histories without downloading all git objects 67 in a regular --unshallow fetch.

Without this patch, users 66 can make a clone partial by editing the 65 repository configuration to convert the 64 remote into a promisor, like:

git config core.repositoryFormatVersion 1
git config extensions.partialClone origin   
git fetch --unshallow --filter=blob:none origin

Since the hard 63 part of making this work is already in place 62 and such edits can be error-prone, teach 61 Git to perform the required configuration 60 change automatically instead.

Note that this 59 change does not modify the existing Git 58 behavior which recognizes setting extensions.partialClone without 57 changing repositoryFormatVersion.


Warning: In 2.28-rc0, we corrected 56 a bug that some repository extensions are 55 honored by mistake even in a version 0 repositories 54 (these configuration variables in extensions.* namespace 53 were supposed to have special meaning in 52 repositories whose version numbers are 1 51 or higher), but this was a bit too big a 50 change.

See commit 62f2eca, commit 1166419 (15 Jul 2020) by Jonathan Nieder (artagnon).
(Merged by Junio C Hamano -- gitster -- in commit d13b7f2, 16 Jul 2020)

Revert "check_repository_format_gently(): refuse extensions for old repositories"

Reported-by: Johannes Schindelin
Signed-off-by: Jonathan Nieder

This reverts 49 commit 14c7fa269e42df4133edd9ae7763b678ed6594cd.

The core.repositoryFormatVersion field was introduced in ab9cb76f661 ("Repository 48 format version check.", 2005-11-25, Git 47 v0.99.9l -- merge), providing a welcome bit of 46 forward compatibility, thanks to some welcome 45 analysis by Martin Atukunda.

The semantics 44 are simple: a repository with core.repositoryFormatVersion set to 0 43 should be comprehensible by all Git implementations 42 in active use; and Git implementations should 41 error out early instead of trying to act 40 on Git repositories with higher core.repositoryFormatVersion values 39 representing new formats that they do not 38 understand.

A new repository format did not 37 need to be defined until 00a09d57eb8 (introduce "extensions" form 36 of core.repositoryformatversion, 2015-06-23).

This provided a finer-grained 35 extension mechanism for Git repositories.

In 34 a repository with core.repositoryFormatVersion set to 1, Git implementations 33 can act on "extensions.*" settings 32 that modify how a repository is interpreted.

In 31 repository format version 1, unrecognized 30 extensions settings cause Git to error out.

What 29 happens if a user sets an extension setting 28 but forgets to increase the repository format 27 version to 1?
The extension settings were 26 still recognized in that case; worse, unrecognized 25 extensions settings do not cause Git to error 24 out.

So combining repository format version 23 0 with extensions settings produces in some 22 sense the worst of both worlds.

To improve 21 that situation, since 14c7fa269e4 (check_repository_format_gently(): refuse extensions 20 for old repositories, 2020-06-05) Git instead 19 ignores extensions in v0 mode. This way, v0 18 repositories get the historical (pre-2015) behavior 17 and maintain compatibility with Git implementations 16 that do not know about the v1 format.

Unfortunately, users 15 had been using this sort of configuration 14 and this behavior change came to many as 13 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 14c7fa269e4 might 12 be a good behavior if we were traveling 11 back in time to 2015, but we're far too 10 late.

For some reason I thought that it was 9 what had been originally implemented and 8 that it had regressed.

Apologies for not 7 doing my research when 14c7fa269e4 was under development.

Let's 6 return to the behavior we've had since 2015: always 5 act on extensions.* settings, regardless 4 of repository format version.

While we're 3 here, include some tests to describe the 2 effect on the "upgrade repository version" code 1 path.

[*] https://github.com/google/copybara/commit/ca76c0b1e13c4e36448d12c2aba4a5d9d98fb6e7

More Related questions