Git 在 SHA-256 支援上遇到的問題

在 Hacker News 首頁上的「Whatever happened to SHA-256 support in Git?」這篇,大概半年前,今年六月的文章,在講 GitSHA-256 支援上遇到的問題。

最大的問題還是沒有 transition plan:

Bjarmason pointed out that there is still no interoperability between SHA-1 and SHA-256 repositories, and that none of the Git hosting providers appear to be supporting SHA-256.

這點導致了目前場上看的到的服務與 open source 軟體都沒有支援的計畫,這點算是一個超級失敗的 transition plan。

另外乾脆請 OpenAIChatGPT 幫忙寫:

Git是一種源代碼管理系統,它使用散列函數將每個對象(例如文件的每個版本)和每個提交都轉換為一個數值,用於存儲該對象。散列函數的安全性是整個倉庫完整性的重要組成部分。如果攻擊者可以用具有相同散列值的另一個提交替換提交,他們可能會在不冒檢測風險的情況下將惡意代碼植入倉庫中。這種前景令任何依賴 Git 倉庫中代碼安全性的人感到擔心,也就是所有人。

Git 項目早已選擇 SHA-256 作為 SHA-1 的替代品。Git 最初是使用 SHA-1 寫成的,但是這些代碼已被重構,並且可以處理多種散列類型,其中 SHA-256 是第二種支持的類型。現在可以使用 SHA-256 創建 Git 倉庫(只需使用 --object-format=sha256 標誌),大多數本地操作都會正常工作。Git 中支持替代散列算法的基礎是2020年發布的2.29版本的一部分,並且似乎很穩定。

然而,自從2021年3月發布的2.31版本中出現了修復程序以來,2.29版本是最後一個在任何重大方面支持替代散列的版本。專

續寫前文,Git 專案在支持 SHA-256 之前一直使用 SHA-1 作為散列算法。然而,由於 SHA-1 的終極破解,Git 項目被迫尋找替代方案。Git 原本的代碼是深深地嵌入 SHA-1 的,但是這些代碼已經被重構,並且可以處理多種散列類型,其中 SHA-256 是第二種支持的類型。因此,現在可以使用 SHA-256 創建 Git 倉庫(只需使用 --object-format=sha256 標誌),大多數本地操作都會正常工作。

然而,目前尚不存在 SHA-1 和 SHA-256 倉庫之間的相互操作性,並且 Git 托管提供商似乎都不支持 SHA-256。這種支持(或缺乏支持)很重要,因為無法推送到 Git 熔爐的倉庫對許多人來說將是無用的。此外,使用 SHA-256 的較長散列可能會破壞 Git 項目以外開發的工具,這種風險也無法完全消除。整體而言,這是一種尚未準備好用於現實世界的功能。

雖然如此,值得注意的是,迄今為止完成大部分散列轉換工作的 brian m. carlson 對 Bjarmason 的評估持不同看法。在他看來,目前唯一“可以辯解

的”使用 SHA-1 的原因是與 Git 熔爐提供商的相互操作性。否則,他認為 SHA-1 已經過時,並且使用 SHA-256 的性能可能“大幅提升”。但是,他同意所需的相互操作性目前尚不存在,且沒有人表示它即將在短期內到來。

因此,目前看來,Git 專案在支持 SHA-256 方面的工作似乎已經停止。至於什麼原因導致了這種情況,目前還不清楚。但是,這並不意味著 Git 將永遠不會支持 SHA-256 或其他散列算法。相反,可能是因為尚未解決所有技術問題,或者可能是因為其他原因(例如技術資源有限)。無論原因是什麼,重要的是要記住,Git 項目的開發人員一直在努力使其更強大、更安全,並且將繼續努力。

SourceHut 宣佈拒絕 cryptocurrency 與 blockchain 相關的專案

SourceHut 是個 GitMercurial 的 hosting service,以及提供一些專案管理常見的功能。

他們宣佈不再提供 cryptocurrency 以及 blockchain 相關專案的服務,自 2023 年生效:「SourceHut terms of service updates, cryptocurrency-related projects to be removed」。

SourceHut is planning to roll out updates to our terms of service, effective in 2023. The changes most likely to impact users is the prohibition of cryptocurrency- or blockchain-related projects on SourceHut.

因為這些技術幾乎都是用在違法用途上:

These domains are strongly associated with fraudulent activities and high-risk investments which take advantage of people who are suffering from economic hardship and growing global wealth inequality. Few to no legitimate use-cases for this technology have been found; instead it is mostly used for fraudulent “get rich quick” schemes and to facilitate criminal activity, such as ransomware, illicit trade, and sanctions evasion. These projects often encourage large-scale energy waste and electronics waste, which contributes to the declining health of Earth’s environment. The presence of these projects on SourceHut exposes new victims to these scams and is harmful to the reputation of SourceHut and its community.

