作者galic (嘎利)
看板Soft_Job
標題Re: [討論] 零基礎該懂 git 嗎?
時間Tue Aug 4 22:57:09 2026
突然覺得值得回一篇,因為你在問的問題我最近才想過。
當然不是「有了AI之後,還需要 XXXX?」
這種換個 XXXX ,就能重新發一篇的格式廢文。
我還順便看了你在版上的其他文章,我覺得你其實有感受到真正的問題,
缺乏的是問出好問題的能力。
說的是
#1cUZCuPN (Soft_Job) [ptt.cc] [討論] FP正在殺死設計模式嗎?
零基礎知識的 vibe coder 需不需要 git 我不知道,
但有基礎知識的世界第一個 vibe coder → Linus Torvalds 就是發明 git 的人。
每個人工作的方式跟目的都不同,
你要論證這個題目可能得去找沒 git 知識的初學 vibe coder,
分成兩組:一組補充簡單 git 概念,一組限制不能知道什麼是 git。
我相信最終你根本得不到什麼結論。
個人認為軟體工程的直覺會破壞大腦的運作,
讓你容易認定工作的結果跟工作的模式有直接關聯。
你花大把的時間改善的只是效率或品質,(可能間接影響你能不能產出結果,)
但這跟是不是能走向預期的結果不是同一個問題。
這說的是你把使用工具的知識跟解答問題的知識綁在了一起,
如果能清楚的拆開,那這題根本不需要討論。
直覺是一個簡單判斷條件:
如果產出結果必定需要某個工具,那使用工具的知識是必須的。
如果要開發 ios 程式是不是要學 swift?
如果要開發一個在 ios 上做健康管理的 app 是不是要學 swift?
很顯然你問的問題很像後者,大部分的人會回答你健康管理的知識比學 swift更重要。
而今天,「學 swift」的位子可以用 AI 一詞替上。「健康管理的知識」也可以。
這才是現在每個人都在面對的問題,而且他沒有答案。
=====
其實想回答的是抽象語意的這題,這跟我最近在做的題目有關,
而我覺得我手上有你要的答案。
要先搞清楚的一點是 git 其實很複雜,這也是我一直覺得他很難使用的原因。
git 的底層實作是快照(snapshot),那是資料/資料庫領域的東西。
但它的心智模型卻是補丁(patch) 和增量。
最初我猜這原因來自:早期大家熟悉的版本控制都是補丁模型。但這好像沒真正解釋。
AI 給我的答案是因為分散式協作需要 Code Review 和 Branch (尤其是Long-lived)。
Code Review 需要的就是 diff △ (也就是patch),看看這次變更了哪裡。
而 Branch 最終要 Merge 和 Rebase,你要解決衝突時也是 diff。
這觀念最後影響了 Dolt — 把 Git 的增量概念套上了 SQL。
你推文舉的 Jujutsu (jj/咒術) 很顯然是在解我說的「git 很難用」的問題。
因為在 push 到 remote 之前,對我來說(或大部分不習慣多人協作的人),
patch 模型是殺雞用牛刀。
沒有 jj 之前,你需要 stash、rebase、cherry-pick 等高級操作。
而 jj 用的正好就是資料庫的那套模型—ACID、Operation Log(Undo)...。
=====
最後你說的語意,那是第三種—CRDT 或 CvRDT。
這你平常就有在用但可能無感,Google Docs 和改版後的Notion。
他背後是一個漂亮的抽象代數—格(lattice),CRDT 是 join-semilattice (上半),
CvRDT 是 meet- (下半-)。
而格偏偏被用在詞彙、命題、概念甚至程式狀態,
利用格的偏序與上下確界結構,來對概念的包容、特異性與真值進行嚴格的數學建模。
你最熟的是指稱語意,
說的是在 Domain Theory 中,熟悉的程式計算(Lambda Calculus) 被轉換成完備格,
來證明遞迴、迴圈語義是有意義且可收斂的。
所以語意的概念有了,版本控制有了,那一個(抽象)語意的版本控制是什麼?
這就是我在做的題目。
而我必須告訴你的是,他很可能必須是一種新的程式語言,因為現有語言很難做到。
一個貼近的語言叫 Unison,能做到基於語意的版控,
而他的實作叫做 Content-addressed AST(語法樹)。
你需要能從語法層級... 不對。
這其實很簡單:
res = create(
model="gpt-5.5",
instructions="分析這兩個程式版本的差異?",
input=[ {"content": [file1 file2] } ],
)
print(res.text)
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 125.224.73.199 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Soft_Job/M.1785855433.A.252.html
1F:→ MOONY135: ? 08/05 07:38
2F:→ sarsman: ? 08/05 09:04
3F:→ langrisser19: ? 08/05 09:32
4F:推 pponywong: 他其實就是想表示Linus才是第一個vibe coder 08/05 10:11
5F:→ pponywong: 只是vibe的對象是一群工程師 08/05 10:11
6F:推 GiPaPa: 我以為我很懂git 但現在我覺得我不懂了 08/05 10:14
7F:→ MOONY135: 我覺得他如果加上「token無料」 or 「token free」我會 08/05 10:41
8F:→ MOONY135: 贊成他的說法 免費的人力 08/05 10:41
9F:推 VScode: 你講的東西好硬聽不懂 08/05 13:21
10F:噓 USD5566: 並不值得回一篇 他就上來問爽的 看個git而已在那邊毛一 08/05 13:53
11F:→ USD5566: 堆被電還上來問可不可以不要看zzz 08/05 13:53
12F:推 abc0922001: 我也覺得奇怪,git不就是以防AI弄你嗎 08/05 15:25
13F:推 viper9709: 推一二三樓~看不懂+1 XD 08/05 16:35
14F:推 wulouise: 同意問好問題的部分,其他太發散 08/05 18:21
15F:推 nashmvp: 推 08/06 00:54
16F:推 ian90911: 推 08/06 14:41
17F:→ Romulus: 我甚至第一次知道git底層實作是snapshot而不是patch 08/07 10:40
18F:→ Romulus: 這個version control based語言聽起來很炫酷 發展的如何 08/07 10:41
回一下好了:
Unison 的內容定址想解的問題不是語意版本控制,他的重心在建置與重構。
因為名稱改變雜湊不變,且依賴的是雜湊不是名稱。
兩個具有相同功能,僅變數命名不同的函式會被視為相同,這大大減少建置時間。
這被稱作「漸進式編譯與共用快取」。
起初看起來像是解效率問題,但這幾年看起來更重要,因為他能有效防止供應鍊攻擊。
但防不住命名/別名污染(像釣魚攻擊騙走你的簽章),那是中心化套件發佈系統的原罪。
19F:→ superpandal: 本來不想推文 推一下好了 首先git不是基於patch本來 08/07 20:28
20F:→ superpandal: 就是正常的 因為效能考量你不可能在基本版本一路套用 08/07 20:29
21F:→ superpandal: 變更再來比較差異 小repo還好大repo就不行 外部相容 08/07 20:31
22F:→ superpandal: diff和patch是跨版控工具或無版控的協作 release版本 08/07 20:33
23F:→ superpandal: 程式也不可能包含整個repo 至於git高級功能我是反對 08/07 20:38
24F:→ superpandal: 加入的 git本來就可以自定義指令 stash的功能大致上 08/07 20:40
25F:→ superpandal: 就只是git diff > 1.patch和git apply 1.patch的結合 08/07 20:41
26F:→ superpandal: 寫個腳本就能有的功能 cherry-pick同理 rebase稍嫌麻 08/07 20:43
27F:→ superpandal: 煩 總之本來就是高度與系統機制整合與相容的工具 由 08/07 20:45
28F:→ superpandal: 此可知寫一個好的東西條件壓根不在於你讀了多少指導 08/07 20:46
29F:→ superpandal: 性指南或算法 而是整合與一致性 環環相扣 扣人心弦 08/07 20:48
30F:→ superpandal: patch還可以修改套用 比stash靈活多了 至於語意版控 08/07 20:51
31F:→ superpandal: 我只能說近乎無意義 使用者如果都不想學git 你覺得他 08/07 20:53
32F:→ superpandal: 會去學你創的dsl 而那個dsl換用diff也才一行 你多寫 08/07 20:54
33F:→ superpandal: 一大堆累贅 早就已經有很好的工具可以勝任 不多解釋 08/07 21:03
34F:→ superpandal: 了 08/07 21:03
35F:→ superpandal: 至於sql的方式我覺得很醜 08/07 21:11
說到大部份的指令都是marco,補個可以做的練習。
git 主要物件只有內容(blob)、目錄樹(tree)和節點(commit)。
而多數時候你操作的都是指標: HEAD、branch、tag...,
和處理三個主要空間的同步: 工作區、暫存區(staged)、儲存庫(repo)。
先不管遠端操作,設計一個 git 精簡指令集會長怎樣?
1. add [file]: 檔案從工作區進入暫存區
2. snapshot: 檔案從暫存區進到儲存庫 (類似commit但不移動指標)
3. point <name> <commit-id>: 操作指標,這個最難懂
<name> 放 branch name 就是 git branch
<name> 放 HEAD 就是 git checkout
<name> 放 branch name 但 <commit-id> 放 HEAD~2 之類的指標,就是 git reset
4. extract <commit-id>: 從儲存庫或暫存區取東西出來
5. diff <commit-A> <commit-B>: 產生 patch
-. apply: 把 patch 套用到工作區 (這不是git功能,所以不算)
說的練習就是自己組回原本的 git 指令:
commit = snapshot -> point HEAD + point branch
merge = apply (diff <parent> <current>) + (diff <parent> <target>)
-> add -> commit
rebase = (diff commit => patch) -> point <branch> <new-target>
-> extract -> apply patch -> add -> commit
stash = add -> snapshot (孤兒)
好像沒練習到,因為我寫出來了。
※ 編輯: galic (125.224.100.176 臺灣), 08/07/2026 22:48:29
36F:→ superpandal: snapshot我不覺得有必要 apply怎麼不算git功能... 是 08/08 00:27
37F:→ superpandal: 可以不用git實現就是... 而底層操作根本不會曝露的 08/08 00:28
38F:→ superpandal: 不明白你發這個做什麼 我說的git自定義子命令是指可 08/08 00:30
39F:→ superpandal: 以新增子命令或修改曝露的子命令的運作 只要寫腳本即 08/08 00:32
40F:→ superpandal: 可 而stash cherry-pick確實可以應用層透過腳本自己 08/08 00:34
41F:→ superpandal: 寫一個 所以我認為這些子命令基本沒必要實現 我相信 08/08 00:36
42F:→ superpandal: 原始版本的git都是簡潔的 現在一大堆亂七八糟的 08/08 00:37
43F:→ galic: patch是unix指令... 08/08 00:55
44F:→ galic: 沒snapshot要怎麼完成commit? 還子命令 你乾脆自己造個git 08/08 00:59
45F:→ galic: 這裡是個分享知識和經驗的學術論壇 至少我是這麼認為的 08/08 01:36
46F:→ superpandal: 我知道 我常用 但git apply是自己實現的 haha 08/08 01:41
47F:→ superpandal: 在commit內實現就可以了啊 不覺得一定得獨立函數 08/08 01:43
48F:→ superpandal: git的子命令可以自己透過腳本擴充你不知道嗎 本來就 08/08 01:44
49F:→ superpandal: 是這樣用的 你舉例的stash cherry-pick完全可以外部 08/08 01:45
50F:→ superpandal: 實現 我沒有很想跟你討論那麼深 剛開始回應就是了 只 08/08 01:48
51F:→ superpandal: 是多講了一些 08/08 01:49
52F:→ superpandal: 因為你說那些是高級操作 我不那麼認為 我腳本仔湊的 08/08 01:52
53F:→ superpandal: 出來功能 事實上很多功能也應該這麼做 避免臃腫化 08/08 01:55
54F:噓 pttano: 都不用懂 08/09 15:55
55F:→ galic: 自己跑到人家文章底下說寫這些幹嘛 你不自己認為自己發一篇 08/09 16:05
56F:→ galic: 不用拿你的蠢知識跟蠢用詞來這裡獻醜 08/09 16:05
57F:→ galic: 在台灣 我們不說高級功能 我們說進階功能 08/09 16:10
58F:→ galic: 我們不說指導性指南 我們說指引 08/09 16:10
59F:→ galic: 我們不說算法 我們說演算法 08/09 16:10
60F:→ galic: git的客製化指令是透過alias實現 那不是什麼鬼「子命令」 08/09 16:13
61F:→ galic: 那叫「別名」 08/09 16:13
62F:→ galic: git不建議自己組marco是因為你自己沒辦法處理「一致性」 08/09 16:15
63F:→ galic: 這裡的一致性說的是資料一致性(data consistency) 08/09 16:16
64F:→ galic: 你沒辦法保證中間一個你亂組的指令錯了之後是什麼結果 08/09 16:16
65F:→ galic: 你覺得人家設計太臃腫可以去給建議 但自己搞腳本就是走錯路 08/09 16:18
66F:→ galic: 你厲害就自己造一個git讓大家來佩服 08/09 16:18
67F:→ galic: 我在講拆解精簡指令有助於理解底層運作 你在那邊扯東扯西 08/09 16:19
68F:→ superpandal: 高級操作是你講的 我只是在附和你的說法 你要不要翻 08/09 18:38
69F:→ superpandal: 上去看你自己講的 至於其它你管我講什麼 我只是根據 08/09 18:40
70F:→ superpandal: 情況選詞形容 這樣一看你就是不懂怎麼客製化子命令 08/09 18:42
71F:→ superpandal: 還用git alias 完全就是不同東西 你在PATH下某個資料 08/09 18:45
72F:→ superpandal: 夾寫個腳本名 git-test 再某個git repo 下執行 08/09 18:46
73F:→ superpandal: git test看看就知道了 還在扯git alias haha 我講了 08/09 18:48
74F:→ superpandal: 系統機制你是完全不能領會關聯 剩下你回應的就不用說 08/09 18:49
75F:→ superpandal: 了 完全建立在錯誤認知上 git本來就允許你這麼做 本 08/09 18:51
76F:→ superpandal: 來git就不需要提供太多的子命令 可以用擴充的 對應你 08/09 18:53
77F:→ superpandal: 你講需要這些高級操作才能實現 你懂我的意思了嗎 08/09 18:55
78F:→ superpandal: haha ai都比你好溝通 08/09 18:55
79F:→ superpandal: 還有 git有些子命令就是用腳本寫的 連開發者都走錯路 08/09 20:10
80F:→ superpandal: 了嗎? 不要小看腳本 腳本開發便捷是很好的工具 08/09 20:13