All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 2/2] reflog: ignore expire-unreachable for "HEAD" reflog
Date: Wed, 14 Apr 2010 13:35:45 -0700	[thread overview]
Message-ID: <7vfx2xpyam.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <7vljcppycc.fsf@alter.siamese.dyndns.org> (Junio C. Hamano's message of "Wed\, 14 Apr 2010 13\:34\:43 -0700")

"git reflog expire" (and "git gc") examines the reflog entries and
discards old/stale ones using two criteria.  The entries that are older
than "reflogexpire" (defaults to 90 days) are unconditionally removed, and
the entries that are older than "reflogexpireunreachable" (defaults to 30
days) are removed if the entry point at commits that are not reachable
from the value of the ref.

This is reasonable for local branches, remote tracking branches and tags.
You (or other people) may have failed experiments that have been made and
then later discarded by resetting the tip of the branch back, and setting
the value of "reflogexpireunreachable" shorter than that of "reflogexpire"
will prune the entries that describe these failed experiments earlier than
the entries that describe the steps that led to the current history.

It however doesn't make much sense for "HEAD" reflog.  When you switch
between branches, it is normal that the tip of the branch you were on is
not an ancestor of the branch you have switched to.  Expiring the entries
that describe what you did while on the previous branch earlier than usual
does not help.

The test t7701 relied on this incorrect behaviour of entries being pruned
from the "HEAD" reflog.  Work it around by setting the "HEAD" reflog
entries to be expired immediately.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-reflog.c                     |   35 ++++++++++++++++++++++++---------
 t/t7701-repack-unpack-unreachable.sh |    1 +
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/builtin-reflog.c b/builtin-reflog.c
index 9792090..c4bc5be 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -34,8 +34,11 @@ struct cmd_reflog_expire_cb {
 
 struct expire_reflog_cb {
 	FILE *newlog;
-	const char *ref;
-	struct commit *ref_commit;
+	enum {
+		UE_NORMAL,
+		UE_ALWAYS,
+		UE_NEVER
+	} unreachable_expire_kind;
 	struct commit_list *mark_list;
 	unsigned long mark_limit;
 	struct cmd_reflog_expire_cb *cmd;
@@ -304,8 +307,9 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
 	    (!keep_entry(&old, osha1) || !keep_entry(&new, nsha1)))
 		goto prune;
 
-	if (timestamp < cb->cmd->expire_unreachable) {
-		if (!cb->ref_commit)
+	if ((cb->unreachable_expire_kind != UE_NEVER) &&
+	    (timestamp < cb->cmd->expire_unreachable)) {
+		if (cb->unreachable_expire_kind == UE_ALWAYS)
 			goto prune;
 		if (unreachable(cb, old, osha1) || unreachable(cb, new, nsha1))
 			goto prune;
@@ -338,6 +342,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
 	struct expire_reflog_cb cb;
 	struct ref_lock *lock;
 	char *log_file, *newlog_path = NULL;
+	struct commit *tip_commit;
 	int status = 0;
 
 	memset(&cb, 0, sizeof(cb));
@@ -357,18 +362,28 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
 		cb.newlog = fopen(newlog_path, "w");
 	}
 
-	cb.ref_commit = lookup_commit_reference_gently(sha1, 1);
-	cb.ref = ref;
 	cb.cmd = cmd;
-	if (cb.ref_commit) {
+
+	if (!cmd->expire_unreachable || !strcmp(ref, "HEAD")) {
+		tip_commit = NULL;
+		cb.unreachable_expire_kind = UE_NEVER;
+	} else {
+		tip_commit = lookup_commit_reference_gently(sha1, 1);
+		if (!tip_commit)
+			cb.unreachable_expire_kind = UE_ALWAYS;
+		else
+			cb.unreachable_expire_kind = UE_NORMAL;
+	}
+
+	if (cb.unreachable_expire_kind == UE_NORMAL) {
 		cb.mark_list = NULL;
-		commit_list_insert(cb.ref_commit, &cb.mark_list);
+		commit_list_insert(tip_commit, &cb.mark_list);
 		cb.mark_limit = cmd->expire_total;
 		mark_reachable(&cb);
 	}
 	for_each_reflog_ent(ref, expire_reflog_ent, &cb);
-	if (cb.ref_commit)
-		clear_commit_marks(cb.ref_commit, REACHABLE);
+	if (cb.unreachable_expire_kind == UE_NORMAL)
+		clear_commit_marks(tip_commit, REACHABLE);
  finish:
 	if (cb.newlog) {
 		if (fclose(cb.newlog)) {
diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh
index 5babdf2..e14b110 100755
--- a/t/t7701-repack-unpack-unreachable.sh
+++ b/t/t7701-repack-unpack-unreachable.sh
@@ -9,6 +9,7 @@ csha1=
 tsha1=
 
 test_expect_success '-A with -d option leaves unreachable objects unpacked' '
+	git config gc.HEAD.reflogexpire now &&
 	echo content > file1 &&
 	git add . &&
 	git commit -m initial_commit &&
-- 
1.7.1.rc1.252.gce30c

  reply	other threads:[~2010-04-14 20:36 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-14 20:34 [PATCH 1/2] Document gc.<pattern>.reflogexpire variables Junio C Hamano
2010-04-14 20:35 ` Junio C Hamano [this message]
2010-04-15  6:45   ` [PATCH 2/2] reflog: ignore expire-unreachable for "HEAD" reflog Johannes Sixt
2010-04-15  7:40     ` Junio C Hamano
2010-04-15  8:49       ` Johannes Sixt
2010-04-15 12:30         ` Junio C Hamano
2010-04-15 12:58           ` Johannes Sixt
2010-04-15 16:36             ` Jeff King
2010-04-15 16:57               ` Junio C Hamano
2010-04-15 19:48                 ` Nicolas Pitre
2010-04-15 22:42                   ` Junio C Hamano
2010-04-16  1:11                     ` Nicolas Pitre
2010-04-16  1:37                       ` Junio C Hamano
2010-04-16  3:07                         ` Nicolas Pitre
2010-04-16  6:08               ` Johannes Sixt
2010-04-15 16:49             ` Junio C Hamano

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=7vfx2xpyam.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    /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.