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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.