簡體   English   中英

Git未跟蹤的文件和“工作目錄”

[英]Git untracked files and “working directory”

我是Git和VCS的新手,有一個問題使我喪命了幾天。如果Git不在乎git項目中的未跟蹤文件,為什么當您發布git時它在未跟蹤文件下顯示git repo的狀態git status命令?

我克隆的git項目中是否必須要有一個工作樹? 工作樹是一個虛擬的概念嗎?

在此處輸入圖片說明

Git關心未跟蹤的文件。 它們是Git存儲庫的新功能。 這里的“未跟蹤”是一個重要的地位類似modifieddeleted等,您可能想跟蹤他們,誰知道。 如果您不想看到它們處於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 ,因此CB的子B 同時, B記住其父A的ID。 A是我們的第一個提交,因此它沒有父項。 我們說名稱master 指向 CC指向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作為其父級,具有我們已檢出的提交,即CD存儲的C的哈希ID,因此D指向C D ,作為一個新的承諾,得到一個新的,唯一的哈希ID,太:混帳莫名其妙來了一個大丑哈希ID(我們不必擔心很多有關如何 ,特別是因為我們不能改變它:-) )。

作為最后一個技巧, git commitD的哈希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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM