Presumably the problem is that these tools only take the abbreviated hash into account. Not also the subject:
<abbrev. hash> ("<subject>")
You also have another data point. You only need to search in the history from the commit that you are reading. Assuming that the "Fixes" commit is an ancestor of the commit whose commit footer you are reading.
I always just assumed that tools would take all the data into account. Which means that you both need to collide with the abbreviated hash as well as the subject. Now I don't do that since I just copy-paste the hash, but I would quickly notice in case the subject is different (and likely the commit message and the diff just look irrelevant).
I don't understand why the Linux Kernel has this hard-coded rule[2] -- again, you were going to get collisions eventually, so the tools should have just taken all the data into account (at least the subject) from the start. The recommendation in the Git project is to use `git show -s --pretty=reference`, without any fiddling with the abbreviation:
<abbrev. hash> (subject, ISO date)
Although the Git maintainer uses `--abbrev=8` since git-show will just use a longer abbreviation in case the output would be ambiguous[1].
They could have used this instead if they wanted simpler, future-proof tooling:
Fixes: <full hash>
Just like tools like git-revert and git-cherry-pick do.
git itself does not use a fixed size abbreviation but determines the length necessary with the birthday paradox formula. It just happens to be seven characters most of the time, because most repos are small.
This is just for the abbreviated hash which git uses only for specific cases like display in the git log and similar, where it is a user experience improvement and relatively safe.
I know. I don’t understand why the Linux Kernel uses a hard-coded abbreviation instead of just letting Git figure out how long it should be (edited my comment now).
The length of the required abbreviation grows over time, while content you put in commit messages sticks around. Meaning a commit done in year 2005 may have gotten away with "Fixes: abcd" and was unambiguous at that time, whereas after 20 years of growth, there could now be multiple other commits with that prefix.
By that logic, any length of abbreviation will eventually fail if stored for a long time, those abbreviations should be seen as temporary for user interaction only. For the "Fixes:" footer they should have gone with full hash, it's hidden away in the footer so it doesn't disrupt anyone. Aanyone interacting with it will double click to copy it regardless if it is 8 or 40 characters long. Abbreviating it simply adds no value.
So as noted you can configure the length, but you can't actually adjust the probability used by the auto-length formula.
The formula calculates how many bits are needed to store the approximate number of objects, then uses twice that many bits, rounding up.
For example, at 16000 objects git is still using the minimum length of 7 characters. But at 17000 objects it now takes 15 bits to store the object count, so it wants 30 bits of hash, which means 8 characters.
Comments
Presumably the problem is that these tools only take the abbreviated hash into account. Not also the subject:
You also have another data point. You only need to search in the history from the commit that you are reading. Assuming that the "Fixes" commit is an ancestor of the commit whose commit footer you are reading.I always just assumed that tools would take all the data into account. Which means that you both need to collide with the abbreviated hash as well as the subject. Now I don't do that since I just copy-paste the hash, but I would quickly notice in case the subject is different (and likely the commit message and the diff just look irrelevant).
I don't understand why the Linux Kernel has this hard-coded rule[2] -- again, you were going to get collisions eventually, so the tools should have just taken all the data into account (at least the subject) from the start. The recommendation in the Git project is to use `git show -s --pretty=reference`, without any fiddling with the abbreviation:
Although the Git maintainer uses `--abbrev=8` since git-show will just use a longer abbreviation in case the output would be ambiguous[1].They could have used this instead if they wanted simpler, future-proof tooling:
Just like tools like git-revert and git-cherry-pick do.[1]: https://lore.kernel.org/git/xmqq34j5h7v9.fsf@gitster.g/
[2]: Edit: hard-coded as opposed to Git just figuring out how long the abbreviation should be based on how many objects there are.
Well the first mentioned script:
has `get_full_hash`[1] which uses the subject to search through the abbreviated matches.
Edit: And that check was added two weeks ago by Kees [2].
[1]: https://github.com/kees/kernel-tools/blob/trunk/helpers/chec...
[2]: https://github.com/kees/kernel-tools/commit/5bf6a1e71df59a23...
git itself does not use a fixed size abbreviation but determines the length necessary with the birthday paradox formula. It just happens to be seven characters most of the time, because most repos are small.
This is just for the abbreviated hash which git uses only for specific cases like display in the git log and similar, where it is a user experience improvement and relatively safe.
I know. I don’t understand why the Linux Kernel uses a hard-coded abbreviation instead of just letting Git figure out how long it should be (edited my comment now).
The length of the required abbreviation grows over time, while content you put in commit messages sticks around. Meaning a commit done in year 2005 may have gotten away with "Fixes: abcd" and was unambiguous at that time, whereas after 20 years of growth, there could now be multiple other commits with that prefix.
By that logic, any length of abbreviation will eventually fail if stored for a long time, those abbreviations should be seen as temporary for user interaction only. For the "Fixes:" footer they should have gone with full hash, it's hidden away in the footer so it doesn't disrupt anyone. Aanyone interacting with it will double click to copy it regardless if it is 8 or 40 characters long. Abbreviating it simply adds no value.
Well a fix has to be for a parent commit so future commits and future growth aren't nearly as important.
At what probability? Can that probability be configured as a global Git option?
So as noted you can configure the length, but you can't actually adjust the probability used by the auto-length formula.
The formula calculates how many bits are needed to store the approximate number of objects, then uses twice that many bits, rounding up.
For example, at 16000 objects git is still using the minimum length of 7 characters. But at 17000 objects it now takes 15 bits to store the object count, so it wants 30 bits of hash, which means 8 characters.
It can be configured with `core.abbrev`.
https://git-scm.com/docs/git-config#Documentation/git-config...
I love when the word "hopefully" is used in technical documentation ))
All technical documentation is wishful thinking, they're just being explicit about it.