| 1 | = Upcoming breaking changes |
| 2 | |
| 3 | The Git project aims to ensure backwards compatibility to the best extent |
| 4 | possible. Minor releases will not break backwards compatibility unless there is |
| 5 | a very strong reason to do so, like for example a security vulnerability. |
| 6 | |
| 7 | Regardless of that, due to the age of the Git project, it is only natural to |
| 8 | accumulate a backlog of backwards-incompatible changes that will eventually be |
| 9 | required to keep the project aligned with a changing world. These changes fall |
| 10 | into several categories: |
| 11 | |
| 12 | * Changes to long established defaults. |
| 13 | * Concepts that have been replaced with a superior design. |
| 14 | * Concepts, commands, configuration or options that have been lacking in major |
| 15 | ways and that cannot be fixed and which will thus be removed without any |
| 16 | replacement. |
| 17 | |
| 18 | Explicitly not included in this list are fixes to minor bugs that may cause a |
| 19 | change in user-visible behavior. |
| 20 | |
| 21 | The Git project irregularly releases breaking versions that deliberately break |
| 22 | backwards compatibility with older versions. This is done to ensure that Git |
| 23 | remains relevant, safe and maintainable going forward. The release cadence of |
| 24 | breaking versions is typically measured in multiple years. We had the following |
| 25 | major breaking releases in the past: |
| 26 | |
| 27 | * Git 1.6.0, released in August 2008. |
| 28 | * Git 2.0, released in May 2014. |
| 29 | |
| 30 | We use <major>.<minor> release numbers these days, starting from Git 2.0. For |
| 31 | future releases, our plan is to increment <major> in the release number when we |
| 32 | make the next breaking release. Before Git 2.0, the release numbers were |
| 33 | 1.<major>.<minor> with the intention to increment <major> for "usual" breaking |
| 34 | releases, reserving the jump to Git 2.0 for really large backward-compatibility |
| 35 | breaking changes. |
| 36 | |
| 37 | The intent of this document is to track upcoming deprecations for future |
| 38 | breaking releases. Furthermore, this document also tracks what will _not_ be |
| 39 | deprecated. This is done such that the outcome of discussions document both |
| 40 | when the discussion favors deprecation, but also when it rejects a deprecation. |
| 41 | |
| 42 | Items should have a clear summary of the reasons why we do or do not want to |
| 43 | make the described change that can be easily understood without having to read |
| 44 | the mailing list discussions. If there are alternatives to the changed feature, |
| 45 | those alternatives should be pointed out to our users. |
| 46 | |
| 47 | All items should be accompanied by references to relevant mailing list threads |
| 48 | where the deprecation was discussed. These references use message-IDs, which |
| 49 | can visited via |
| 50 | |
| 51 | https://lore.kernel.org/git/$message_id/ |
| 52 | |
| 53 | to see the message and its surrounding discussion. Such a reference is there to |
| 54 | make it easier for you to find how the project reached consensus on the |
| 55 | described item back then. |
| 56 | |
| 57 | This is a living document as the environment surrounding the project changes |
| 58 | over time. If circumstances change, an earlier decision to deprecate or change |
| 59 | something may need to be revisited from time to time. So do not take items on |
| 60 | this list to mean "it is settled, do not waste our time bringing it up again". |
| 61 | |
| 62 | == Procedure |
| 63 | |
| 64 | Discussing the desire to make breaking changes, declaring that breaking |
| 65 | changes are made at a certain version boundary, and recording these |
| 66 | decisions in this document, are necessary but not sufficient. |
| 67 | Because such changes are expected to be numerous, and the design and |
| 68 | implementation of them are expected to span over time, they have to |
| 69 | be deployable trivially at such a version boundary, prepared over long |
| 70 | time. |
| 71 | |
| 72 | The breaking changes MUST be guarded with the a compile-time switch, |
| 73 | WITH_BREAKING_CHANGES, to help this process. When built with it, |
| 74 | the resulting Git binary together with its documentation would |
| 75 | behave as if these breaking changes slated for the next big version |
| 76 | boundary are already in effect. We also have a CI job to exercise |
| 77 | the work-in-progress version of Git with these breaking changes. |
| 78 | |
| 79 | |
| 80 | == Git 3.0 |
| 81 | |
| 82 | The following subsections document upcoming breaking changes for Git 3.0. There |
| 83 | is no planned release date for this breaking version yet. |
| 84 | |
| 85 | Proposed changes and removals only include items which are "ready" to be done. |
| 86 | In other words, this is not supposed to be a wishlist of features that should |
| 87 | be changed to or replaced in case the alternative was implemented already. |
| 88 | |
| 89 | === Changes |
| 90 | |
| 91 | * The default hash function for new repositories will be changed from "sha1" |
| 92 | to "sha256". SHA-1 has been deprecated by NIST in 2011 and is nowadays |
| 93 | recommended against in FIPS 140-2 and similar certifications. Furthermore, |
| 94 | there are practical attacks on SHA-1 that weaken its cryptographic properties: |
| 95 | + |
| 96 | ** The SHAppening (2015). The first demonstration of a practical attack |
| 97 | against SHA-1 with 2^57 operations. |
| 98 | ** SHAttered (2017). Generation of two valid PDF files with 2^63 operations. |
| 99 | ** Birthday-Near-Collision (2019). This attack allows for chosen prefix |
| 100 | attacks with 2^68 operations. |
| 101 | ** Shambles (2020). This attack allows for chosen prefix attacks with 2^63 |
| 102 | operations. |
| 103 | + |
| 104 | While we have protections in place against known attacks, it is expected |
| 105 | that more attacks against SHA-1 will be found by future research. Paired |
| 106 | with the ever-growing capability of hardware, it is only a matter of time |
| 107 | before SHA-1 will be considered broken completely. We want to be prepared |
| 108 | and will thus change the default hash algorithm to "sha256" for newly |
| 109 | initialized repositories. |
| 110 | + |
| 111 | An important requirement for this change is that the ecosystem is ready to |
| 112 | support the "sha256" object format. This includes popular Git libraries, |
| 113 | applications and forges. |
| 114 | + |
| 115 | There is no plan to deprecate the "sha1" object format at this point in time. |
| 116 | + |
| 117 | Cf. <2f5de416-04ba-c23d-1e0b-83bb655829a7@zombino.com>, |
| 118 | <20170223155046.e7nxivfwqqoprsqj@LykOS.localdomain>, |
| 119 | <CA+EOSBncr=4a4d8n9xS4FNehyebpmX8JiUwCsXD47EQDE+DiUQ@mail.gmail.com>. |
| 120 | |
| 121 | * The default storage format for references in newly created repositories will |
| 122 | be changed from "files" to "reftable". The "reftable" format provides |
| 123 | multiple advantages over the "files" format: |
| 124 | + |
| 125 | ** It is impossible to store two references that only differ in casing on |
| 126 | case-insensitive filesystems with the "files" format. This issue is common |
| 127 | on Windows and macOS platforms. As the "reftable" backend does not use |
| 128 | filesystem paths to encode reference names this problem goes away. |
| 129 | ** Similarly, macOS normalizes path names that contain unicode characters, |
| 130 | which has the consequence that you cannot store two names with unicode |
| 131 | characters that are encoded differently with the "files" backend. Again, |
| 132 | this is not an issue with the "reftable" backend. |
| 133 | ** Deleting references with the "files" backend requires Git to rewrite the |
| 134 | complete "packed-refs" file. In large repositories with many references |
| 135 | this file can easily be dozens of megabytes in size, in extreme cases it |
| 136 | may be gigabytes. The "reftable" backend uses tombstone markers for |
| 137 | deleted references and thus does not have to rewrite all of its data. |
| 138 | ** Repository housekeeping with the "files" backend typically performs |
| 139 | all-into-one repacks of references. This can be quite expensive, and |
| 140 | consequently housekeeping is a tradeoff between the number of loose |
| 141 | references that accumulate and slow down operations that read references, |
| 142 | and compressing those loose references into the "packed-refs" file. The |
| 143 | "reftable" backend uses geometric compaction after every write, which |
| 144 | amortizes costs and ensures that the backend is always in a |
| 145 | well-maintained state. |
| 146 | ** Operations that write multiple references at once are not atomic with the |
| 147 | "files" backend. Consequently, Git may see in-between states when it reads |
| 148 | references while a reference transaction is in the process of being |
| 149 | committed to disk. |
| 150 | ** Writing many references at once is slow with the "files" backend because |
| 151 | every reference is created as a separate file. The "reftable" backend |
| 152 | significantly outperforms the "files" backend by multiple orders of |
| 153 | magnitude. |
| 154 | ** The reftable backend uses a binary format with prefix compression for |
| 155 | reference names. As a result, the format uses less space compared to the |
| 156 | "packed-refs" file. |
| 157 | + |
| 158 | Users that get immediate benefit from the "reftable" backend could continue to |
| 159 | opt-in to the "reftable" format manually by setting the "init.defaultRefFormat" |
| 160 | config. But defaults matter, and we think that overall users will have a better |
| 161 | experience with less platform-specific quirks when they use the new backend by |
| 162 | default. |
| 163 | + |
| 164 | A prerequisite for this change is that the ecosystem is ready to support the |
| 165 | "reftable" format. Most importantly, alternative implementations of Git like |
| 166 | JGit, libgit2 and Gitoxide need to support it. |
| 167 | |
| 168 | * In new repositories, the default branch name will be `main`. We have been |
| 169 | warning that the default name will change since 675704c74dd (init: |
| 170 | provide useful advice about init.defaultBranch, 2020-12-11). The new name |
| 171 | matches the default branch name used in new repositories by many of the |
| 172 | big Git forges. |
| 173 | |
| 174 | * Git will require Rust as a mandatory part of the build process. While Git |
| 175 | already started to adopt Rust in Git 2.49, all parts written in Rust are |
| 176 | optional for the time being. This includes: |
| 177 | + |
| 178 | ** The Rust wrapper around libgit.a that is part of "contrib/" and which has |
| 179 | been introduced in Git 2.49. |
| 180 | ** Subsystems that have an alternative implementation in Rust to test |
| 181 | interoperability between our C and Rust codebase. |
| 182 | ** Newly written features that are not mission critical for a fully functional |
| 183 | Git client. |
| 184 | + |
| 185 | These changes are meant as test balloons to allow distributors of Git to prepare |
| 186 | for Rust becoming a mandatory part of the build process. There will be multiple |
| 187 | milestones for the introduction of Rust: |
| 188 | + |
| 189 | -- |
| 190 | 1. Initially, with Git 2.52, support for Rust will be auto-detected by Meson and |
| 191 | disabled in our Makefile so that the project can sort out the initial |
| 192 | infrastructure. |
| 193 | 2. In Git 2.55, both build systems will default-enable support for Rust. |
| 194 | Consequently, builds will break by default if Rust is not available on the |
| 195 | build host. The use of Rust can still be explicitly disabled via build |
| 196 | flags. |
| 197 | 3. In Git 3.0, the build options will be removed and support for Rust is |
| 198 | mandatory. |
| 199 | -- |
| 200 | + |
| 201 | You can explicitly ask both Meson and our Makefile-based system to enable Rust |
| 202 | by saying `meson configure -Drust=enabled` and `make WITH_RUST=YesPlease`, |
| 203 | respectively. |
| 204 | + |
| 205 | The Git project will declare the last version before Git 3.0 to be a long-term |
| 206 | support release. This long-term release will receive important bug fixes for at |
| 207 | least four release cycles and security fixes for six release cycles. The Git |
| 208 | project will hand over maintainership of the long-term release to distributors |
| 209 | in case they need to extend the life of that long-term release even further. |
| 210 | Details of how this long-term release will be handed over to the community will |
| 211 | be discussed once the Git project decides to stop officially supporting it. |
| 212 | + |
| 213 | We will evaluate the impact on downstream distributions before making Rust |
| 214 | mandatory in Git 3.0. If we see that the impact on downstream distributions |
| 215 | would be significant, we may decide to defer this change to a subsequent minor |
| 216 | release. This evaluation will also take into account our own experience with |
| 217 | how painful it is to keep Rust an optional component. |
| 218 | |
| 219 | * The default value of `safe.bareRepository` will change from `all` to |
| 220 | `explicit`. It is all too easy for an attacker to trick a user into cloning a |
| 221 | repository that contains an embedded bare repository with malicious hooks |
| 222 | configured. If the user enters that subdirectory and runs any Git command, Git |
| 223 | discovers the bare repository and the hooks fire. The user does not even need |
| 224 | to run a Git command explicitly: many shell prompts run `git status` in the |
| 225 | background to display branch and dirty state information, and `git status` in |
| 226 | turn may invoke the fsmonitor hook if so configured, making the user |
| 227 | vulnerable the moment they `cd` into the directory. The `safe.bareRepository` |
| 228 | configuration variable was introduced in 8959555cee (setup_git_directory(): |
| 229 | add an owner check for the top-level directory, 2022-03-02) with a default of |
| 230 | `all` to preserve backwards compatibility. |
| 231 | + |
| 232 | Changing the default to `explicit` means that Git will refuse to work with bare |
| 233 | repositories that are discovered implicitly by walking up the directory tree. |
| 234 | Bare repositories specified explicitly via the `--git-dir` command-line option |
| 235 | or the `GIT_DIR` environment variable continue to work regardless of this |
| 236 | setting. Repositories that look like a `.git` directory, a worktree, or a |
| 237 | submodule directory are also unaffected. |
| 238 | + |
| 239 | Users who rely on implicit discovery of bare repositories can restore the |
| 240 | previous behavior by setting `safe.bareRepository=all` in their global or |
| 241 | system configuration. |
| 242 | |
| 243 | === Removals |
| 244 | |
| 245 | * Support for grafting commits has long been superseded by git-replace(1). |
| 246 | Grafts are inferior to replacement refs: |
| 247 | + |
| 248 | ** Grafts are a local-only mechanism and cannot be shared across |
| 249 | repositories. |
| 250 | ** Grafts can lead to hard-to-diagnose problems when transferring objects |
| 251 | between repositories. |
| 252 | + |
| 253 | The grafting mechanism has been marked as outdated since e650d0643b (docs: mark |
| 254 | info/grafts as outdated, 2014-03-05) and will be removed. |
| 255 | + |
| 256 | Cf. <20140304174806.GA11561@sigill.intra.peff.net>. |
| 257 | |
| 258 | * The git-pack-redundant(1) command can be used to remove redundant pack files. |
| 259 | The subcommand is unusably slow and the reason why nobody reports it as a |
| 260 | performance bug is suspected to be the absence of users. We have nominated |
| 261 | the command for removal and have started to emit a user-visible warning in |
| 262 | c3b58472be (pack-redundant: gauge the usage before proposing its removal, |
| 263 | 2020-08-25) whenever the command is executed. |
| 264 | + |
| 265 | So far there was a single complaint about somebody still using the command, but |
| 266 | that complaint did not cause us to reverse course. On the contrary, we have |
| 267 | doubled down on the deprecation and starting with 4406522b76 (pack-redundant: |
| 268 | escalate deprecation warning to an error, 2023-03-23), the command dies unless |
| 269 | the user passes the `--i-still-use-this` option. |
| 270 | + |
| 271 | There have not been any subsequent complaints, so this command will finally be |
| 272 | removed. |
| 273 | + |
| 274 | Cf. <xmqq1rjuz6n3.fsf_-_@gitster.c.googlers.com>, |
| 275 | <CAKvOHKAFXQwt4D8yUCCkf_TQL79mYaJ=KAKhtpDNTvHJFuX1NA@mail.gmail.com>, |
| 276 | <20230323204047.GA9290@coredump.intra.peff.net>, |
| 277 | |
| 278 | * Support for storing shorthands for remote URLs in "$GIT_COMMON_DIR/branches/" |
| 279 | and "$GIT_COMMON_DIR/remotes/" has been long superseded by storing remotes in |
| 280 | the repository configuration. |
| 281 | + |
| 282 | The mechanism has originally been introduced in f170e4b39d ([PATCH] fetch/pull: |
| 283 | short-hand notation for remote repositories., 2005-07-16) and was superseded by |
| 284 | 6687f8fea2 ([PATCH] Use .git/remote/origin, not .git/branches/origin., |
| 285 | 2005-08-20), where we switched from ".git/branches/" to ".git/remotes/". That |
| 286 | commit already mentions an upcoming deprecation of the ".git/branches/" |
| 287 | directory, and starting with a1d4aa7424 (Add repository-layout document., |
| 288 | 2005-09-01) we have also marked this layout as deprecated. Eventually we also |
| 289 | started to migrate away from ".git/remotes/" in favor of config-based remotes, |
| 290 | and we have marked the directory as legacy in 3d3d282146 (Documentation: |
| 291 | Grammar correction, wording fixes and cleanup, 2011-08-23) |
| 292 | + |
| 293 | As our documentation mentions, these directories are unlikely to be used in |
| 294 | modern repositories and most users aren't even aware of these mechanisms. They |
| 295 | have been deprecated for almost 20 years and 14 years respectively, and we are |
| 296 | not aware of any active users that have complained about this deprecation. |
| 297 | Furthermore, the ".git/branches/" directory is nowadays misleadingly named and |
| 298 | may cause confusion as "branches" are almost exclusively used in the context of |
| 299 | references. |
| 300 | + |
| 301 | These features will be removed. |
| 302 | |
| 303 | * Support for "--stdin" option in the "name-rev" command was |
| 304 | deprecated (and hidden from the documentation) in the Git 2.40 |
| 305 | timeframe, in preference to its synonym "--annotate-stdin". Git 3.0 |
| 306 | removes the support for "--stdin" altogether. |
| 307 | |
| 308 | * The git-whatchanged(1) command has outlived its usefulness more than |
| 309 | 10 years ago, and takes more keystrokes to type than its rough |
| 310 | equivalent `git log --raw`. We have nominated the command for |
| 311 | removal, have changed the command to refuse to work unless the |
| 312 | `--i-still-use-this` option is given, and asked the users to report |
| 313 | when they do so. |
| 314 | + |
| 315 | The command will be removed. |
| 316 | |
| 317 | * Support for `core.commentString=auto` has been deprecated and will |
| 318 | be removed in Git 3.0. |
| 319 | + |
| 320 | cf. <xmqqa59i45wc.fsf@gitster.g> |
| 321 | |
| 322 | * Support for `core.preferSymlinkRefs=true` has been deprecated and will be |
| 323 | removed in Git 3.0. Writing symbolic refs as symbolic links will be phased |
| 324 | out in favor of using plain files using the textual representation of |
| 325 | symbolic refs. |
| 326 | + |
| 327 | Symbolic references were initially always stored as a symbolic link. This was |
| 328 | changed in 9b143c6e15 (Teach update-ref about a symbolic ref stored in a |
| 329 | textfile., 2005-09-25), where a new textual symref format was introduced to |
| 330 | store those symbolic refs in a plain file. In 9f0bb90d16 |
| 331 | (core.prefersymlinkrefs: use symlinks for .git/HEAD, 2006-05-02), the Git |
| 332 | project switched the default to use the textual symrefs in favor of symbolic |
| 333 | links. |
| 334 | + |
| 335 | The migration away from symbolic links has happened almost 20 years ago by now, |
| 336 | and there is no known reason why one should prefer them nowadays. Furthermore, |
| 337 | symbolic links are not supported on some platforms. |
| 338 | + |
| 339 | Note that only the writing side for such symbolic links is deprecated. Reading |
| 340 | such symbolic links is still supported for now. |
| 341 | |
| 342 | == Superseded features that will not be deprecated |
| 343 | |
| 344 | Some features have gained newer replacements that aim to improve the design in |
| 345 | certain ways. The fact that there is a replacement does not automatically mean |
| 346 | that the old way of doing things will eventually be removed. This section tracks |
| 347 | those features with newer alternatives. |
| 348 | |
| 349 | * The features git-checkout(1) offers are covered by the pair of commands |
| 350 | git-restore(1) and git-switch(1). Because the use of git-checkout(1) is still |
| 351 | widespread, and it is not expected that this will change anytime soon, all |
| 352 | three commands will stay. |
| 353 | + |
| 354 | This decision may get revisited in case we ever figure out that there are |
| 355 | almost no users of any of the commands anymore. |
| 356 | + |
| 357 | Cf. <xmqqttjazwwa.fsf@gitster.g>, |
| 358 | <xmqqleeubork.fsf@gitster.g>, |
| 359 | <112b6568912a6de6672bf5592c3a718e@manjaro.org>. |