我痛恨 Git 的 10 個理由

2022-02-02 16:26:08 字數 4022 閱讀 1489

2023年03月10日

git 是乙個源**版本控制系統,正在迅速成為開源專案的標準。它有乙個強大的分布式模型,允許高階使用者用分支來處理各種棘手的問題和改寫歷史記錄。但是,要學習 git 是需要付出更多的努力,讓人不爽的命令列介面以及 git 是如此的忽視它的使用者。

下面是我為什麼如此痛恨 git 的 10 個理由:

1. 複雜的資訊模型

git 的資訊模型是很複雜的,而且你必須對他們都很了解。在這個方面上你看看 subversion:有檔案、工作目錄、資源庫、版本、分支和標籤。你需要了解的就是這些東西,實際上,分支、標籤和檔案你已經了解,但如果使用 git ,你擁有更多的概念需要了解:檔案、工作樹、索引、本地資源庫、遠端資源庫、遠端、提交、treeishes、分支和 stash。你需要了解比 subversion 更多得多的知識點。

2. 讓人抓狂的命令列語法

git 的命令列語法完全是隨意的而且不一致,例如 git pull 基本上跟 git merge 和 git fetch 一樣,git branch 和 git checkout 合併就變成 git checkout -b,git reset 命令的不同引數做的事情完全不一樣,指定檔名後命令的語義完全不同等等。

而最為壯觀的就是 git am 命令了,據我所知,這是因為 linus 在當年某個晚上為了解決通過電子郵件閱讀補丁而使用的不同的補丁語法,特別是在郵件的標題上。

3. 蹩腳、讓人費解的文件

說起 git 的這個文件,我唯一想說的就是「操」。他們是為計算機科學家在寫文件,而不是使用者。在這裡舉個例子:

git-push – update remote refs along with associated objects

如果是針對使用者而言,應該描述為:

git-push – upload changes from your local repository into a remote repository

另外乙個例子:

git-rebase – forward-port local commits to the updated upstream head

4. 資訊模型的擴散

剛才我在第一點提到的 git 的資訊模型是非常複雜的,而且還想癌細胞一樣一直在擴散,當然一直在使用 git ,就會不斷的冒出各種新的概念,例如 refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces 之類的。

5. 漏洞百出的抽象

git 包含太多不是抽象的抽象,在定義使用者介面和實現上經常沒有任何區別,這是可以理解的,對乙個高階使用者來說他需要了解一些功能的具體實現,以掌握各個命令的微妙之處。但大量的內部細節對初學者來說簡直是噩夢。有這麼乙個說法,關於水暖器材和瓷器,但你必須成為乙個水暖工才能知道器材如何安裝在瓷器上。 

很多人對我的抱怨予以回應說:你無需使用所有的命令,你可以向 subversion 一樣來使用 git。這是狡辯,就好比是告訴乙個老奶奶說高速公路並不可怕,她可以在高速路上靠左邊的快車道上以時速 20 公里爬行,一樣的道理。git 並沒有提供任何有用的子集,每個命令都會連帶著對其他命令的要求,很簡單的動作經常需要很複雜的動作來撤銷或者改進。 

下面是乙個 github 專案維護者的一些善意的建議:

在分支和 master 上尋找合併的基準: 『git merge-base master yourbranch』

假設你已經提交了更改記錄,從對你的提交重新基準化到合併準,然後建立乙個新分支

git rebase –onto head~1 head

git checkout -b my-new-branch

檢出你的 ruggedisation 分支,然後移除提交: 『git reset –hard head~1′

合併新的分支到 ruggedisation: 『git merge my-new-branch』

檢出 master (『git checkout master』), 合併新分支 (『git merge my-new-branch』), 然後檢查合併後的情況,接著移除合併 (『git reset –hard head~1′).

提交新的分支 (『git push origin my-new-branch』) 並記錄 pull 請求

翻譯:「奶奶,在高速公路上開車很容易的。鬆開離合器,讓轉速超過 6000 轉使車輪打滑,然後進入第乙個彎道並上高速公路,看路牌到出口前,使用手剎漂移轉向出口。

6. 維護簡單,但是提交麻煩

