From: Junio C Hamano <gitster@pobox.com>
To: しらいしななこ <nanako3@bluebottle.com>
Cc: Wincent Colaiuta <win@wincent.com>,
Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Eric Raible <raible@gmail.com>,
Git Mailing List <git@vger.kernel.org>,
Nicolas Pitre <nico@cam.org>
Subject: Re: [PATCH 2/2] git-gc: skip stashes when expiring reflogs
Date: Mon, 16 Jun 2008 00:21:21 -0700 [thread overview]
Message-ID: <7vy755c0b2.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <7vabhne15k.fsf@gitster.siamese.dyndns.org> (Junio C. Hamano's message of "Sat, 14 Jun 2008 22:07:51 -0700")
Junio C Hamano <gitster@pobox.com> writes:
> I think the steps from here on would be:
>
> - Apply the patch in your message I am responding to, so that a stash
> that is kept forever will not pin the unnecessary history behind it in
> the repository. As you said there is no reason to make the base commit
> (H) actually the same as the commit in the true history --- the only
> thing we care about it is its tree object;
>
> - Design and decide the way to tell git to make stash entries unexpirable
> (or maybe have very long expiration period). I am leaning toward a
> configuration option that lets you specify expiration period per ref,
> rather than marking individual reflog entries as I suggested earlier;
>
> - Make the default for new repositories' stash reflog expiry period
> "never", by setting the above configuration upon "git init".
>
> None of the above should obviously be in 1.5.6, but I think even the third
> step to the change the default would be acceptable in the next 1.6.0
> release.
So here is the second step from the above list. I did not write any test
nor docs, but if people are so keen to see permanent stashes supported, I
am reasonably sure that they will contribute by filling the gap even if I
do not do anything further ;-)
Obviously this will _not_ come anywhere near 'master' nor 'next' until
1.5.6 ships.
-- >8 --
From: Junio C Hamano <gitster@pobox.com>
Date: Sun, 15 Jun 2008 23:48:46 -0700
Subject: [PATCH] Per-ref reflog expiry configuration
In addition to gc.reflogexpireunreachable and gc.reflogexpire, this lets
you set gc.<pattern>.reflogexpireunreachable and gc.<pattern>.reflogexpire
variables.
When "git reflog expire" expires reflog entry for $ref, the expiry timers
are taken from the first <pattern> that matches $ref (and if there isn't
the global default value is used).
For example, you could:
[gc "refs/stash"]
reflogexpire = never
reflogexpireunreachable = never
[gc "refs/remotes/*"]
reflogexpire = 7 days
reflogexpireunreachable = 3 days
[gc]
reflogexpire = 90 days
reflogexpireunreachable = 30 days
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-reflog.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 126 insertions(+), 19 deletions(-)
diff --git a/builtin-reflog.c b/builtin-reflog.c
index b151e24..eec14c7 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -269,7 +269,9 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
int status = 0;
memset(&cb, 0, sizeof(cb));
- /* we take the lock for the ref itself to prevent it from
+
+ /*
+ * we take the lock for the ref itself to prevent it from
* getting updated.
*/
lock = lock_any_ref_for_update(ref, sha1, 0);
@@ -331,21 +333,119 @@ static int collect_reflog(const char *ref, const unsigned char *sha1, int unused
return 0;
}
-static int reflog_expire_config(const char *var, const char *value, void *cb)
+static struct reflog_expire_cfg {
+ struct reflog_expire_cfg *next;
+ unsigned long expire_total;
+ unsigned long expire_unreachable;
+ size_t len;
+ char pattern[FLEX_ARRAY];
+} *reflog_expire_cfg, **reflog_expire_cfg_tail;
+
+static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
{
- if (!strcmp(var, "gc.reflogexpire")) {
- if (!value)
- config_error_nonbool(var);
- default_reflog_expire = approxidate(value);
+ struct reflog_expire_cfg *ent;
+
+ if (!reflog_expire_cfg_tail)
+ reflog_expire_cfg_tail = &reflog_expire_cfg;
+
+ for (ent = reflog_expire_cfg; ent; ent = ent->next)
+ if (ent->len == len &&
+ !memcmp(ent->pattern, pattern, len))
+ return ent;
+
+ ent = xcalloc(1, (sizeof(*ent) + len));
+ memcpy(ent->pattern, pattern, len);
+ ent->len = len;
+ *reflog_expire_cfg_tail = ent;
+ reflog_expire_cfg_tail = &(ent->next);
+ return ent;
+}
+
+static int parse_expire_cfg_value(const char *var, const char *value, unsigned long *expire)
+{
+ if (!value)
+ return config_error_nonbool(var);
+ if (!strcmp(value, "never") || !strcmp(value, "false")) {
+ *expire = 0;
return 0;
}
- if (!strcmp(var, "gc.reflogexpireunreachable")) {
- if (!value)
- config_error_nonbool(var);
- default_reflog_expire_unreachable = approxidate(value);
+ *expire = approxidate(value);
+ return 0;
+}
+
+/* expiry timer slot */
+#define EXPIRE_TOTAL 01
+#define EXPIRE_UNREACH 02
+
+static int reflog_expire_config(const char *var, const char *value, void *cb)
+{
+ const char *lastdot = strrchr(var, '.');
+ unsigned long expire;
+ int slot;
+ struct reflog_expire_cfg *ent;
+
+ if (!lastdot || prefixcmp(var, "gc."))
+ return git_default_config(var, value, cb);
+
+ if (!strcmp(lastdot, ".reflogexpire")) {
+ slot = EXPIRE_TOTAL;
+ if (parse_expire_cfg_value(var, value, &expire))
+ return -1;
+ } else if (!strcmp(lastdot, ".reflogexpireunreachable")) {
+ slot = EXPIRE_UNREACH;
+ if (parse_expire_cfg_value(var, value, &expire))
+ return -1;
+ } else
+ return git_default_config(var, value, cb);
+
+ if (lastdot == var + 2) {
+ switch (slot) {
+ case EXPIRE_TOTAL:
+ default_reflog_expire = expire;
+ break;
+ case EXPIRE_UNREACH:
+ default_reflog_expire_unreachable = expire;
+ break;
+ }
return 0;
}
- return git_default_config(var, value, cb);
+
+ ent = find_cfg_ent(var + 3, lastdot - (var+3));
+ if (!ent)
+ return -1;
+ switch (slot) {
+ case EXPIRE_TOTAL:
+ ent->expire_total = expire;
+ break;
+ case EXPIRE_UNREACH:
+ ent->expire_unreachable = expire;
+ break;
+ }
+ return 0;
+}
+
+static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, const char *ref)
+{
+ struct reflog_expire_cfg *ent;
+
+ if (slot == (EXPIRE_TOTAL|EXPIRE_UNREACH))
+ return; /* both given explicitly -- nothing to tweak */
+
+ for (ent = reflog_expire_cfg; ent; ent = ent->next) {
+ if (!fnmatch(ent->pattern, ref, 0)) {
+ if (!(slot & EXPIRE_TOTAL))
+ cb->expire_total = ent->expire_total;
+ if (!(slot & EXPIRE_UNREACH))
+ cb->expire_unreachable = ent->expire_unreachable;
+ return;
+ }
+ }
+
+ /* Nothing matched -- set the default value */
+ if (!(slot & EXPIRE_TOTAL))
+ cb->expire_total = default_reflog_expire;
+ if (!(slot & EXPIRE_UNREACH))
+ cb->expire_unreachable = default_reflog_expire_unreachable;
}
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
@@ -353,6 +453,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
struct cmd_reflog_expire_cb cb;
unsigned long now = time(NULL);
int i, status, do_all;
+ int explicit_expiry = 0;
git_config(reflog_expire_config, NULL);
@@ -367,20 +468,18 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
cb.expire_total = default_reflog_expire;
cb.expire_unreachable = default_reflog_expire_unreachable;
- /*
- * We can trust the commits and objects reachable from refs
- * even in older repository. We cannot trust what's reachable
- * from reflog if the repository was pruned with older git.
- */
-
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
cb.dry_run = 1;
- else if (!prefixcmp(arg, "--expire="))
+ else if (!prefixcmp(arg, "--expire=")) {
cb.expire_total = approxidate(arg + 9);
- else if (!prefixcmp(arg, "--expire-unreachable="))
+ explicit_expiry |= EXPIRE_TOTAL;
+ }
+ else if (!prefixcmp(arg, "--expire-unreachable=")) {
cb.expire_unreachable = approxidate(arg + 21);
+ explicit_expiry |= EXPIRE_UNREACH;
+ }
else if (!strcmp(arg, "--stale-fix"))
cb.stalefix = 1;
else if (!strcmp(arg, "--rewrite"))
@@ -400,6 +499,12 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
else
break;
}
+
+ /*
+ * We can trust the commits and objects reachable from refs
+ * even in older repository. We cannot trust what's reachable
+ * from reflog if the repository was pruned with older git.
+ */
if (cb.stalefix) {
init_revisions(&cb.revs, prefix);
if (cb.verbose)
@@ -417,6 +522,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
for_each_reflog(collect_reflog, &collected);
for (i = 0; i < collected.nr; i++) {
struct collected_reflog *e = collected.e[i];
+ set_reflog_expiry_param(&cb, explicit_expiry, e->reflog);
status |= expire_reflog(e->reflog, e->sha1, 0, &cb);
free(e);
}
@@ -430,6 +536,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
status |= error("%s points nowhere!", ref);
continue;
}
+ set_reflog_expiry_param(&cb, explicit_expiry, ref);
status |= expire_reflog(ref, sha1, 0, &cb);
}
return status;
--
1.5.6.rc3.7.g336d0
next prev parent reply other threads:[~2008-06-16 7:22 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <OLvkESB0JjBNs9kF8Q2M5UFNBJqq4FjbgGeQVyWstGwcXqCOq16_oomM0y-utOBbV7BnndyrICE@cipher.nrlssc.navy.mil>
2008-06-11 21:29 ` [PATCH 2/2] git-gc: skip stashes when expiring reflogs Brandon Casey
2008-06-11 21:36 ` Mike Hommey
2008-06-11 21:44 ` Johannes Schindelin
2008-06-11 23:03 ` Jeff King
2008-06-11 23:21 ` Nicolas Pitre
2008-06-12 4:32 ` Eric Raible
2008-06-12 5:35 ` Wincent Colaiuta
2008-06-12 14:14 ` Nicolas Pitre
2008-06-12 20:13 ` Junio C Hamano
2008-06-12 20:35 ` Eric Raible
2008-06-12 20:51 ` Junio C Hamano
2008-06-12 21:36 ` Eric Raible
2008-06-13 4:52 ` Johannes Schindelin
2008-06-13 8:43 ` Wincent Colaiuta
2008-06-13 9:13 ` Jeff King
2008-06-13 21:41 ` Johannes Schindelin
2008-06-13 23:33 ` Christian Jaeger
2008-06-14 8:58 ` Wincent Colaiuta
2008-06-14 23:59 ` しらいしななこ
[not found] ` <200806142359.m5ENxsBL028758@mi0.bluebottle.com>
2008-06-15 4:00 ` Johannes Schindelin
[not found] ` <200806142359.m5ENxsBI028758 @mi0.bluebottle.com>
2008-06-15 5:07 ` Junio C Hamano
2008-06-16 3:33 ` Eric Raible
2008-06-16 7:21 ` Junio C Hamano [this message]
2008-06-17 9:05 ` Johannes Schindelin
2008-06-17 21:54 ` Junio C Hamano
2008-06-18 15:25 ` Johannes Schindelin
2008-06-18 18:58 ` Junio C Hamano
2008-06-16 16:30 ` Brandon Casey
2008-06-16 16:52 ` Jakub Narebski
2008-06-13 12:05 ` Mikael Magnusson
2008-06-12 21:27 ` Brandon Casey
2008-06-12 21:46 ` Junio C Hamano
2008-06-12 22:10 ` Brandon Casey
2008-06-13 3:45 ` しらいしななこ
2008-06-13 4:26 ` Andreas Ericsson
2008-06-13 5:58 ` Jeff King
2008-06-13 7:16 ` Andreas Ericsson
2008-06-13 7:42 ` Jeff King
2008-06-13 8:11 ` Andreas Ericsson
2008-06-13 8:51 ` Jakub Narebski
2008-06-13 8:56 ` Sverre Rabbelier
2008-06-13 9:10 ` Jeff King
2008-06-13 11:14 ` Miles Bader
2008-06-13 9:47 ` Junio C Hamano
2008-06-13 10:05 ` Jakub Narebski
2008-06-13 10:33 ` Sverre Rabbelier
2008-06-13 17:31 ` Olivier Marin
2008-06-13 19:21 ` Junio C Hamano
2008-06-13 19:35 ` Wincent Colaiuta
2008-06-13 19:42 ` Brandon Casey
2008-06-13 19:49 ` Olivier Marin
2008-06-14 1:16 ` しらいしななこ
2008-06-13 12:40 ` Wincent Colaiuta
2008-06-13 13:11 ` Jeff King
2008-06-13 17:03 ` Olivier Marin
2008-06-13 13:54 ` Jon Loeliger
2008-06-13 16:54 ` Brandon Casey
2008-06-11 23:25 ` Brandon Casey
2008-06-12 4:18 ` Jeff King
2008-06-12 16:46 ` Brandon Casey
2008-06-13 5:48 ` Jeff King
2008-06-13 8:41 ` Wincent Colaiuta
2008-06-13 8:53 ` Sverre Rabbelier
2008-06-13 9:07 ` Teemu Likonen
2008-06-13 9:04 ` Jeff King
2008-06-13 11:22 ` Miles Bader
2008-06-13 16:43 ` Brandon Casey
2008-06-13 17:30 ` Jeff King
2008-06-11 22:35 ` Brandon Casey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vy755c0b2.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=nanako3@bluebottle.com \
--cc=nico@cam.org \
--cc=raible@gmail.com \
--cc=win@wincent.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).