[英]How do I figure out what file is taking so long to write to my remote git repository?
我在Mac Sierra上使用Git 2.8。 嘗試將本地存儲庫推送到遠程服務器時遇到問題。 這樣做需要很長時間。 我認為這是因為它正在嘗試推送非常大的文件,而我必須無意中簽入了該文件。這是當我嘗試推送內容時發生的情況。 它只是掛起,然后我必須按Ctrl +C。
On branch master
Your branch is ahead of 'origin/master' by 62 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
Counting objects: 609, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (608/608), done.
Writing objects: 20% (124/609), 33.04 MiB | 1.03 MiB/s
localhost:myproject nataliab$ Killed by signal 2.
我如何找出導致掛斷的文件是什么? 我已經嘗試過“ git status”,但是它什么也沒告訴我……
localhost:myproject nataliab$ git status
On branch master
Your branch is ahead of 'origin/master' by 62 commits.
(use "git push" to publish your local commits)
nothing to commit, working directory clean
謝謝你的幫助, -
TL; DR:進行交互式變基並用更好的提交替換您的錯誤提交,或使用BFG(請參閱如何從Git存儲庫的提交歷史記錄中刪除/刪除大文件? )。
在Git中,每次提交都是永久的且不可更改。 此外,提交是歷史記錄:您的最新提交指向第二次最新提交,指向第三次最新提交,依此類推,一直返回到第一次提交。
現在,假設您已提交了一個大文件(例如4.7 GB左右的DVD映像)。 以后,您刪除文件並再次提交。
當您使用git push
生成的提交時,Git將必須(不僅)推動新的提交(該操作會刪除該文件),還會推動創建該文件的較早的提交。
如果Git無法做到這一點,您將無法撤回包含大文件的提交。 Git的全部要點是能夠回憶起每次提交,因此這與版本控制相反。 如果Git僅發送您的最新消息,那將是不受控制的取消版本控制。
這些文件是提交的副作用。 Git就是關於提交的。 文件只是一種偶然的獎勵。 當然,文件首先是提交的目的,但是Git仍然是關於提交的。
您的大文件位於您擁有的提交中的某處,但沒有:
localhost:myproject nataliab$ git status On branch master Your branch is ahead of 'origin/master' by 62 commits. (use "git push" to publish your local commits) nothing to commit, working directory clean
在這62次(可能是1次 )提交中的某個地方,您添加了一些大文件。 大概以后,您大概刪除了它們,但是Git必須推送所有提交。
而且,提交是永久的且不可更改。 您不能更改添加文件的舊提交。 這僅留下一種可能的解決方案: 根本不要推送這些提交 。
您可能並且確實應該反對。 大概您確實想推送(至少其中一些)提交。 但是我要告訴您的是您不想推送這些提交。 您想推送一些稍作改動的更好的提交。
1 “可能”,因為origin/master
是您的Git對其他 Git存儲庫上origin
名稱下的master
的記憶。 此內存並不總是最新的。 您可以運行git fetch origin
來從它們中git fetch origin
最新的提交,從而讓您的Git更新其內存。 但是,如果您是唯一使用另一個存儲庫的人,那么Git的內存將足夠准確。
使用git log
查看您當前正在推送的提交:
$ git log --name-status origin/master..master
--name-status
參數告訴Git將每個提交與上一個提交進行比較(照常),但是然后不顯示完整的git diff
,而是顯示添加,修改和刪除的文件。
您將有一個提交刪除了一些大文件,然后有一個較早的提交添加了那些大文件。 現在,您的工作是更正先前的提交,以便它根本不會添加這些文件。
您實際上無法更改先前的提交! 但是您可以 將其復制到非常相似的提交中:進行幾乎完全相同的提交,只是它不添加大文件。 您進行的新提交將具有相同的父ID,這就是Git跟蹤哪個提交在其他提交之前的方式。 它將具有相同的作者(您),相同的提交者(您),相同的日志消息,甚至可能是相同的日期……但它沒有大文件。
作為將此特定錯誤提交復制到更好的新提交的副作用,您將被迫復制每個后續提交 。 原因是每個提交都記錄其先前的(父)提交ID,而新的和經過改進的副本提交將具有不同的父提交。 因此,現在您需要復制其子級。 新的“子副本”與上一個子副本相同,除了兩件事:父ID和大文件不存在的事實。
對於每次提交,直到刪除大文件的提交,都會重復此操作。 現在, 如果特定的提交只是刪除了大文件,那么您就可以在此時放棄該提交:到目前為止,您一直在制作的每個副本都缺少這些文件,因此將無事可做。 但是,如果該提交除了刪除大文件之外還執行其他操作,則可能會保留其他部分。
此后,您可能只想復制其余的每個提交,只更改其父ID。
有兩種執行這種提交復制的Git命令: git filter-branch
和git rebase -i
。 前者使用起來有些困難,因此,如果您要堅持使用Git附帶的功能,通常建議您使用rebase
,除非您需要復制的提交中包含合並提交(任何此類合並都會顯示在git log
輸出)。
使用filter-branch
和rebase -i
的說明在Greg Bacon對上述問題的鏈接答案中。
盡管我從未使用過BFG,但據報道它的操作要簡單得多。 它不執行filter-branch
和交互式變基的工作,因此它沒有如此復雜的控件。 盡管如此,它仍然復制提交。
Git分支機構的工作方式是名稱 master
指向分支master
的最新提交。 每個提交都指向其先前的對應對象。 因此,一旦您將“錯誤”提交復制到“更好”提交,您的master
將指向最新復制的提交。 該提交指向其父級,依此類推,對於許多人(現在可能是61歲)而言,它都承諾要到達origin/master
點。
另一個Git倉庫( origin
)已經具有該提交和每個更早的提交。 但是現在您可以git push origin master
,您的Git將調用他們的Git,找到要推送的提交,然后開始推送-並且要推送的將是新的,更好的副本 ,而不是原始副本 。
(原件會發生什么?最終,它們會老化並過期並被刪除。如果您希望將它們退回,則至少需要30天才能將它們退回。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.