work - gitignore教學




如何讓Git“忘記”一個被跟踪但現在位於.gitignore的文件? (14)

在以下時間使用此

你想要解開很多文件,或者

2.您更新了gitignore文件

來源鏈接: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/ http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/

假設您已經將一些文件添加/提交到您的git存儲庫,然後將它們添加到您的.gitignore; 這些文件仍將存在於您的存儲庫索引中。 本文我們將看到如何擺脫它們。

第1步:提交所有更改

在繼續之前,請確保提交所有更改,包括.gitignore文件。

第2步:從存儲庫中刪除所有內容

要清除您的倉庫,請使用:

git rm -r --cached .
  • rm是remove命令
  • -r將允許遞歸刪除
  • -cached只會從索引中刪除文件。 你的文件仍然存在。

rm命令可能是不可原諒的。 如果您希望事先嘗試它的功能,請添加-n--dry-run標誌來測試。

第3步:重新添加所有內容

git add .

第4步:提交

git commit -m ".gitignore fix"

你的存儲庫很乾淨:)

將更改推送到遙控器以查看更改在那裡有效。

git正在跟踪一個文件,但現在該文件位於.gitignore列表中。

但是,該文件在編輯後會一直顯示為git status 。 你怎麼強迫git完全忘掉它?


什麼對我不起作用

(在Linux下),我想在這裡使用帖子來建議ls-files --ignored --exclude-standard | xargs git rm -r --cached ls-files --ignored --exclude-standard | xargs git rm -r --cached方法。 但是,(某些)要刪除的文件在其名稱中有一個嵌入的換行符/ LF / \n 。 兩種解決方案都沒有:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

應對這種情況(獲取有關未找到文件的錯誤)。

所以我提供

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached

這對ls-files使用-z參數,對xargs使用-0參數安全/正確地處理文件名中的“討厭​​”字符。

在手冊頁git-ls-files(1)中 ,它指出:

如果未使用-z選項,則路徑名中的TAB,LF和反斜杠字符分別表示為\ t,\ n和\\。

所以如果文件名中包含任何這些字符,我認為我的解決方案是必需的。

編輯:我被要求添加 - 像任何git rm命令---這必須後面提交使刪除永久,例如git commit -am "Remove ignored files"


Matt Fear的答案是最有效的恕我直言。 以下只是一個PowerShell腳本,用於Windows中的那些只能從他們的git倉庫中刪除與其排除列表匹配的文件。

# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles =  gc .gitignore | ?{$_ -notmatch  "#"} |  ?{$_ -match  "\S"} | % {
                    $ignore = "*" + $_ + "*"
                    (gci -r -i $ignore).FullName
                }
$ignoreFiles = $ignoreFiles| ?{$_ -match  "\S"}

# Remove each of these file from Git 
$ignoreFiles | % { git rm $_}

git add .

BFG專門用於從Git repos中刪除不需要的數據,如大文件或密碼,因此它有一個簡單的標誌,可以刪除任何大型歷史(不在當前提交)文件:'--strip-blobs-降幅高於“

$ java -jar bfg.jar --strip-blobs-bigger-than 100M

如果您想按名稱指定文件,也可以這樣做:

$ java -jar bfg.jar --delete-files *.mp4

BFG比git filter-branch快10-1000倍,並且通常更容易使用 - 查看完整的使用說明examples以獲取更多詳細信息。

資料來源: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.htmlhttps://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html


git update-index為我做的工作:

git update-index --assume-unchanged <file>

注意:此解決方案實際上獨立於.gitignore因為gitignore僅適用於未跟踪的文件。

編輯:由於此答案已過帳,因此創建了一個新選項,應該首選。 您應該使用--skip-worktree ,它用於用戶不想再提交的已修改跟踪文件,並保持--assume-unchanged性能,以防止git檢查大型跟踪文件的狀態。 有關詳細信息,請參閱https://.com/a/13631525/717372


這在最新的git中不再是一個問題 (在撰寫本文時為v2.17.1)。

.gitignore最終忽略了被跟踪但已刪除的文件。 您可以通過運行以下腳本來自行測試。 最終的git status語句應該報告“沒有提交”。

# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init

# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial

# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore

# Remove the file and commit
git rm file
git commit -m "removed file"

# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status

