2016-12-29 95 views
3

我有一個小的回購有一對夫婦提交的:一個Git復位後,可達承諾不刪除

* a0fc4f8 (HEAD -> testbranch) added file.txt 
* e6e6a8b (master) hello world now 
* f308f53 Made it echo 
* f705657 Added hello 
* 08a2de3 (tag: initial) initial 

另外:

$ git status 
On branch testbranch 
nothing to commit, working directory clean 

我無法理解以下行爲。在這種狀態下我運行: $ git reset initial
我現在看到:

* e6e6a8b (master) hello world now 
* f308f53 Made it echo 
* f705657 Added hello 
* 08a2de3 (HEAD -> testbranch, tag: initial) initial 

我所期待的:提交a0fc4f8將被刪除,因爲它是不可達。
發生了什麼事:
1)做git show a0fc4f8仍顯示提交
2)做git status顯示被添加的file.txt提交a0fc4f8爲未跟蹤和文件你好,是由提交f705657加入也顯示爲未跟蹤。
3)運行git gcgit gc --prune=all不會刪除a0fc4f8,儘管它不再可及,並且沒有與其關聯的名稱/標記。
這是爲什麼發生?

更新:

$ git fsck 
Checking object directories: 100% (256/256), done. 
Checking objects: 100% (15/15), done.  

更新2:

$ git log --all --decorate --graph --oneline 
* e6e6a8b (master) hello world now 
* f308f53 Made it echo 
* f705657 Added hello 
* 08a2de3 (HEAD -> testbranch, tag: initial) initial 

$ git gc --force 
Counting objects: 15, done. 
Delta compression using up to 4 threads. 
Compressing objects: 100% (8/8), done. 
Writing objects: 100% (15/15), done. 
Total 15 (delta 1), reused 15 (delta 1) 

$ git log --all --decorate --graph --oneline 
* e6e6a8b (master) hello world now 
* f308f53 Made it echo 
* f705657 Added hello 
* 08a2de3 (HEAD -> testbranch, tag: initial) initial 

$ git的節目a0fc4f8仍顯示提交

更新3:

$ git reflog testbranch 
08a2de3 [email protected]{0}: reset: moving to initial 
a0fc4f8 [email protected]{1}: commit: added file.txt 
e6e6a8b [email protected]{2}: branch: Created from HEAD 
+0

'git fcck'在'git gc --prune = all'後面說了什麼? –

+0

@MichałWalenciak:請檢查更新 – Jim

+1

如果您運行'git reset(--mixed)initial',那麼您的工作目錄是未觸及的,這就是爲什麼'a0fc4f8'提交中有所有更改的原因。 – C1sc0

回答

5

1)否則git show a0fc4f8仍顯示提交

這是由設計。不可達的對象不是有幾個原因立即刪除:

  • 也許你錯誤地跑了最後的命令(或提供錯誤的參數給它),你會發現錯誤,並希望回到以前的狀態;
  • 與完成操作所需的工作量相比,刪除不可訪問的對象(節省一定量的磁盤空間)的收益太小。

修剪不可達對象時會自動執行。它也是由一些git命令執行的(其中一些是fetchpush)。

2)否則git status表明,加入按提交a0fc4f8作爲未跟蹤和文件被提交f705657加入hellofile.txt也顯示爲未跟蹤。

您運行git reset而沒有指定模式。默認模式是--mixed,這意味着:

  • 分支移動到該命令(initial在這種情況下)的提交指定;
  • 重置索引以匹配分支指向的新提交;
  • 工作樹未被修改。

這就解釋了爲什麼文件在目錄(第三顆子彈),爲什麼他們是未經跟蹤(第二子彈;該指數相匹配的initial承諾,但在創建時根本不存在這些文件)。

3)運行git gcgit gc --prune=all不會刪除a0fc4f8雖然它不是能再連接,並具有與之關聯的名稱/標籤。

git gc還檢查分支reflogs的參考。如果您的testbranch分支啓用reflog,則reflog中的最新條目指向提交a0fc4f8(這是testbranch分支在運行git reset之前的位置)。您可以通過運行git reflog testbranch來檢查分支testbranch是否啓用了引用日誌。如果它打印了某些內容,則會在第二行的位置[email protected]{1}處找到提交a0fc4f8。表示nth分支name(它指向的提交,n移動過去)的值。

您可以在documentation中找到更多關於git gc工作方式的信息。

節記載:

git gc嘗試很難成爲它收集垃圾的安全。特別是,它不僅會保存當前一組分支和標記所引用的對象,還會保留由索引引用的對象,遠程跟蹤分支,由git filter-branch保存在refs/original/中的引用或引用日誌(可引用分支中的提交後來修改或倒帶)。

如果您希望收集某些對象並且不收集這些對象,請檢查所有這些位置,然後決定在您的情況下刪除這些引用是否有意義。

+0

我在reflog中看到'a0fc4f8',但它不是最近的入口嗎?請看更新的OP – Jim

+0

你是對的,這是第二個條目。第一個條目('testbranch @ {0}',最近的)是分支的當前位置。 ['testbranch @ {1}'](https://git-scm.com/docs/gitrevisions#gitrevisions-emltrefnamegtltngtemegemmaster1em)是它以前的位置(即'git reset'移動之前的位置)。 – axiac

+0

因此,如果推薦有一個參考git gc忽略它的東西?但是這意味着git gc永遠不會刪除提交嗎?那個提交不會總是成爲reflog歷史記錄的一部分嗎? – Jim