git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).