如果你不能git rm跟踪文件,因為其他人可能需要它(警告,即使 git rm --cached ,當其他人得到這個改變時,他們的文件將被刪除在他們的文件系統中)。 這些通常是由配置文件覆蓋,身份驗證憑據等完成的。請查看https://gist.github.com/1423106了解人們解決問題的方法。

總結一下:

  • 讓您的應用程序查找被忽略的文件config-overide.ini並將其用於提交的文件config.ini(或者,查找〜/ .config / myapp.ini或$ MYCONFIGFILE)
  • 如果需要,提交文件config-sample.ini並忽略文件config.ini,根據需要使用腳本或類似的文件複製文件。
  • 嘗試使用gitattributes clean / smudge magic來為你應用和刪除更改,例如將配置文件塗抹為來自備用分支的簽出,並將配置文件清理為HEAD的簽出。 這是棘手的東西,我不建議新手用戶使用它。
  • 將配置文件保留在專用於它的部署分支上,該分支永遠不會合併到主服務器。 當您想要部署/編譯/測試時,您將合併到該分支並獲取該文件。 除了使用人工合併策略和extra-git模塊之外,這基本上是塗抹/清潔方法。
  • 反推薦:不要使用假設不變,它只會以淚水結束。

如果已經提交了DS_Store

find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch

忽略它們:

echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

最後,提交一下!


將它移出,提交,然後將其移回。這在過去對我有用。 實現這一目標可能有一種“輕微”的方式。


將文件移動或複製到安全位置,這樣您就不會丟失它。 然後git rm文件並提交。 如果您還原到其中一個早期提交,或者另一個尚未刪除的分支,該文件仍將顯示。 但是,在以後的所有提交中,您都不會再看到該文件。 如果文件在git中忽略,那麼你可以將它移回文件夾,git將看不到它。


我想,也許git不能完全忘記文件因為它的概念( “快照,不是差異”部分 )。

例如,在使用CVS時,不存在此問題。 CVS將信息存儲為基於文件的更改列表。 CVS的信息是一組文件以及隨時間對每個文件所做的更改。

但是在Git每次提交或保存項目狀態時,它基本上都會描繪當時所有文件的外觀,並存儲對該快照的引用。 因此,如果您添加了一次文件,它將始終存在於該快照中。

這2篇文章對我有幫助:

git假設 - 未更改vs skip-worktree以及如何使用Git忽略跟踪文件中的更改

基於它我會執行以下操作,如果已經跟踪了文件:

git update-index --skip-worktree <file>

從此刻起,此文件中的所有本地更改都將被忽略,並且不會轉到遠程。 如果在遠程更改文件,則在git pull時會發生衝突。 藏匿不起作用。 要解決此問題, 請將文件內容複製到安全位置並按照以下步驟操作:

git update-index --no-skip-worktree <file>
git stash
git pull 

文件內容將被遠程內容替換。 將更改從安全位置粘貼到文件並再次執行:

git update-index --skip-worktree <file>

如果每個使用項目的人都會執行git update-index --skip-worktree <file> ,那麼應該沒有pull問題。 當每個開發人員都有自己的項目配置時,此解決方案適用於配置文件。

在遠程更改文件時,每次執行此操作都不是很方便,但可以保護它不被遠程內容覆蓋。


我總是使用此命令刪除那些未跟踪的文件。 單行,Unix風格,乾淨的輸出:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

它列出了所有被忽略的文件,用引用的行替換每個輸出行,而不是處理內部有空格的路徑,並將所有內容傳遞給git rm -r --cached以從索引中刪除路徑/文件/目錄。


按順序執行以下步驟,你會沒事的。

1. 從目錄/存儲中 刪除錯誤添加的文件。 您可以使用“rm -r”(用於linux)命令或通過瀏覽目錄刪除它們。

2.現在將文件/目錄添加到gitignore文件並保存。

3.現在使用這些命令它們從git緩存中 刪除 (如果有多個目錄,則通過重複發出此命令逐個刪除它們)

git rm -r --cached path-to-those-files

4. 現在進行提交和推送 ,使用這些命令。 這將從git remote中刪除這些文件並使git 停止跟踪這些文件。

git add .
git commit -m "removed unnecessary files from git"
git push origin

git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

這將獲取被忽略文件的列表並將其從索引中刪除,然後提交更改。





git-rm