Basically, the idea is to attribute a new kind of ID to an initial 'change'. During review, or whenever a commit is rebased, the change ID is kept, whereas the commit of course changes. This allows tooling to identify all previous versions of a change, and is what enables "per-commit" code review à la Gerrit [2] (which IMO is a much better experience than the branch-review-squash model that GitHub normalized). It's also used in jj, although I'm not familiar with that.
As of today, any tool that wants a change ID needs to somehow encode it in commit message bodies. The proposed discussion was about making a change ID a standard header field that git would natively keep across rebases.
[1] https://lore.kernel.org/git/Z_OGMb-1oV0Ex05e@pks.im/T/#mf941...
[2] https://gerrit-review.googlesource.com/Documentation/user-ch...
I doubt that core Git will adopt it anytime soon as it was not discussed at this years contributor summit (last week) and doesn't seem to be a hot topic on the ML.
What I would like to see is support for `git rebase` not dropping it, which is the current main issue. The `git replay` command, as well as commands based on the same sequencing code (`git history` for example) do not drop custom headers like this, so there is partial non-breakage, but several of the other history editing commands do drop custom headers.
For example, if GitHub is down, that would not be a blocker to access review comments or to do reviews. And maybe you could push your reviews to a GitLab mirror if you want a UI.
Surely you mean when GitHub is down.
As an aside, I thought it a bit worrisome that the move to Sha256 is apparently delayed due to GitHub dragging their feet on this.
It's a bit more convenient if you prefer referring to a non-leaf commit directly rather than relative to the leaf branch a la master~2
Yes, you do need to do that. However, there is also much more work after that.
Git will not intermingle SHA-256 and SHA-1 enabled repositories, even in things like submodules, so anything used in that manner will need to keep both versions into the indefinite future. If you rely on a submodule that has not yet converted, you will have to convert it yourself and try to keep it up to date, or the forge will have to automatically keep a bidirectional mirror (if you have submodules in various forges, you'll have to wait for all of them to do it), etc.
This means that every SHA referenced anywhere on the internet, in commit messages, in issues, in code comments is now invalid and needs a mapping to find the rewritten one for forever.
It also means that every commit signature ever made is now invalid and will probably have to be stripped from the rewritten new 256 history because it's impossible to resign everything.
Companies like Google and GitHub are working on keeping two versions of each repository so that there can be long stages of ecosystem migrations, but no matter what, it's going to be a huge pain for millions of developers for years to come.
Quite a generous offer!
</aside>
Looking forward to losing all references at once vs just the current one...
I've noticed persistent Git/fs interaction where on crash the current ref can just disappear...
All those problems just go away when branches are no longer files on disk.
I enabled it in setup script of one large repo I maintain; the main issue is the incompatibility with some people's personal tooling based on libgit2 (some git status tooling in oh-my-zsh), but people do find workarounds.
What about future attacks by quantum computers? Is Git safe from quantum computers for it's all hashes only? Or shall there be issues with quantum attacks?
I'm asking for there are several projects that are already moving to quantum-resistant schemes (like OpenSSH who uses an hybrid scheme [1]).
And sha256 is in private preview at GitHub: https://github.com/bk2204/talk-rust-in-git/blob/dev/presenta...
[dead]
[dead]
I wouldn't agree with all of those reasons, but it's very definitely not "just for the sake of it." One of the better reasons so many people look to writing some things in Rust is that we now have pretty ample evidence than trying to write a binary file format parser in C is a cornucopia of CVEs that are just simply absent in Rust, and the excuse of "well, but a sufficiently smart programmer doesn't write bugs in C" doesn't cut it anymore.
Good, are there (m)any other plans to ditch the slow files and use proper database? Or is it only reserved for various post-git competitors?
The filesystem is a proper database, just not a relational one.
Linus focused heavily on performance when he wrote git; he used the filesystem because, as the main Linux kernel maintainer, he knew that the Linux VFS and filesystems were fast enough for these use cases.
(It's the use cases that have changed; it was not expected back then to have more than a few hundred refs in a single repository.)
They allow for example to identify all the clones of a commit and they allow to give stable identities across rebases eg suppose you rebase a typo at the beginning of a feature branch without change ids a reviewer sees n new unrelated commits while with change ids it is possible to clearly identify which commits where changed/added/removed since the previous review iteration.
A rebase can introduce change to a commit in cases such as handling conflicts or squashing.
Also, a commit already retains it's commit message after rebasing.
and with change ids you can quickly separate commits that changed from commit that did not.
> Also, a commit already retains it's commit message after rebasing.
but commit message are not ids, there is no command for checking out a commit by its message, nor any sense that commit with the same message are somehow functionally related
[deleted]
If you never rewrite history, you could achieve something similar, but it precludes you from having a “tidy” branch.
Whether or not you’re into rewriting history is a different discussion that has been hashed out over and over again.
If you treat a branch as your unit of review, then it becomes super difficult for someone to submit a chain of related changes. You'll be constantly rebasing your pull requests onto each other as you get feedback from dependent branches.
I heard that the github CLI recently introduced support for this, but since in git there's no concept of dependent branches (a branch isn't even an object in git, just a reference to a commit), I think this approach will always be clunkier than reviewing commits related by a change ID.
What's wrong with branches?
Tools and scripts will have to be migrated of course, but I'm the brave new world of agentic coding it shouldn't be too hard.
The main pain is providing user support to developers who are curiously not very tech/OS savvy (has anyone else noticed this phenomenon?)
Failing that, have a kind of git object that wraps another and says hey this is in sha1 don't mess with it
[0] Migration document: https://git-scm.com/docs/hash-function-transition
But the article helps. Basically Grover’s is not as potent as Shorr’s. And it seems like everyone is convinced there is no dramatically better quantum algorithm than Grover’s?
Grover's assumes the function is a black box that you cannot look inside and that your only way of finding a certain result is through repeated invocation.
Under this assumption, Grover's is optimal in the number of invocations of the function required to find the result.
However, this assumption may be quite wrong for AES and friends. It may be the structure allows for non brute force attacks that are totally impractical classically but not subject to Grover's optimality limitation quantumly.
The only thing you are guaranteed here is that if you cannot take advantage of structure at all then Grover's is the best you can do.
Given that we have pretty much always found a way to take some advantage of structure, I would bet we will do so here.
That may or may not make it viable to break at all, I just wouldn't bet that it must be treated like a black box forever.
To me that would be a very bad bet.
And, if I’m following you, that’s the key difference in Grover’s and Shorr’s: Shorr’s takes advantage of structure?
I'll explain it without going too far into why any of this is true, which is much more complicated to prove. This will let me use relatively simple math.
Let's say you want to factor N. Pick some number that is coprime to N, which we'll call a, and consider f(x) = a^x (mod N).
Since it's a modular function, it repeats at some point. Shor calculates the period of this function (r), rather than seeing which of the 2^n numbers is "the answer".
Once you know the period of this function, there is a high chance that the factors fall out of gcd(a^(r/2) - 1, N) and gcd(a^(r/2)+1, N).
The point here is not to explain Shor's as much as to point out it is finding a strong amount of structure to take advantage of, quantumly.
This is actually the same way the oracle separation of BQP and the entire polynomial hiearchy works[1] - It depends on forrelation, which is a problem where quantum computers can extract a global property of the function without needing to learn all the individual values, by taking advantage of structure.
Which is why i go to "The idea that there is literally no structure that can be taken advantage of in AES strikes me as a bad bet".
In part because it's already false if you go literature searching. For example, https://www.sciencedirect.com/science/article/abs/pii/S00200...
There are already reduced round quantum attacks on AES as well. Again, more to the point, the idea that symmetric key ciphers and cryptographic hashes in general are safe because grover's is slower than shor's is not a thing i would bet on at all. Even if AES ends up relatively safe, that tells you basically nothing about the other practically-used ciphers and functions since there are a lot of different construction mechanisms being used.
[1] People still seem to believe there are no functions which quantum computing models have been been proven to be faster at than classical computing models. This is false. Forrelation is the canonical example - and shows that BQP can perform things exponentially faster than you can classically even given access to an infinite polynomial hierarchy.
It is the current physical actualization of these computing models that have the "is it really faster than classical computers" issue, not the theory ;)
(IE it is a perfect example of "in theory there is no difference between theory and practice, and in practice, there is")
This has nothing to do with SHAttered
And from the other comment, symmetric cryptography is safe too from QC attacks.
So it's apparently as you wrote: it's really only asymmetric crypto that is at risk.
Quantum algorithms require some sort of quantum 'trick' to actually have any speedup over classical computers. The most general quantum trick is Grover's algorithm, which lets you find f⁻¹(x) (given f and x) in sqrt(N) queries rather than N queries, where N is the size of the set from which x is drawn. This cuts the bit security of every algorithm in half, although for things like cryptographic hashes, it really means that a second preimage is now only as 'easy' as finding a collision (due to the birthday attack).
The other really well-known quantum trick is QFT, which allows you to find the period of an unknown periodic function really quickly. This is what allows quantum computers to break asymmetric algorithms based on integer factoring or elliptic curves, since they can both be expressed in terms of the QFT.
Priorities!
They've already gone through the pain, deciding on it on 2018[0] (and functional & non-experimental 3 years ago per TFA). What's left is just changing the default (and some stragglers to complete support). Changing the function now would push back changing the default by a couple additional years until the new git version gets widespread deployment (incl. on LTS distros and whatnot).
[0]: https://github.com/git/git/commit/0ed8d8da374f648764758f1303...
What I've done since before git was a thing is a variant of my backup process: my main work areas are synced using rsync⁰ to a copy¹ that is the head of a series of snapshots. If this ends up containing any newly created/modified files²³ a new snapshot is created using `cp -al`. This way I don't have to remember to commit regularly, and I have an automatic trace of everything I've done to a certain granularity⁴. The snapshots are given a name based on the contents of a text file, if present, so I can label points in time (otherwise the snapshot names are just timestamps). Tidying up is easy, just delete old snapshots with `rm -rf`, you could automate this if you like⁵ but I've never felt the need to. The not having to remember to do anything is key for me - over the years it has saved me⁶ from harmful edits not noticed for some time that might otherwise have been more of a pain to recover from. You could do similar per repo with the WIP-branch-in-git option: have script that scans for projects in that named branch, for any found check `git status`, if there are any changes commit with the timestamp as the commit message.
--------
[0] set to ignore a few things like .git directories and some artefacts that I would list in .gitignore
[1] off on a server, that isn't key but it does give me protection against the work machine going boom as well as from accidents off my own doing
[2] detected by looking for files with only one link to them, this can be an expensive check over huge numbers of files but not for what I'm using it on
[3] the sync deletes files too, though I don't use such changes on their own as a reason to create a new snapshot
[4] much higher than the 24-hour granularity that my normal backups have, about 1440 times smaller in fact
[5] keeping them for a maximum amount of time, perhaps, and/or more complex heuristics like not keeping too many copies that are only a few minutes or less apart
[6] only a few times, but more than enough to make me glad I implemented it!
Then you can also do `git diff > changes.diff`. Or simply `rsync -avPh repo/ repo.snap/`, if your repo isn't huge. Or consider putting your repo in a filesystem that can do CoW snapshots.
The solution: create a branch or tag with the things that you're trying. If you want to apply it, use `git merge --squash`. This way your unfinished work lives outside the stash stack!
That is not a problem for local use + constant repo state.
[1] https://blog.gitbutler.com/how-git-core-devs-configure-git
1. Git push should default to --force-with-lease --force-if-includes.
2. push.autoSetupRemote should be enabled by default.
3. The default conflict style should be zdiff3.
4. diff.submodule should be 'log' by default (gives much nicer submodule diffs).
5. Submodule updates / clones should be recursive by default. (There is a setting for this but I can't remember it.)
receive.denyCurrentBranch should be updateInstead by default (or at the very least mentioned in the help message, rather than it recommending ignore or warn or refuse, none of which do what is wanted)
This one always baffled me. The default conflictstyle is so hard to read it's almost useless. Using diff3 is mandatory.
I hadn't heard of zdiff3, I'll give it a shot.
on my Linux system, C takes ownership of a 'top-level' /usr/include directory, all the kernel APIs have their canonical definitions in C headers, a lot of system features like nsswitch require dynamically linked C libraries etc. etc.
Rust is just something that programs can choose to be written in and that doesn't inconvenience me in any way.
Maybe git's case is different though. Do you have more info about it? Are you a git maintainer who was coerced to use Rust, or do you know of such cases?
Just because something does provide an immediate perfect solution does not mean it isn't not worth investigating and/or pursuing.
Also consider that bugs tend to be more prevalent in new code (e.g., [0]) as a result, you are likely to see more of a benefit from writing new code in a memory-safe language than raw line count proportions would indicate.
[0]: https://security.googleblog.com/2024/09/eliminating-memory-s...
Ah, yeah, "you're holding it wrong", though use cases haven't changed, it's closer to the expected common case of expectations turning out wildy wrong (Why would you ever expect people to stop NAMING things at scale???)
But also the core property of the filesystem database has always been low performance for a bunch of tiny things
(As a Windows user, I certainly can't argue that sometimes the filesystem as database has been a performance hit when using git. Though Windows filesystem performance isn't always slow, just performs differently, especially with corporate anti-virus tools involved.)
This is work that Patrick and GitLab have been doing for years now and it's very impressive and nearly complete.
Issue is it would be pretty slow so you'd want it to be a one time thing.
I don't see how that's possible without turning the language into something that isn't C, either by adding significant new functionality (e.g. fat pointers) or subtracting enough functionality that it's a much less capable language (e.g. disallowing dynamic memory allocation).
An important improvement over rust is that "Fil-C has no unsafe statement."
In case of fil-c, it is about 1.5-4x slower performance, and a memory overhead.
So, let's not present it as a panacea to all problems: there could good reasons to use it, but it isn't a magic trick.