删除超过X天的隐藏更改 [英] Delete stashed changes older than X days

查看:58
本文介绍了删除超过X天的隐藏更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何删除所有早于X天的藏匿处?

How could I delete all stashes older than X days?

我在我的日常工作流程中使用git stash,这意味着我最终会被保存数月之久.

I use git stash in my everyday workflow, which means I end up with months of old stashes.

推荐答案

手动使用git reflog expire

推送"存储的基本机制(即名称不只是stashstash@{0}而是stash@{1}stash@{2}等的任何存储)是Git的 reflogs .只要引用发生更改,reflog就会记录引用的上一个值. (我将在下面定义 reference ,并在其中完成 reflog 的定义.)

Use git reflog expire manually

The underlying mechanism for "pushed" stashes—i.e., any stash whose name is not just stash or stash@{0}, but rather stash@{1}, stash@{2}, and so on—is Git's reflogs. The reflog records the previous value of a reference, whenever the reference changes. (I'll define reference below, and complete the definition of the reflog there.)

大多数reflog条目通过可配置的gc.reflogExpiregc.reflogExpireUnreachable设置自行失效(请参阅

Most reflog entries expire on their own, through the configurable gc.reflogExpire and gc.reflogExpireUnreachable settings (see both the git config documentation and the git reflog documentation). The refs/stash reference, however, is special: by default, its entries never expire, rather than expiring after 30 or 90 days.

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

You can run git reflog expire manually and override any of these. For instance:

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

告诉Git过期至少40天的所有隐藏条目(所有这些条目始终不可访问)(请参见下文).在选项中添加--dry-run可以查看哪些会过期,而实际上并不会过期...尽管这里有一个小缺陷:它不会打印其 numbers ,即,它从未说过要折腾,例如stash@{17}.

tells Git to expire any stash entries, all of which are always unreachable (see below for details), that are at least 40 days old. Add --dry-run to the options to see which ones would expire, without actually expiring them ... though there is a minor flaw here: it does not print their numbers, i.e., it never says that it's going to toss, say, stash@{17}.

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

Git's references are a generalization of branch names, tag names, remote-tracking branch names, and all those other names that Git has. A reference simply translates a name—something like master or v1.2 or stash—to one of Git's internal hash IDs.

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

A branch name is just a reference whose full name starts with refs/heads/. A tag name is just a reference whose full name starts with refs/tags/. A remote-tracking branch name is a reference whose full name starts with refs/remotes/ (and then has the name of the remote and another slash).

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

Some reference names, particularly branches, change quite often. For instance, your master branch, which is really refs/heads/master, changes every time you add a new commit to master. Whenever Git replaces the stored hash value for a reference, it may—depending on whether reflogs are turned on—save the previous hash value. These saved entries are your reflogs.

每个reflog条目都有一个时间戳. Reflog条目最终会过期并过期,因此您不会收到成千上万个reflog条目.

Each reflog entry has a time stamp. Reflog entries eventually age out and get expired, so that you do not wind up with thousands or millions of reflog entries.

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

Branch names normally move in a forward fashion, e.g., one commit at a time. That is, we add new commits to a branch, and all the old commits that were on that branch are still on the branch. Sometimes we will pick up commits en-masse and add them all at once, in a "fast" forward fashion: all the new commits are on the branch, and all the old commits are also still on the branch. The branch name points to the tip commit on the branch, the right-most o in this diagram:

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

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

We add more commits, and the branch name still points to the tip:

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

但是由于每个提交都指向其 parent 提交,因此 all 这些提交都是 reachable .

but since each commit points back to its parent commit, all these commits are reachable.

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

Sometimes, though, we deliberately remove a commit, and replace it with another. For instance, if we have commits we have not pushed, we can use git commit --amend or git rebase -i to make some changes. When we do that, the old ones don't go away just get. Instead, they get shoved to the side:

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

成为:

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

其中Y是我们替换X的地方.

where Y is our replacement for X.

请注意,Y的父提交不是X,而是X的父提交.这意味着X不能从Y到达 .

Note that the parent commit of Y is not X, but rather X's parent. This means commit X is not reachable from Y.

对于可访问对象和不可访问对象,两个单独的"reflogExpire"配置项是指可以通过从引用的 current 值开始找到的提交(对于我们名为branch的分支,这是refs/heads/branch,并且向后工作.提交Y可以访问,o也是可以访问的,但X不能访问.如果有一个reflog条目指向较早的o之一,则它是 reachable ,但是branch@{1}指向X,它是 unreachable .

The two separate "reflogExpire" configuration items, for reachable and unreachable objects, refer to commits that can be found by starting at the current value of the reference—for our branch named branch, that's refs/heads/branch—and working backwards. Commit Y is reachable, and so are the os, but X is not. If there is a reflog entry pointing to one of the earlier os, it's reachable, but branch@{1} points to X which is unreachable.

Git的设计师从本质上认为无法实现的提交不那么值得,因此他们的reflog条目应尽快过期.因此,对于 unreachable 条目,默认值为30天,对于可达的条目,默认值为90天.

Git's designers essentially believe that unreachable commits are less worthy, so their reflog entries should expire sooner. Thus, the default is 30 days for unreachable entries, and 90 days for the reachable ones.

但是,refs/stash参考完全无法正常前进.相反,它指向当前的存储区,这是一种袋子":一次提交-实际上至少两次提交,有时更多次提交-不在任何分支上(我称其为存储袋";参见如何从"git stash save --all"中恢复?).反过来,这意味着从当前refs/stash可以访问到 no 以前的stash@{n}!因此,每个隐藏reflog条目始终无法访问.

The refs/stash reference, though, does not advance normally at all. Instead, it points to the current stash, which is a sort of bag-on-the-side: a commit—actually at least two commits and sometimes more—that is not on any branch (I call this a "stash bag"; see How to recover from "git stash save --all"?). This, in turn, means that no previous stash@{n} is reachable from the current refs/stash, ever! Every stash reflog entry is therefore unreachable at all times.

这篇关于删除超过X天的隐藏更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