git 很強大的一點就是**基準庫的維護,你必須合併來自大量不同源的提交,非常適合大規模並行開發。但是這些都不是為大多數 git 的使用者設計的,他們只是需要編寫**,可能好幾個月都在同乙個分支上,對他們來說 git 是帶有 4 個手柄的雙鍋的咖啡機,但使用者只想立即喝到咖啡。

有趣的是,我並不認為這是 git 在設計中做的權衡。它完全是忽視了真正的使用者需求、混淆架構和介面。如果你是乙個架構師,那麼 git 是很棒的。但對使用者來說它很糟糕,已經有不少人在為 git 編寫一些簡化的介面,例如 easygit。

7. 不安全的版本控制

作為乙個版本控制系統而言,它必須承諾的就是:一旦**提交到系統,那麼我將保證**的安全,你做的任何改動你都可以找回。而 git 食言了,有很多方法可以讓整個資料庫完全崩潰而且不可恢復:

git add . / … / git push -f origin master

git push origin +master

git rebase -i / git push

8. 將版本控制庫維護者的責任移給貢獻者

在傳統的開源專案中,只需要乙個人負責處理分支和合併這樣複雜的操作,那就是維護者。而其他人只需要簡單的更新提交、更新提交、不斷的更新提交。而現在 git 讓每個使用者都需要了解作為維護者才需要知道的各種操作,煩不勝煩。而維護者呢,無所事事,翹起二郎腿喝咖啡。

9. git 的歷史是一堆謊言

開發工作主要的產出就是源**,乙個維護良好的**歷史就對乙個產品來說非常的重要,關於重新基準化有很多的爭論,多數是依賴於對凌亂合併和不可讀的日子的審美判斷。而重新基準化為開發者提供乙個「乾淨整潔」的卻毫無用途歷史記錄,而實際上正確的解決方法是更好的日誌輸出以及對不想要的合併進行過濾。

10. 簡單任務也要諸多命令

如果你在開發乙個開源專案,你做了一些改變,然後想與其他人分享,你只需要:

修改**

執行 svn commit

如果你增加了一些新檔案:

新增檔案

svn add

svn commit

make some changes

git add [not to be confused with svn add]

git commit

git push

到此為止,你的更改只完成了一半,接下來你需要登入到 github,查詢你的提交,然後發布乙個 「pull request」 ,這樣其他人才可以獲取你的改動

在現實中,github 的維護者希望你的改動是功能方面的分支,他們會要求你這樣操作:

git checkout master [to make sure each new feature starts from the baseline]

git checkout -b newfeature

make some changes

git add [not to be confused with svn add]

git commit

git push

然後登入到 github,切換到你的新特性分支,發布 「pull request」

為了將你的更改從你的本地目錄中移到實際的專案資源庫,你需要:add, commit, push, 「click pull request」, pull, merge, push. 

下面是乙個流程圖向你展示乙個典型的開發者在 subversion 上要做的工作:

"bread and butter" 是與遠端 svn 資料庫操作的命令和概念。

然後我們再來看看如果你的專案託管在 github 上會是怎樣的:

如果 git 的強大之處是分支和合併,那麼它的弱點就是讓簡單的任務變得非常複雜。

愛上 SQLAlchemy 的 10 個理由

最近,我見到了很多針對 orm 的抨擊,但是我覺得有些批評是莫須有的。我本人就是 sqlalchemy 的忠實擁躉。在我的專案裡很多地方都用到了 sqlalchemy,我也為 sqlalchemy 專案貢獻了一些 這篇文章裡,我會闡述你應當愛上 sqlalchemy 的10個理由。說實話,除了 sq...

喜愛Sahi的10個理由

工具與語言本身 1.容易上手 個人體驗,sahi學習起來要比qtp selenium 2.2.對extjs支援不錯 qtp能支援的對於動態id的支援 通過正規表示式或者 near等相對關係 sahi可以同樣做到。而在對於 處理方面,sahi要略勝一籌。比如,判斷乙個表的某個 是否是某值,在sahi裡...

我最痛恨的拓撲排序QwQ

鬼 知 道 剛 學 這 破 玩 意 的 時 候 我 有 多 絕 望,現在再回來學,嗯 真 可 愛 拓撲序有以下幾個特點 每個點都有入度和出度,當某點入度為0時,則沒有指向它的邊,由拓撲序的第二條特點得出,這時沒有點必須排在它的前面,於是將它加入拓撲序,就相當於在原圖中刪掉這個點,該點指向的所有點入度...