[英]Git untracked files and “working directory”
Git關心未跟蹤的文件。 它們是Git存儲庫的新功能。 這里的“未跟蹤”是一個重要的地位類似modified
, deleted
等,您可能想跟蹤他們,誰知道。 如果您不想看到它們處於git status
但必須保留它們,則gitignore會有所幫助。 而且,Github推薦將.gitignore文件用於許多流行的操作系統,環境和語言。
在大多數情況下,工作樹位於存儲庫中,因為它很自然且方便。 但是一個.git
可以有多個工作樹 。 這樣,多余的工作樹就在存儲庫之外。 這是一篇關於git worktree
簡短文章 。
我克隆的git項目中是否必須要有一個工作樹?
正如ElpieKay回答的那樣,不,不是必須的 ,但這是正常的。 每個Git存儲庫都附帶一個-好吧,每個非裸露的 Git存儲庫。 (您不必擔心“裸倉庫”,但是它只是一個沒有工作樹的倉庫,因此您不能用它來做任何工作。這看起來很奇怪,而且很奇怪。這就是方法)不過,像GitHub這樣的地方存儲您的存儲庫。)
工作樹是一個虛擬的概念嗎?
我不確定這句話的意思。 這是一個版本控制概念,尤其是在現代版本控制系統中。 這些通常將事物分為提交/簽入的文件和當前正在處理的文件 。 提交的文件將進入存儲庫,在該存儲庫中它們將永久存在於凍結的快照中,而正在工作的文件則可以在其中使用和更改它們。 工作表單文件進入工作樹或工作樹中(在使用或不使用連字符的情況下,如何對此進行拼寫有一些變體;請根據需要使用。)
特別是對於Git,您還需要了解一件事,那就是Git所謂的索引 , 暫存區或偶爾的緩存 。 這些都是一件事-一個概念-它只有三個名字 。 在這里將Git與Mercurial(另一個相當現代且非常相似的VCS)以及其他VCS進行比較很有用:Mercurial和其他VCS 確實具有存儲庫和工作樹(或工作樹),但是沒有索引。 因此,Git是不尋常的。 這是如何考慮的:
提交的文件位於凍結(只讀)快照中。 為了使它們占用更少的空間,Git以特殊的,僅Git的格式存儲它們。 這種格式是壓縮的,有時壓縮程度很高,其他程序幾乎無法讀取。
您正在處理的文件進入工作樹,您可以在其中進行處理。 在這里,它們具有普通的,未壓縮的形式,當然您可以覆蓋它們。 您還在工作樹中存儲了Git不會凍結到快照中的文件:這些是未跟蹤的文件。
Git的索引是一種特殊的中介,介於提交和工作樹之間。 索引中的文件已被壓縮為僅Git格式,但尚未提交 (凍結)。 他們都准備好了提交100%,但實際上沒有犯呢。
運行git commit
只是凍結任何文件索引現在 。 這就是為什么git commit
如此之快的原因:如果您使用了其他VCS,則在運行其“ commit”動詞時,它們中的許多都會非常慢,因為它們花費大量時間來瀏覽目錄,壓縮文件,准備好使用它們。凍結的。 在某些VCS中,您實際上可以在等待提交時去喝咖啡。 :-)
如果您認為索引就是Git會提交的內容,那么如果您現在運行git commit
,那么您對Git的索引會有很好的了解。 這自然導致正確定義了被跟蹤文件與未跟蹤文件:被跟蹤文件是當前在索引中的文件,因此它將在下一次提交中; 一個未跟蹤的文件是當前不在索引中但在工作樹中的文件。 (如果文件不在這兩個指標或工作的樹,它只是沒有一個文件都沒有。)
上面還有其他重要的事情:請注意,我們還沒有提到branch一詞。 這是因為Git更加關注提交 , 而不是分支 。 這些提交(即Git用git commit
制作的凍結快照) 組成了分支,因此分支通過擁有提交而出現。 這使得提交成為最重要的部分:在Git中,分支名稱 (如master
)主要用於查找提交。
Git與這里的許多其他VCS也有很大不同。 在其他VCS中,分支是非常重要的,因為提交存在是因為它們在分支中。 因此,提交取決於分支。 在Git中,這是另一種方式:首先存在提交,然后才添加分支名稱。 Git讓我們可以隨意移動名稱 ,而無需更改任何提交!
任何提交的真實名稱是其較大的丑陋哈希ID。 當您運行git log
,將打印出這些哈希ID。 提交的哈希ID永遠不會更改,因為那是提交的真實名稱。 分支名稱只是一個易於理解的名稱,我們會在提交時堅持執行,然后在工作時, 將人類可讀的名稱移至最新名稱。 因此,如果我們從一個只有三個提交的小型存儲庫開始,我們可以使用字母而不是哈希ID來繪制它:
A <-B <-C <--master
名稱 master
記住最新提交的哈希ID,此處為提交C
提交C
記住提交B
的ID。 Git將B
稱為B
的父 C
,因此C
是B
的子B
。 同時, B
記住其父A
的ID。 A
是我們的第一個提交,因此它沒有父項。 我們說名稱master
指向 C
, C
指向B
指向A
(而A
指向無處)。
當我們檢出master
,實際上是在檢出commit C
這會將所有C
的凍結快照的副本放入索引(僅Git形式,但現在我們可以覆蓋文件) 和工作樹(正常形式)中。 然后,我們在工作樹中進行一些工作,完成工作后,我們運行,例如:
git add README.txt newfile.py
這會將每個文件的工作樹版本復制到索引中。 如果已經有README.txt
的索引版本, README.txt
替換索引版本。 如果newfile.py
確實是新的,則將其復制到索引中,以便對其進行跟蹤 -並且,除了被壓縮為僅Git形式之外,索引中的newfile.py
現在與工作樹中的匹配。
然后我們運行:
git commit
其中(收集日志信息等之后),使新的快照D
從無論是在指數:同老existing_file.txt
那是在C
,更新README.txt
,以及新文件newfile.py
,也許。 新提交D
作為其父級,具有我們已檢出的提交,即C
: D
存儲的C
的哈希ID,因此D
指向C
D
,作為一個新的承諾,得到一個新的,唯一的哈希ID,太:混帳莫名其妙來了一個大丑哈希ID(我們不必擔心很多有關如何 ,特別是因為我們不能改變它:-) )。
作為最后一個技巧, git commit
將D
的哈希ID寫入名稱master
:
A <-B <-C <-D <--master
因此,現在master
像往常一樣指向最新的提交。 而且,由於Git只是從索引中獲得D
,因此索引和D
匹配。 只要您從所有工作樹文件中更新了所有索引文件,索引和工作樹也將匹配:所有內容都匹配,並且git status
表示“工作樹干凈”。
如果創建新文件,則最初它不會添加到任何分支。 因此,它將顯示為未跟蹤的文件。
如果要添加所有這些更改,請使用
git add -A
要么
git add path/to/fileName
如果您想刪除所有這些更改,
git clean -fd
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.