簡體   English   中英

Git沒有獲取被忽略的跟蹤文件

[英]Git not fetching ignored tracked files

這個問題幾乎與FAQ(關於如何阻止Git跟蹤被忽略的文件)相反。 在這種情況下, 我想跟蹤它們,而不是忽略它們。

我有一個.gitignore文件,其中包含以下行:

**/*.exe

在大多數情況下, .exe文件是構建的產物,並且將被忽略(此項目托管在MinGW和Cygwin的組合上,因此二進制文件在Windows上運行。)

但是,此忽略規則也有例外。 我已經在源代碼樹中添加了一些.exe文件。 據我了解, .gitignore不適用於跟蹤的文件(索引中的文件)。

但是,當我克隆我的存儲庫時,不會提取.exe文件。

如果我在添加了原始存儲庫的文件對該文件執行git status則會得到:

$ git status program.exe On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean

該文件也存在於工作樹中:

$ ls -l program.exe -rwxrwx---+ 1 abc xyz 23040 Mar 20 15:35 program.exe

$ git log program.exe

commit 412fd58b5a11bf6a40f661109e71f2c0026c1643 Author: abc <abc@xyz.com> Date: Sat Apr 1 02:21:40 2017 -0700

cleanup

commit b0a2efd4dc17b70d046c1e7d78e3142cf29410ba Author: abc <abc@xyz.com> Date: Mon Mar 20 18:41:00 2017 -0700

Initial version

我已將提交推送到另一台服務器上的裸存儲庫中。 我可以在裸倉庫中找到與最新簽入相對應的blob:

MyProject.git/objects/41/2fd58b5a11bf6a40f661109e71f2c0026c1643

因此很明顯,它正在被跟蹤。 但是,當我克隆存儲庫時,它不會出現在工作樹中。 在克隆的存儲庫上

$ git status program.exe On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean

$ ls -l program.exe ls: cannot access 'program.exe': No such file or directory

我沒有使用assume-unchanged的東西。

  1. 在其他存儲庫中提取時,是否被忽略但跟蹤的文件仍然被忽略?

  2. 即使它們匹配.gitignore您如何強制它們被獲取?

  3. 您是否需要從匹配的.gitignore中排除它們才能獲取它們?

$ git --version git version 2.12.0.windows.1

編輯:記住,將跟蹤文件添加到.gitignore之后,我不是想忽略它們; 我正在嘗試獲取跟蹤和提交的文件,盡管它們匹配.gitignore

TL; DR:我認為這里有一個關於被跟蹤的含義的關鍵見解

在最初的答案和下面的大量討論之間,我意識到我認為不是很明顯的事情。 當我第一次使用Git時,這當然對我來說並不明顯(可能長達數月甚至數年)。 這里有兩個部分:

  • 在Git中, tracked表示索引

  • 但是,每次簽出某些特定的提交(例如git checkout otherbranch ,索引(您將進行的下一次提交)都會更改

這意味着是否跟蹤文件是相對的,而不是絕對的。 可以在git checkout branch1之后跟蹤文件F ,然后在git checkout branch2之后取消跟蹤文件F。 它可能在分支master上的先前提交中已被跟蹤,而現在在分支master上未被跟蹤。 如果該文件是既未經跟蹤忽略,但在過去跟蹤和目前在工作樹,它可以是相當難以弄清楚發生了什么事情。 該文件即使在歷史記錄中也不會出現在新的克隆中。

(原始,請在此處填寫完整的答案。)


但是,當我克隆我的存儲庫時,不會提取.exe文件。

git clone操作不會獲取任何文件。 相反,它將獲取提交。 現在,提交包含文件確實是事實,所以這看起來似乎毫無意義,但它對於您的問題(實際上對幾乎所有Git都至關重要)至關重要,因此確實很重要。 Git不在乎文件; Git就是關於提交的。

提交本身形成了歷史。 每個提交都包含一些文件集,但是還具有指向先前提交的后向指針:“這就是我們現在擁有的。這是我們之前提交的哈希ID。” 我們稱其為提交的父級 該父提交也有其自己的父。 該向后鏈存儲庫中的歷史記錄。

master這樣的分支名稱是Git記錄該分支的當前哈希ID的方式。 Git在最近一次提交時從此處開始,使用分支名稱; 然后,如果需要,Git會向后工作,獲取較早的(父)提交,並按要求轉到較舊的(祖父母,曾祖父母等)提交。

運行git clone復制分支名稱,分支提交,該提交的父級以及父級的父級,依此類推; 這樣您就可以獲取所有歷史記錄。 每個提交都帶有與該提交一起存儲的文件,因此一旦擁有所有提交,就不僅擁有所有當前文件,而且還擁有所有先前的當前父提交文件,以及所有早先的文件。到第一次提交。 但是所有這些文件都以僅Git的秘密格式隱藏起來,除了Git以外對其他任何東西都沒有好處。 仍然是git clone復制的內容。

當然,為了使Git實際有用,我們需要使用一些實際有用的形式的文件。 因此,Git在此提交歷史記錄中添加了一些內容,但這並不是被克隆的內容。 這就是您的問題所在。

存儲庫中的內容

在一個有用的(即非--bare )存儲庫中,我們不僅需要所有提交和各種分支名稱來記住其最近的哈希ID,還需要一個工作樹 工作樹是我們可以處理實際文件的地方。 這些文件以樹狀結構排列,其中包含頂級文件和目錄,並根據需要在目錄中包含更多文件和子目錄。 (因此,名稱為“工作樹”:這是工作表單文件的樹。)

Git還會拋出Git稱為索引的另一件事。 索引的簡短描述是它是您構建下一個提交的地方。 如果您從不對自己的存儲庫進行任何更改,則該索引會為您帶來麻煩,但是Git仍然會迫使您了解它。 如果你做的修改,該指數是至關重要的,因為進行更改的方法是修改在工作樹的事情,然后使用git add到這些修改復制回索引,使他們上演 ,明年提交。 然后,當您運行git commit進行提交時,Git 現在將索引中的內容(即以前存在的所有舊內容,除了您用git add新內容替換的內容)復制到新提交中。

要知道這一點確實非常重要: 索引會跟蹤工作樹中的內容。 實際上,這就是“被跟蹤”的含義:被跟蹤 在索引中的含義 但是索引也是下一次提交中的索引,因此它開始與當前提交中的匹配。

您可以(通常這樣做 )在工作樹中包含故意未被跟蹤的文件。 例如,您的*.exe文件被無意跟蹤。 未被跟蹤意味着它們不在索引中。 這意味着它們也不在當前提交中, 1 ,現在我們可以看到會有問題。


1也就是說, 除非索引為“ dirty”, 否則它們不在當前提交中,因此需要將其寫出到新提交中。 再次,這是您首先進行新提交的方式:您修改工作樹中的內容,例如修改文件,添加全新文件或刪除現有文件,然后復制這些“臟”的工作,樹文件進入索引,“使索引變臟”。 然后,您使用git commit進行新的提交。 新提交的父級是當前提交的父級,而其文件就是索引中的內容。 然后,Git將新提交的哈希ID寫入分支名稱,並且新提交現在是歷史記錄的一部分,將被永久保存。


異議:“我可以找到問題”

您提到:

我可以在裸倉庫中找到與最新簽入相對應的blob: MyProject.git/objects/41/2fd58b5a11bf6a40f661109e71f2c0026c1643

這意味着該文件在某些時候提交。 這是歷史的承諾。 這並不意味着該文件位於像master這樣的分支上的最新提交中。 該存儲庫具有僅Git內部(壓縮對象)格式,曾經提交過的每個文件的每個版本。 並且,您可以而且經常在工作樹中擁有不在索引中且不在當前提交中的文件。 該文件很可能與您過去提交的文件匹配。

因此,文件在存儲庫中的存在並不意味着它在某個特定分支上的最新提交中 這確實意味着您可以提取歷史文件。 例如,鑒於以上所述,您可以:

git show 412fd58b5a11bf6a40f661109e71f2c0026c1643 > foo.exe

隨時將其提取到foo.exe 如果您知道提交哈希和路徑,則也可以使用它:

git show 1234567:path/to/foo.exe > foo.exe

以及提交是否具有名稱 (例如分支或標記名稱):

git show name:path/to/foo.exe > foo.exe

可以使用此方法提取歷史文件,但是顯然有些痛苦。

git clone在獲取所有提交后會做什么

如前所述, git clone首先復制提交和分支名稱。 實際上,默認情況下,它將這些分支名稱重命名為Git所謂的“遠程跟蹤分支”。 但是,在退出它並調用一切正常且准備就緒之前的最后一步, git clone 填充了您的工作樹

它在你的工作樹填充的方法git checkout一些分行的名稱,通常是master 該分支名稱會記住該分支的最新提交的哈希ID。 該提交是從索引進行的,並且該索引中沒有.exe文件。 因此,最新的master提交中沒有.exe文件。

由於此工作樹是全新的,並且檢出的提交中沒有.exe文件,因此新工作樹中也沒有.exe文件。 這就是為什么他們失蹤的原因。

如果這些.exe文件確實存在於存儲庫中的其他提交中,則它們位於存儲庫中,您可以將其取出。 您只是沒有簡單地將它們弄出來:

git checkout master

因為這只會將為master上的最新提交保存的文件提取到索引中,然后提取到工作樹中。

所以, 在哪里得到你.exe文件?

好吧,這部分取決於您。 Git在這里沒有為您提供預包裝的解決方案。 它們可能位於您要克隆的另一個Git存儲庫的工作樹中,但是克隆協議中沒有任何內容可以采用另一個Git的工作樹

處理這個的一個方法是有一個承諾,它包含什么,但最新.exe文件。 然后您可以告訴Git:

    將提交中哈希值為feede3e所有文件提取到我的工作樹中,而不提取到索引中

例如,假設該提交具有該哈希ID。 事實證明,這非常困難,因為Git 確實想將提交中的文件提取到索引中,然后再將它們復制到工作樹中。 將它們放入索引會使它們被跟蹤 ,這不是您想要的。 當然,首先要將那些.exe文件提交到提交中,那么,還有什么呢:等待它……您猜對了嗎? 是的,這需要將那些.exe文件放入索引中!

Git不會讓您同時擁有它。 要么跟蹤文件,要么它們都在索引中,所以它們確實進入了提交; 否則它們將無法跟蹤,因此它們不在索引中,因此它們不會進入提交。 選擇一個並堅持下去。 如果你喜歡,使用git worktree add ,或者這個倉庫,或者完全獨立的存儲設備的單獨的克隆,創建使用不同的分支, 確實有第二個庫或worktree .exe跟蹤和提交的文件。 實際上,您可能希望此分支或其他存儲庫跟蹤和保存.exe文件。 然后,您可以從那里簡單地復制.exe文件。

或者,當然,您可以從確實有它們的地方獲得它們,但是可以使用git clone其他方法。

(它實際上有可能做到這一切,沒有一個單獨的工作樹,使用各種Git的管道命令和臨時索引的,但它是相當棘手的,而不是Git的是如何構建的工作。在任何情況下,請注意,你會希望有一個名稱(例如分支名稱),您可以輕松記住,以獲取具有最新 .exe文件的最新提交;具有分支名稱的想法可以為您記住哈希ID,提交對象可以保存文件,還可以記得上一次提交的對象...好,這是一個分支 ,是混帳什么它使能記住承諾,能記住已保存列的索引文件的哈希分支的名稱,以便你真的想要一個獨立的工作樹和獨立。索引,用於更新和提交文件。畢竟,您真的不想在Git模型之外工作。)

.gitignore文件是一個紅色鯡魚

.gitignore中的條目所做的主要兩件事:

  • 它可以抑制有關未跟蹤文件的投訴 如果foo.exe存在於工作樹中但不存在於索引中,因此不會保存在下一個git commit ,那么Git 會對發牢騷 它不斷地告訴您:“嘿, foo.exe不會被提交!記住將foo.exe添加到索引中!不要忘記foo.exe ,否則它將不會被提交!” 這得到討厭,和你看到的,你真的忘記文件投訴的方式獲得。 因此,將foo.exe*.exe添加到.gitignore關閉此投訴。

  • 它禁止foo.exegit add -a 自動添加。 您可以通過提及目錄名稱或使用--all或使用git add *類的shell全局功能,整體上添加骯臟的工作樹文件,而不必一次手動git add向索引中git add一個文件。 如果foo.exe當前未被跟蹤並且.gitignore列出,則它們實際上不會將foo.exe復制到索引中。 甚至git add *都會跳過它,並有抱怨; git add . git add -a會跳過它而不會產生任何投訴。

請注意,如果跟蹤文件, .gitignore中列出文件名無效。 .gitignore中的條目主要是關於防止文件跟蹤,而不是停止已經生效的任何操作。

您的構建文件位於bin文件夾中。 因此您必須將.gitignore添加到:

bin/*.exe or bin/* 

並且您應該從gitignore文件中刪除此行:

**/*.exe

編輯:如果要忽略除某些文件以外的所有exe文件,可以使用“!”將其排除。 在行模式的開頭,請查看此https://stackoverflow.com/a/987162/5410373

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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