【问题标题】:Delete stashed changes older than X days删除超过 X 天的隐藏更改
【发布时间】:2017-12-02 17:10:01
【问题描述】:

如何删除所有超过 X 天的存储?

我在日常工作流程中使用git stash,这意味着我最终会得到几个月的旧存储。

【问题讨论】:

  • 也许您的工作流程应该开始使用git stash pop 而不是git stash apply
  • git stash list --before="x days ago" 列出了 x 天之前的所有存储。然后git stash drop 一个接一个。git stash list 有一些适用于git log 的选项。也许有一个 git-stash 子命令可以将它们全部删除。
  • git stash drop stash{@x.days.ago} 通常会在 X 天前删除一个存储。不知道如何解决以删除所有存储.. 可能是git stash drop stash{@x.days.ago..n} 免责声明:我没有尝试过。
  • 谢谢大家,今晚我会试试这个并报告!

标签: git


【解决方案1】:

手动使用git reflog expire

“推送”存储的底层机制——即任何名称不只是stashstash@{0},而是stash@{1}stash@{2} 等的存储——是Git 的reflogs。每当引用发生更改时,reflog 都会记录引用的先前值。 (我会在下面定义reference,并在那里完成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}

引用和引用日志

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

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

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

每个 reflog 条目都有一个时间戳。 Reflog 条目最终会过期并过期,因此您最终不会收到数千或数百万个 reflog 条目。

可达和不可达,以及为什么它们不适用于refs/stash

分支名称通常以向前的方式移动,例如,一次提交一次。也就是说,我们将 new 提交添加到一个分支,并且该分支上的所有 old 提交仍然在该分支上。有时我们会以“快速”前进的方式一次性提取所有提交并添加它们:所有新提交都在分支上,所有旧提交也仍在分支上。分支名称指向分支上的 tip 提交,在这张图中最右边的o

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

我们添加了更多的commits,分支名依然指向tip:

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

但由于每个提交都指向其提交,因此所有这些提交都是可访问的

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

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

变成:

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

其中YX 的替代品。

注意Y的父提交不是X,而是X的父提交。这意味着提交X 无法Y 访问。

两个单独的“reflogExpire”配置项,对于可访问和不可访问的对象,指的是可以从引用的当前值开始找到的提交——对于我们名为branch的分支,那是refs/heads/branch——并且向后工作。提交Y 是可达的,os 也是如此,但X 不是。如果有一个 reflog 条目指向较早的 os 之一,它是可访问的,但 branch@{1} 指向 X,这是 不可访问的

Git 的设计者本质上认为无法访问的提交是不值得的,所以他们的 reflog 条目应该更早过期。因此,不可达条目的默认值为 30 天,可达的条目为 90 天。

但是,refs/stash 引用根本不会正常前进。相反,它指向当前的存储,这是一种侧边的袋子:一个提交——实际上至少两次提交,有时更多——不在任何分支上(我称之为“存储袋”;见How to recover from "git stash save --all"?)。反过来,这意味着 no 以前的stash@{<em>n</em>} 可以从当前的refs/stash 访问,永远!因此,每个 stash reflog 条目在任何时候都是不可访问的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
相关资源
最近更新 更多