我希望標題不要太混亂,我將嘗試在這里更詳細地解釋我遇到的問題:
假設您有一個包含代碼檔案(例如“main.py”)和安裝檔案(例如“setup.env”)的存盤庫。現在,代碼對于在存盤庫上作業的每個人都是通用的,但設定特定于每個貢獻者。對于這個例子,假設忽略設定檔案并將設定移動到單獨的子模塊中不是一個選項。
如果我們現在為通用和個人更改分別創建兩個名為“feat-code”和“feat-setup”的分支,是否可以同時在兩個分支上擁有當前 HEAD?這將有效地合并兩個歷史記錄,而無需實際合并和創建提交。
uj5u.com熱心網友回復:
您不能立即執行此操作,但是您可以擁有單獨的 git 存盤庫用于個人設定。我個人不建議這樣做。
通常當 setup 存盤在 git repo 中時,它是模板,必須單獨更改。它們被添加到 .gitignore 檔案中,所以不要擔心更改。如果您創建新的,請記住在個性化之前將其添加到 .gitignore。
uj5u.com熱心網友回復:
不,你不能那樣做。
HEAD在 Git 中看起來像一個分支名稱,但它不是:它是一個符號。對于某些人來說,當他們使用 Git 的單字符同義詞時,這更有意義@。在@為同一個意思HEAD它是代表一個符號:當前分支的名字。1 因此,如果您當前的分支是feat-code,則@意味著feat-code。如果您當前的分支是feat-setup,則@意味著feat-setup。并且HEAD只是一種更長的書寫方式@。
當您使用git switch(或稱老git checkout在其git switch模式),你Git的指示來改變這個名字@代表。在此程序中,您還告訴 Git 切換簽出的提交,除了下面概述的一種特殊情況。這意味著洗掉來自當前提交的所有檔案;我已經選擇了我想要使用的提交,使用我在命令列上給你的分支名稱。從該提交中取出所有檔案。
要理解這一點,您需要知道 Git 實際上就是關于commits 的。你所做的大部分事情——除了進行新提交的程序——都是說“看看這個提交”或“看看那個提交”或“提取一些提交”或“向我展示從某個特定提交開始的提交”的方式. 所以你需要了解所有關于提交的資訊:
每個提交都有編號,帶有一個隨機的、丑陋的十六進制數字,該數字是該提交所獨有的。當您進行新的提交時,它將永遠使用該數字;任何地方的其他提交都不能再次使用該數字。2
每個提交存盤——永遠(或只要提交本身繼續存在)——兩件事:
提交具有每個檔案的快照。更準確地說,它有 Git“知道”的所有檔案的快照(見下文)。這些檔案以壓縮、Git 化和重復資料洗掉格式存盤。只有 Git 可以讀取它們,實際上沒有任何東西——甚至 Git 本身——都無法覆寫它們。
提交還包含一些元資料,例如提交者的姓名和電子郵件地址。它有一些日期和時間戳以及一些其他資訊。一條資訊是針對 Git 本身的:每個提交都有一個串列——通常只有一個元素長——以前存在的提交,Git 稱之為該提交的父項或父項。
所有提交——所有 Git 內部物件,真的——都是只讀的。任何提交的任何部分都不能更改。
這意味著你不能真正做任何與提交。您必須將其中一個提取到作業區中。您提取的提交是您當前的提交,而您進行作業的作業區現在已從該提交中取出檔案。Git 將此作業區稱為您的作業樹或作業樹,并且作業樹具有關聯的當前提交和當前分支,如符號@ or the name HEAD`所記住的。
1還有一種“分離的 HEAD”模式,您不在任何分支上。Git 將此用于git rebase,以及其他幾種內部模式,如果您想“回到過去”并查看舊提交,您可以使用此模式。但是,您通常不會在這種模式下做任何新作業,因為一旦您再次選擇分支名稱,您在這種模式下所做的新提交就會“丟失”(從某種意義上說,您和 Git 都找不到它們)。所以在這種模式下作業需要格外小心,就像 Git 在正在進行的變基程序中使用一樣。
2這在技術上是不可能的,但巨大的提交哈希 ID 推遲了世界末日。我們必須希望它推遲足夠長的時間。
你的作業樹和 Git 的索引
當您選擇要簽出的分支時,該分支中的檔案將進入 Git 的索引,然后進入您的作業樹。所以 Git 現在知道所有這些檔案。他們來到了的提交您選擇。它們現在位于 Git 的索引(或暫存區)和您的作業樹中。如果您在作業樹中創建其他檔案,Git不知道它們,除非您運行它們,否則它們不會出現在下一次提交中git add。
當您運行 時git commit,Git 會打包Git 索引(也稱為暫存區)中的所有檔案。所以如果你修改了一個作業樹檔案,你需要運行git add它:這告訴 Git使臨時區域副本與作業樹副本匹配。如果你創建了一個全新的檔案,你必須運行git add它:這再次告訴 Git 相同的事情。無論哪種方式,臨時區域(索引)副本現在都會更新以匹配作業樹副本,并且下一次提交將具有該檔案。
這意味著 Git 的索引(或暫存區)充當您提議的下一次提交。您可以查看并處理作業樹中的檔案,但您必須使用git add它們來更新提交建議。
git worktree add
一個非常有用的技巧是 Git 允許您一次擁有多個活動的作業樹。每個作業樹都有自己的 HEAD索引。Git 確實要求每個作業樹都位于不同的分支上(或處于 detached-HEAD 模式)。這樣做的原因與分支名稱的作業方式有關,我尚未介紹。這是一個快速總結。
分支名稱的作業原理
在 Git 中,分支名稱只是選擇一個特定的提交。我們說分支名稱指向這個提交。該名稱通過包含該提交的原始哈希 ID 來實作這一點。
Remember above that I said that each commit stores the raw hash ID(s) of some previous commit(s), usually just one. This means that commits also point to other commits—backwards, the way Git works:
... <-a123456 <-b789abc <-fedcba9 ...
might be a string of (shortened) hash IDs, with each commit pointing backwards to its parent. If we replace the hash IDs with uppercase letters, we get something more usable by humans:
...--F--G--H <-- somebranch
The name somebranch contains the hash ID of the latest commit on the branch, which in this case is hash H. Commit H contains a snapshot of all files, plus metadata that includes the raw hash ID of earlier commit G. Commit G contains a snapshot of files, plus the hash ID of earlier commit F. This goes on forever, or at least, until we get to the very first commit ever, which—since it can't point backwards to any earlier commit—doesn't. (Its list of previous hash IDs is empty, in other words.)
Now, more than one branch name can select the same commit, like this:
...--G--H <-- main, feature
We need to know which name you're using:
...--G--H <-- main (HEAD), feature
This says you're using commit H through the name main: your current branch is main and its commit is H. If you run git switch feature, you get:
...--G--H <-- main, feature (HEAD)
You're still using commit H, but now you're using it through the name feature.
So this is the special case where Git doesn't ever have to remove any files: you move from commit H to, well, commit H. Obviously they have the same files. So there's nothing to remove-and-replace.
Note that once you make a new commit, the name you're on updates. New commit I will point back to existing commit H, but the current branch name now points to new commit I:
...--G--H <-- main
\
I <-- feature (HEAD)
再做一次新的提交,你有:
...--G--H <-- main
\
I--J <-- feature (HEAD)
這是 Git 中分支的真正秘密:一個名稱只是選擇一個提交。您可以隨心所欲地移動名稱——它們是可變的,并且您的分支名稱由您決定。該提交是永久性的,只讀的; 它們無法更改,只能找到(通過名稱或其他提交)或找不到。例如,如果您 make J,但后來認為它很糟糕,您可以使用 將其從feature(以及 Git 的索引和您的作業樹)中彈出git reset --hard,給出:
...--G--H <-- main
\
I <-- feature (HEAD)
\
J [abandoned]
請注意,沒有發生任何事情J:它仍然在那里。你只是再也找不到它了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/398249.html
標籤:混帐