不過這年頭自己架 GitLab 也不是什麼難事,該有的功能都有,這個只能算是個宣言...

用 Git 2.38 內建的 Scalar 管理大量的 repository

在「Highlights from Git 2.38」這邊有介紹 Git 2.38 加入了微軟開發的 Scalar,是一個用來管理大量 repository 以及巨大 repository 的工具。

第一次用 scalar register 看起來會先有一些前置作業,在掛 repository 進去的時候就會自動去註冊 timers:

Created symlink /home/gslin/.config/systemd/user/timers.target.wants/git-maintenance@hourly.timer → /home/gslin/.config/systemd/user/git-maintenance@.timer.
Created symlink /home/gslin/.config/systemd/user/timers.target.wants/git-maintenance@daily.timer → /home/gslin/.config/systemd/user/git-maintenance@.timer.
Created symlink /home/gslin/.config/systemd/user/timers.target.wants/git-maintenance@weekly.timer → /home/gslin/.config/systemd/user/git-maintenance@.timer.

這樣看起來應該是每個小時會跑一些東西?文件上看起來是會在背景先去拉一些東西,還有定時跑 GC?

接下來就是把目錄下所有的 git repository 丟進去:

find . -maxdepth 1 -mindepth 1 -type d | xargs -n1 -I% bash -c "cd %; scalar register"

然後可以用 scalar list 看到目前掛了哪些 repository。

WebKit 專案將從 Subversion 搬到 GitHub 上

Hacker News 首頁上看到 WebKit 專案宣佈從本來的 Subversion 搬到 GitHub 上:「WebKit on GitHub!」,新的專案位置在 WebKit/WebKit 這邊。對應的討論在「WebKit Migrates from Subversion to GitHub (webkit.org)」這邊。

但 issue tracking system 的部份目前看起來還是繼續用 WebKit Bugzilla,沒有開 GitHub 的 issue 功能,但至少是從 Subversion 換成 Git 了。

在 Hacker News 上的討論意外看到已經是歷史的 SVK (試著在 Subversion 上面堆一些功能),而且還聊到了一些 tricky 的技巧:

Funny story: my first task when I joined the original iPhone team was to merge our forked WebKit with master. It was a sort of hazing ritual slash "when else would we do it but when someone new joins?". Anyways, we used a tool called SVK[1] in order to get very primitive "git-like" abilities. It was basically a bunch of scripts that used SVN under the hood. For example, in order to get the "local everything"-style behaviors of git, the very first thing it did was checkout every single version of the repository in question. For WebKit, this meant that the first day was spent leaving the computer alone and letting it download for hours. I made the mistake of having a space somewhere in the path of the target folder, which broke something or other, so I ended up having to do it all over again.

Anyways, I distinctly remember one of the instructions for merging WebKit in our internal wiki being something like "now type `svk merge`, but hit ctrl-c immediately after! You don't want to use the built-in merge, it'll break everything, but this is the only way to get a magic number that you can find stored in [some file] after the merge has started. If it's not there, try `svk merge` again and let it go a little longer than last time." A few hires later (I think possibly a year after) someone set up a git mirror internally to avoid having to do this craziness, which if I remember correctly, was treated with some skepticism. This was 2007, so why would we try some new-fangled git thing when we had svk?

1. https://wiki.c2.com/?SvkVersionControl

我記得那個時間點 VCS 的選擇的確是個有趣的決策過程... 除了 Git 以外還有 Mercurial,另外還有幾個當時就已經算小眾的 open source solution。

而到了 2010 後就比較明朗了,現在幾乎是 Git 一統天下了,Mercurial 目前最大的使用者應該是 Meta (Facebook)?

Git 2.37.0 對巨大 Monorepo 的加速功能 FSMonitor

這邊用 GitHub 寫的說明好了:「Improve Git monorepo performance with a file system monitor」。

從 2.37.0 開始,Windows 與 Mac 版的使用者可以透過 FSMonitor 的功能記錄檔案系統的變化,大幅減少需要 scan 整個 repository 的時間,可以看到啟用後對於像是 chromium 這種大型專案的 status 時間就大幅下降了:

不過 Linux 還沒支援,目前我的環境都是 Linux,就沒辦法用了...

Git 的「災難處理」

