我痛恨 Git 的 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
翻譯: git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node
4. 信息模型的擴散
剛才我在第一點提到的 Git 的信息模型是非常復雜的,而且還想癌細胞一樣一直在擴散,當然一直在使用 Git ,就會不斷的冒出各種新的概念,例如 refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces 之類的。
5. 漏洞百出的抽象
- 在分支和 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 請求
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
如果你的項目托管在 Github 類的網站中,那么你需要:
- 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”
下面是一個流程圖向你展示一個典型的開發者在 Subversion 上要做的工作:
"Bread and butter" 是與遠程 SVN 資料庫操作的命令和概念。
然后我們再來看看如果你的項目托管在 Github 上會是怎樣的:
如果 Git 的強大之處是分支和合并,那么它的弱點就是讓簡單的任務變得非常復雜。
翻譯自:10 things I hate about Git
</div>