2016-05-23 103 views
0

(這不是How does git detect that a file has been modified?的重複,因爲我在問Windows,引用的QA提到statlstat,這些不適用於Windows)。git如何檢測Windows上的修改文件?

對於像SVN和TFS這樣的傳統系統,「狀態數據庫」需要顯式手動通知本地工作區中文件的任何更改:默認情況下文件是隻讀的,因此您不會意外進行更改而無需首先明確通知您的SVN/TFS客戶端。幸運的是,IDE集成意味着可以將導致文件的添加,修改,刪除和重命名(即「檢出」)的操作自動傳遞給客戶端。這也意味着您需要像TortoiseSVN這樣的軟件來處理Windows資源管理器中的文件,以免您的更改被忽略 - 並且您應該定期運行一個經常冗長的服務器到本地比較掃描來檢測任何更改。

但Git沒有這個問題 - 在我的Windows機器上,我可以擁有數十萬個文件的深度數十個文件的回購庫,但是如果我對一個文件進行1個字節的更改,深深地,我可以看到Git在運行git status後知道。這是一個奇怪的部分 - 因爲git不使用任何守護進程或後臺任務 - 運行git status也不涉及任何重要的IO活動,我可以看到,我立即得到結果,它不會甩掉我的磁盤來搜索更改我做了。另外,Git GUI工具(如Git與Visual Studio 2015的集成)也有一定程度的魔力 - 我可以在記事本或其他程序中進行更改,並且VS'Git Changes窗口立即拾取它。 VS可以簡單地使用ReadDirectoryChangesFileSystemWatcher) - 但是當我在Process Explorer中查看devenv進程時,我看不到任何相應的句柄,但這也不能解釋git status如何看到這些更改。

回答

0

Git的git status過程非常輕巧。

git status檢查指數(也稱臨時區域,運行git add之前)和工作目錄(git add後,但git commit前),然後將這些文件與比較,最後提交的版本。 Git不必檢查存儲庫中的每個文件,而是首先檢查這些區域以查看最近提交中要查找的內容。

git diff作用相似。我建議看看here瞭解更多信息。

+0

這不回答我的問題。我想知道git是如何意識到我所做的更改,而沒有在我的repo目錄樹中運行'git'可執行文件,而沒有看似掃描每個文件。 – Dai

+0

您是否意味着您尚未添加到臨時區域的新文件? –

+0

是的,以及任何以任何方式修改的文件 - 只是更改文件中的單個字符。 – Dai

2

Git在索引中記錄的每個文件上運行一個Windows等效的POSIX-y lstat(2)調用,以便第一次判斷文件是否被修改。它將從該信息中獲取的修改時間和大小與索引中爲該文件記錄的值進行比較。

這個操作在NTFS(和網絡映射驅動器)上非常慢,因此一段時間以後,Git for Windows獲得了一個特殊的調整,其默認值爲core.fscache configuration option,默認情況下會啓用一些2或3 GfW版本。我不知道具體的細節,但它會盡量減少Git需要的文件數量到lstat(2)。由於Git在您的系統上不運行守護程序/服務,因此由core.fscache啓用的機制不會使用文件系統來監視Win32 API;所以它只是優化Git向文件系統層詢問跟蹤文件統計信息的方式。

2

由於Briana Swift和kostix指出 - 它掃描您的磁盤。但是,當查找未分離的更改時,它不需要讀取磁盤上的每個文件。相反,它可以查看存儲在索引中的元數據,以確定要更仔細地檢查哪些文件(實際上是讀取它們)。

如果使用git-ls-files命令來檢查索引,你可以看到這個元數據:

% git ls-files --debug worktree.c 
worktree.c 
    ctime: 1463782535:0 
    mtime: 1463782535:0 
    dev: 16777220 ino: 120901250 
    uid: 501  gid: 20 
    size: 5591 flags: 0 

現在,如果運行git status,git會看worktree.c在磁盤上。如果時間戳和文件大小匹配,那麼git會假設你有而不是改變了這個文件。

但是,如果時間戳和文件大小不匹配匹配,那麼git將更仔細地查看文件以確定您是否已更改它。

所以git 確實「thrash」磁盤,但是以一種更爲有限的方式,比如果您使用類似tf reconcile來檢查您的更改。 (TFVC,當然,是專門用來對付非常大的工作的樹木和應從未觸摸你的硬盤,如果你正確地使用它。)

是的 - Visual Studio中確實有它的一些魔術。它在你的工作目錄和Git倉庫的某些部分運行後臺文件系統監視器。當它注意到工作目錄中的更改時,它將重新計算git status。它還查看對Git存儲庫中分支的更改,以瞭解何時切換了分支或重新計算本地存儲庫與遠程的狀態。

+0

感謝您解釋MSVS幫助您實現'git status'性能的方式。 – kostix

+1

@kostix肯定 - 這是關於Visual Studio的一個奇怪的事情,沒有公佈。太糟糕了,因爲如果你沒有正確設置'.gitignore',幾個因素就會成爲一個嚴重的問題。 (文件系統監視器將在您的構建過程中掃描您的二進制文件,並隨之產生不快。) –