删除超过X天的存储更改

时间:2017-06-29 06:19:48

标签: git

如何删除超过X天的所有藏匿处?

我在日常工作流程中使用git stash,这意味着我最终会有几个月的旧藏匿处。

1 个答案:

答案 0 :(得分:3)

手动使用git reflog expire

"推动"的基本机制stashes-即,任何名称不仅仅是stashstash@{0}的存储,而是stash@{1}stash@{2}等等 - 是Git的 reflogs 。每当引用更改时,reflog都会记录引用的先前值。 (我将在下面定义引用,并在那里完成 reflog 的定义。)

大多数reflog条目都会通过可配置的gc.reflogExpiregc.reflogExpireUnreachable设置自行过期(请参阅the git config documentationthe git reflog documentation)。但是,refs/stash引用是特殊的:默认情况下,其条目永远不会过期,而不是在30或90天后过期。

您可以手动运行git reflog expire并覆盖其中任何一项。例如:

git reflog expire --expire-unreachable=40.days refs/stash

告诉Git过期任何存储条目,所有存储条目始终无法访问(详见下文),至少有40天之久。将--dry-run添加到选项中以查看哪些内容将过期,而不会实际使它们过期...虽然此处存在一个小缺陷:它不会打印数字,即它从未说过它会折腾,比如stash@{17}

参考文献和reflogs

Git的引用是分支名称,标记名称,远程跟踪分支名称以及Git所具有的所有其他名称的概括。引用只是将名称(例如masterv1.2stash)转换为Git的内部哈希ID之一。

分支名称只是完整名称以refs/heads/开头的引用。标记名称只是一个名称以refs/tags/开头的引用。远程跟踪分支名称是一个引用,其全名以refs/remotes/开头(然后具有远程名称和另一个斜杠)。

一些参考名称,特别是分支,经常发生变化。例如,每次向master添加新提交时,refs/heads/master分支(实际为master)都会更改。每当Git替换引用的存储哈希值时,它可能 - 取决于是否打开reflog - 保存之前的哈希值。这些保存的条目是您的 reflogs

每个reflog条目都有一个时间戳。 Reflog条目最终会老化并过期,因此您最终无法获得数千或数百万个reflog条目。

可访问且无法访问,以及为什么它们不适用于refs/stash

分支名称通常以正向方式移动,例如,一次一个提交。也就是说,我们将 new 提交添加到分支,并且该分支上的所有提交仍然在分支上。有时我们会集中提交并立即将它们全部添加到#34; fast"前进时尚:所有新提交都在分支上,所有旧提交仍然在分支上。分支名称指向分支上的 tip 提交,此图中最右侧是o

...--o--o--o   <-- branch

我们添加了更多提交,分支名称仍然指向提示:

...--o--o--o--o--o--o   <-- branch

但由于每次提交都指向 parent 提交,所有这些提交都可以

但有时,我们故意删除提交,并将其替换为另一个提交。例如,如果我们有提交,但我们没有推送,我们可以使用git commit --amendgit rebase -i进行一些更改。当我们这样做时,旧的不会消失。相反,他们被推到了一边:

...--o--o--X   <-- branch

变为:

          X ...... branch@{1}
         /
...--o--o--Y   <-- branch

其中Y替代X

请注意,Y的父提交不是X,而是X的父级。这意味着提交X 不能从Y访问。

两个单独的&#34; reflogExpire&#34;配置项,对于可访问和不可访问的对象,请参阅可以通过从名为branch的分支的当前值开始找到的提交,即refs/heads/branch Y 1}} - 并向后工作。可以访问提交oX也是如此,但o不是。如果有一个指向早期branch@{1}之一的reflog条目,它可以,但X指向refs/stash,这是不可达

Git的设计人员基本上认为无法访问的提交不太值得,因此他们的reflog条目应该更快到期。因此,无法访问的条目的默认值为30天,可访问的条目的默认值为90天。

stash@{n}引用根本没有正常推进。相反,它指向当前存储,这是一种包装:一个提交 - 实际上至少两个提交,有时更多 - 不在任何分支上(我称之为&#34;存储bag&#34 ;;见How to recover from "git stash save --all"?)。反过来,这意味着可以从当前refs/stash到达 no 之前的{{1}}!因此,每个stash reflog条目始终无法访问。