但印象中之前看過 (在 Internet Archive 上可以看到 4 Sep 2017 的版本),但搜尋 Hacker News 後發現沒有提過... 這幾天紅起來的「Dangit, Git!?!」,也有簡體中文版可以看。

裡面其實提到了很多要怎麼處理不小心塞錯資料進 Git 的情況,不過好像還是有些東西沒涵蓋到,像是遇到不小心塞到 credentials 進去後需要清除掉的 git rebase -i HASH,接著一連串的手動修 conflict 與 git rebase --continue,最後再接上 git push --force 這種禁招...

另外推一下「為你自己學 Git」這本書,裡面其實也有提到類似的情境:

第7章:修改歷史紀錄
7.1 狀況題 修改歷史訊息
7.2 狀況題 把多個 Commit 合併成一個Commit
7.3 狀況題 把一個 Commit 拆解成多個Commit
7.4 狀況題 想要在某些 Commit 之間再加新的Commit
7.5 狀況題 想要刪除某幾個 Commit 或是調整Commit 的順序
7.6 Reset、Revert 跟 Rebase 指令有什麼差別?

這本書也有網頁版,在 gitbook.tw 這邊。

在 .gitignore 裡面忽略掉 .gitignore...

Hacker News 上看到「Git ignores .gitignore with .gitignore in .gitignore」這個搞事的功能,可以在 .gitignore 內把 .gitignore 忽略掉 XDDD

這真虧作者想的到這樣的玩法 XDDD

在 Hacker News 上也有看到一些有趣的東西,像是 globally ignore list 之類的:「Git ignores .gitignore with .gitignore in .gitignore (rubenerd.com)」。

用 GitHub Actions 做的監控服務 Upptime

是在 Twitter 上看到這個:

然後翻到 Upptime 這個 open source monitoring 工具,直接是用 GitHub Actions 提供的 schedule (cron job) 每五分鐘跑一次。這邊要注意的是,如果是 public repository 的話不受限制,如果是 private repository 的話會有機會把 quota 吃完:

Billing note: Upptime uses thousands of build minutes every month (approximately 3,000 minutes in the default setting). If you use a public repository, GitHub offers unlimited free build minutes, but if you use a private repository, you'll have to pay for this time.

依照說明是用 GitHub Actions、GitHub IssuesGitHub Pages 三個功能在運作:

  • GitHub Actions is used as an uptime monitor
  • GitHub Issues are used for incident reports
  • GitHub Pages are used for the status website

除了用這三個功能外,另外還是會每天塞一些資料回 git history 裡面:

We also record the response time once per day and commit it to git history. This way, we can graph long-term trends in your websites' response times by going through git commit history. We generate these graphs once every day, also using schedulers.

好像可以玩看看...

Python 的 Black

Hacker News 上看到 Black 這個幫你處理 Python 程式碼的工具:「Black, the uncompromising Python code formatter, is stable (pypi.org)」。

Black is the uncompromising Python code formatter. By using it, you agree to cede control over minutiae of hand-formatting. In return, Black gives you speed, determinism, and freedom from pycodestyle nagging about formatting. You will save time and mental energy for more important matters.

然後從 Hacker News 上討論的情況看起來大家都覺得很不錯?好像可以看看能不能拿來用...

另外一個在討論的時候看到學到的東西,是 git blame --ignore-revs-file 這個功能,可以在 git blame 時濾掉某些 commit,剛好拿來過濾 reformatting commit:

Ignore revisions listed in file, which must be in the same format as an fsck.skipList. This option may be repeated, and these files will be processed after any files specified with the blame.ignoreRevsFile config option. An empty file name, "", will clear the list of revs from previously processed files.

Git 的 Diff 演算法

Lobsters Daily 上看到「When to Use Each of the Git Diff Algorithms」這篇 2020 的文章 (Lobsters 這邊常冒出一些舊文章),講 Git 的 diff 演算法。

文章裡面題到了四個演算法,看了一下 git-diff 的 manpage 也還是這四個:

--diff-algorithm={patience|minimal|histogram|myers}

另外看 manpage 時還有看到 --anchored 的用法,看起來是用來提示 Git 產生比較好懂的 diff 結果:

--anchored=<text>

Generate a diff using the "anchored diff" algorithm.

This option may be specified more than once.

If a line exists in both the source and destination, exists only once, and starts with this text, this algorithm attempts to prevent it from appearing as a deletion or addition in the output. It uses the "patience diff" algorithm internally.

回頭翻了一下自己的 config repository,看起來 2017 年年底的時候我就加了「Use histogram diff algorithm.」,然後過幾天換成「Use patience algorithm.」,就一直用到現在...

這次改用 minimal 跑一陣子看看好了...