* [RFC] git reflog show
@ 2006-12-23 10:19 Shawn Pearce
2006-12-23 10:42 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Shawn Pearce @ 2006-12-23 10:19 UTC (permalink / raw)
To: Junio C Hamano, git
I'm toying with what a 'git reflog show' might look like. I attached
the prototype code below. Here's the output from the recent part of
my mmap pack window topic:
$ ./git-reflog show refs/heads/sp/mapwin
...clipped for space...
ref sp/mapwin@{10}
commit f6ec09f.. -> 1960ea7..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:46:07 2006 -0500
commit (amend): Support unmapping windows on 'temporary' packfiles.
ref sp/mapwin@{9}
commit 1960ea7.. -> e70352c..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:49:10 2006 -0500
commit: Create pack_report() as a debugging aid.
ref sp/mapwin@{8}
commit e70352c.. -> 161cd2d..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:53:48 2006 -0500
commit (amend): Create pack_report() as a debugging aid.
ref sp/mapwin@{7}
commit 161cd2d.. -> 81e4d26..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:03 2006 -0500
reset --hard
ref sp/mapwin@{6}
commit 81e4d26.. -> e69e59b..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:44 2006 -0500
commit (amend): Fully activate the sliding window pack access.
ref sp/mapwin@{5}
commit e69e59b.. -> 11bedbb..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:51 2006 -0500
am: Load core configuration in git-verify-pack.
ref sp/mapwin@{4}
commit 11bedbb.. -> 88035fd..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:52 2006 -0500
am: Ensure core.packedGitWindowSize cannot be less than 2 pages.
ref sp/mapwin@{3}
commit 88035fd.. -> b3b706e..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:52 2006 -0500
am: Improve error message when packfile mmap fails.
ref sp/mapwin@{2}
commit b3b706e.. -> 62c8beb..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:52 2006 -0500
am: Support unmapping windows on 'temporary' packfiles.
ref sp/mapwin@{1}
commit 62c8beb.. -> 6b43fd0..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 01:58:52 2006 -0500
am: Create pack_report() as a debugging aid.
ref sp/mapwin@{0}
commit 6b43fd0.. -> bbdc8fa..
User: Shawn O. Pearce <spearce@spearce.org>
Date: Sat Dec 23 02:06:23 2006 -0500
commit: Test suite for sliding window mmap implementation.
diff --git a/builtin-reflog.c b/builtin-reflog.c
index d4f7353..7156a2c 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -161,8 +161,173 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
return status;
}
+struct cmd_reflog_list_ref
+{
+ const char *name;
+ unsigned int ent_cnt;
+};
+
+struct cmd_reflog_list_ent
+{
+ struct cmd_reflog_list_ent* next;
+ struct cmd_reflog_list_ref *ref;
+ const char *cmd;
+ char *user;
+ unsigned long timestamp;
+ int tz;
+ unsigned int pos;
+ unsigned char old_sha1[20];
+ unsigned char new_sha1[20];
+};
+
+struct cmd_reflog_list_cb
+{
+ struct cmd_reflog_list_ent* entries;
+ struct cmd_reflog_list_ref* cur_ref;
+ unsigned int ref_cnt;
+ unsigned int ent_cnt;
+};
+
+static int list_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
+ char *data, void *cb_data)
+{
+ struct cmd_reflog_list_cb *cb = cb_data;
+ struct cmd_reflog_list_ent *e;
+ unsigned long timestamp;
+ int tz;
+ char *user_end, *cp, *ep;
+
+ cp = strchr(data, '>');
+ if (!cp || *++cp != ' ')
+ return 0; /* corrupt line? */
+ user_end = cp;
+ timestamp = strtoul(cp, &ep, 10);
+ if (*ep++ != ' ')
+ return 0; /* corrupt line? */
+ tz = strtol(ep, &cp, 10);
+ if (*cp++ != '\t')
+ return 0; /* corrupt line? */
+
+ e = xmalloc(sizeof(*e));
+ e->ref = cb->cur_ref;
+ e->cmd = xstrdup(cp);
+ e->user = xmalloc(user_end - data + 1);
+ strncpy(e->user, data, user_end - data);
+ e->user[user_end - data] = 0;
+ e->timestamp = timestamp;
+ e->tz = tz;
+ e->pos = cb->cur_ref->ent_cnt++;
+ hashcpy(e->old_sha1, osha1);
+ hashcpy(e->new_sha1, nsha1);
+ e->next = cb->entries;
+ cb->entries = e;
+ cb->ent_cnt++;
+ return 0;
+}
+
+static int list_reflog(const char *ref, const unsigned char *sha1,
+ int unused, void *cb_data)
+{
+ struct cmd_reflog_list_cb *cb = cb_data;
+
+ cb->ref_cnt++;
+ cb->cur_ref = xmalloc(sizeof(*cb->cur_ref));
+ cb->cur_ref->name = xstrdup(ref);
+ cb->cur_ref->ent_cnt = 0;
+ for_each_reflog_ent(ref, list_reflog_ent, cb);
+ return 0;
+}
+
+static int list_cmp(const void *_a, const void *_b)
+{
+ const struct cmd_reflog_list_ent *a = *((void**)_a);
+ const struct cmd_reflog_list_ent *b = *((void**)_b);
+ if (a->ref == b->ref)
+ return a->pos < b->pos ? -1 : 1;
+ if (a->timestamp < b->timestamp)
+ return -1;
+ if (a->timestamp == b->timestamp)
+ return 0;
+ return 1;
+}
+
+static void reflog_show(struct cmd_reflog_list_ent *e)
+{
+ const char *ref = e->ref->name;
+ if (!strncmp("refs/heads/", ref, 11))
+ ref += 11;
+ printf("ref %s@{%u}\n", ref, e->ref->ent_cnt - e->pos - 1);
+ printf("commit ");
+ if (is_null_sha1(e->old_sha1))
+ printf("deleted");
+ else
+ printf("%s..", find_unique_abbrev(e->old_sha1, DEFAULT_ABBREV));
+ printf(" -> ");
+ if (is_null_sha1(e->new_sha1))
+ printf("deleted");
+ else
+ printf("%s..", find_unique_abbrev(e->new_sha1, DEFAULT_ABBREV));
+ printf("\n");
+ printf("User: %s\n", e->user);
+ printf("Date: %s\n", show_date(e->timestamp, e->tz, 0));
+ printf("\n");
+ printf(" %s\n", e->cmd);
+}
+
+static const char reflog_show_usage[] =
+"git-reflog show [--all|<refs>...]";
+
+static int cmd_reflog_show(int argc, const char **argv, const char *prefix)
+{
+ struct cmd_reflog_list_cb cb;
+ unsigned char sha1[20];
+ int i, do_all = 0, status = 0;
+ struct cmd_reflog_list_ent **ent_arr;
+ struct cmd_reflog_list_ent *e;
+
+ cb.ref_cnt = 0;
+ cb.ent_cnt = 0;
+ cb.entries = NULL;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (!strcmp(arg, "--all"))
+ do_all = 1;
+ else if (arg[0] == '-')
+ usage(reflog_show_usage);
+ else
+ break;
+ }
+ if (do_all)
+ status |= for_each_ref(list_reflog, &cb);
+ while (i < argc) {
+ const char *ref = argv[i++];
+ if (!resolve_ref(ref, sha1, 1, NULL))
+ status |= error("no such ref: %s", ref);
+ else
+ status |= list_reflog(ref, sha1, 0, &cb);
+ }
+ if (!cb.ref_cnt) {
+ const char *ref = "HEAD";
+ if (!resolve_ref(ref, sha1, 1, NULL))
+ status |= error("no such ref: %s", ref);
+ else
+ status |= list_reflog(ref, sha1, 0, &cb);
+ }
+
+ ent_arr = xmalloc(cb.ent_cnt * sizeof(*ent_arr));
+ for (i = 0, e = cb.entries; e; i++, e = e->next)
+ ent_arr[i] = e;
+ qsort(ent_arr, cb.ent_cnt, sizeof(*ent_arr), list_cmp);
+
+ for (i = 0; i < cb.ent_cnt; i++)
+ reflog_show(ent_arr[i]);
+
+ return status;
+}
+
static const char reflog_usage[] =
-"git-reflog (expire | ...)";
+"git-reflog (expire | show | ...)";
int cmd_reflog(int argc, const char **argv, const char *prefix)
{
@@ -170,6 +335,8 @@ int cmd_reflog(int argc, const char **argv, const char *prefix)
usage(reflog_usage);
else if (!strcmp(argv[1], "expire"))
return cmd_reflog_expire(argc - 1, argv + 1, prefix);
+ else if (!strcmp(argv[1], "show"))
+ return cmd_reflog_show(argc - 1, argv + 1, prefix);
else
usage(reflog_usage);
}
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-23 10:19 [RFC] git reflog show Shawn Pearce
@ 2006-12-23 10:42 ` Junio C Hamano
2006-12-23 14:53 ` Johannes Schindelin
0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2006-12-23 10:42 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
Shawn Pearce <spearce@spearce.org> writes:
> I'm toying with what a 'git reflog show' might look like. I attached
> the prototype code below. Here's the output from the recent part of
> my mmap pack window topic:
>
> $ ./git-reflog show refs/heads/sp/mapwin
> ...clipped for space...
>
The output should look almost the same as "git log" for the part
that represents a series of normal branch activity where commits
are built up one-by-one. I think it would be useful if you can
somehow make parts that are _not_ linear stand out and perhaps
allow omitting a stretch of ordinary single strand of pearls.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-23 10:42 ` Junio C Hamano
@ 2006-12-23 14:53 ` Johannes Schindelin
2006-12-24 6:11 ` Shawn Pearce
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Schindelin @ 2006-12-23 14:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Shawn Pearce, git
Hi,
On Sat, 23 Dec 2006, Junio C Hamano wrote:
> Shawn Pearce <spearce@spearce.org> writes:
>
> > I'm toying with what a 'git reflog show' might look like. I attached
> > the prototype code below. Here's the output from the recent part of
> > my mmap pack window topic:
> >
> > $ ./git-reflog show refs/heads/sp/mapwin
> > ...clipped for space...
> >
>
> The output should look almost the same as "git log" for the part
> that represents a series of normal branch activity where commits
> are built up one-by-one. I think it would be useful if you can
> somehow make parts that are _not_ linear stand out and perhaps
> allow omitting a stretch of ordinary single strand of pearls.
I wonder if it would make sense to teach the revision walking machinery
about reflogs. A commit could be marked as coming from a reflog entry, and
in that case the parents could be determined by the reflog rather than the
commit itself.
Is this a stupid idea?
Ciao,
Dscho
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-23 14:53 ` Johannes Schindelin
@ 2006-12-24 6:11 ` Shawn Pearce
2006-12-24 12:49 ` Johannes Schindelin
0 siblings, 1 reply; 14+ messages in thread
From: Shawn Pearce @ 2006-12-24 6:11 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> I wonder if it would make sense to teach the revision walking machinery
> about reflogs. A commit could be marked as coming from a reflog entry, and
> in that case the parents could be determined by the reflog rather than the
> commit itself.
The revision machinery already knows about reflogs with --reflog,
used by git-pack-objects via git-repack. But here its really only
useful to seed the list of commits to be walked as part of a pack
generation, to make sure the things referenced by the reflog stay
around after a repacking. And it implies --all.
Rewriting the commits in memory to appear to have parents based
on their order of appearence in the reflog would nicely generate
a single strand of perls, but it makes it difficult to then access
the same commit's real parents, doesn't it? So that may make the
revision machinary somewhat limited in some applications.
Besides we want the reflog message entry and not the commit message
when we perform pretty output, etc. So really we are then talking
about generating synthetic commit objects for the reflog data.
--
Shawn.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-24 6:11 ` Shawn Pearce
@ 2006-12-24 12:49 ` Johannes Schindelin
2006-12-24 21:47 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Schindelin @ 2006-12-24 12:49 UTC (permalink / raw)
To: Shawn Pearce; +Cc: Junio C Hamano, git
Hi,
On Sun, 24 Dec 2006, Shawn Pearce wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > I wonder if it would make sense to teach the revision walking machinery
> > about reflogs. A commit could be marked as coming from a reflog entry, and
> > in that case the parents could be determined by the reflog rather than the
> > commit itself.
>
> The revision machinery already knows about reflogs with --reflog,
> used by git-pack-objects via git-repack. But here its really only
> useful to seed the list of commits to be walked as part of a pack
> generation, to make sure the things referenced by the reflog stay
> around after a repacking. And it implies --all.
Ah. I think it is a bit misnamed.
Besides, --reflog options of pack-objects, show-branch and general
revision-walk based programs are independent.
I propose to change the behaviour of "--reflog" in revision.c (which
should not have a big impact, since it is not even documented yet):
- if --all-reflog is passed, include all reflogs (part of the current
behaviour of --reflog), and
- if --reflog is passed, write the reflog messages in addition to the
commit lines, and rewrite the parent(s).
> Rewriting the commits in memory to appear to have parents based
> on their order of appearence in the reflog would nicely generate
> a single strand of perls, but it makes it difficult to then access
> the same commit's real parents, doesn't it? So that may make the
> revision machinary somewhat limited in some applications.
Uhm, we rewrite parents all the time. Just think about "git log Makefile".
> Besides we want the reflog message entry and not the commit message
> when we perform pretty output, etc. So really we are then talking
> about generating synthetic commit objects for the reflog data.
Yes, but if we have to read the reflog anyway to determine the logical
(local) parent, we can just as well read the message, and display it, too.
What it buys us is that we do not duplicate efforts here, and we can
easily visualize the reflog in gitk, too.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-24 12:49 ` Johannes Schindelin
@ 2006-12-24 21:47 ` Junio C Hamano
2006-12-25 14:01 ` Johannes Schindelin
0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2006-12-24 21:47 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Shawn Pearce
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Yes, but if we have to read the reflog anyway to determine the logical
> (local) parent, we can just as well read the message, and display it, too.
>
> What it buys us is that we do not duplicate efforts here, and we can
> easily visualize the reflog in gitk, too.
I do not think you can sanely rewrite parenthood.
Think about this sequence
$ git init-db; edit foo; git add foo
$ git commit -m 'first'
$ edit foo; git add foo
$ git commit -m 'second'
$ git reset --hard HEAD@{1}
At this point, the commits on the reflog are:
$ git show-branch --reflog=3 HEAD
! [HEAD@{0}] first
! [HEAD@{1}] second
! [HEAD@{2}] first
---
+ [HEAD@{1}] second
+++ [HEAD@{0}] first
We are currently at the first commit, and its "rewritten" parent
should point at the second commit (i.e. pretend HEAD@{1} is the
parent of HEAD@{0}). The "rewritten" parent of the second commit
should be HEAD@{2}, but that is actually the same first commit
which is HEAD@{0}.
Also I highly doubt visualization based on parents information
rewritten to match the reflog order is of _any_ use. By
rewriting the parenthood, you are losing the topology and your
visualization is no better than what "tac .git/logs/$ref" would
give.
I do agree that reusing the message formattng and display code
from the usual log machinery is desirable. I think you can hook
that information somewhere in object->util (or a callback
mechanism) and teach log display machinery to use it as a
generic mechanism. That might make the existing code to insert
"Subject: " for --pretty=format simpler, but I haven't looked.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-24 21:47 ` Junio C Hamano
@ 2006-12-25 14:01 ` Johannes Schindelin
2006-12-25 18:07 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Schindelin @ 2006-12-25 14:01 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Shawn Pearce
Hi,
On Sun, 24 Dec 2006, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > Yes, but if we have to read the reflog anyway to determine the logical
> > (local) parent, we can just as well read the message, and display it,
> > too.
> >
> > What it buys us is that we do not duplicate efforts here, and we can
> > easily visualize the reflog in gitk, too.
>
> I do not think you can sanely rewrite parenthood.
Well, I did not mean to change the parents in the commit object. Rather,
let the revision walker determine the parent differently for reflogs.
> Also I highly doubt visualization based on parents information rewritten
> to match the reflog order is of _any_ use. By rewriting the parenthood,
> you are losing the topology and your visualization is no better than
> what "tac .git/logs/$ref" would give.
Okay, but if they are _not_ rewritten, we can reuse the log machinery to
show the revisions in "upstream..master@{2.hours.ago}", but in the order
they came into the local repository.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-25 14:01 ` Johannes Schindelin
@ 2006-12-25 18:07 ` Junio C Hamano
2006-12-26 5:48 ` Shawn Pearce
2006-12-26 16:14 ` Johannes Schindelin
0 siblings, 2 replies; 14+ messages in thread
From: Junio C Hamano @ 2006-12-25 18:07 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Shawn Pearce
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> Also I highly doubt visualization based on parents information rewritten
>> to match the reflog order is of _any_ use. By rewriting the parenthood,
>> you are losing the topology and your visualization is no better than
>> what "tac .git/logs/$ref" would give.
>
> Okay, but if they are _not_ rewritten, we can reuse the log machinery to
> show the revisions in "upstream..master@{2.hours.ago}", but in the order
> they came into the local repository.
Shawn's code was about showing where the tip of the branch was,
and I think you are talking about something entirely different,
which I would address later.
A sensible way to reuse existing code to implement Shawn's one
is to add the revisions to rev.pending, and iterate over that
array like "git show" does. This does not need to touch the
existing revision walking code at all. The most valuable parts
of the revision walking code are about ancestry traversal and
history simplification with pathspec, neither of which makes
much sense to use when "walking" reflog. Reflog walking might
want to use the filtering by commit_match() but then it is only
the matter of renaming the function to a bit more specific name
and exporting it.
You can largely reuse the display side of the code that way, and
I think you should be able to hook into the code without making
it too specific to the reflog (perhaps using object->util and/or
a callback) if you need to give extra information (e.g. comments
and commit information from the log).
But it _also_ makes sense to use reflog when the primary thing
we are interested in seeing is not how the tip jumped around,
but seeing how the branch acquired commits, which I think is
what you are suggesting. What we would want to have is a sort
order different from the existing topo or date, which is "reflog
order". While I think it makes sense, a naive implementation
would be somewhat expensive. Instead of sorting topologically
at the end of prepare_revision_walk (you would need to limit the
list if you do this), for each commit, you binary search the
reflog entries to find the earliest one that is the ancestor of
the commit, and use the reflog entry's timestamp as the age of
the commit (it's the first time the branch saw that commit), and
sort commits using that.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-25 18:07 ` Junio C Hamano
@ 2006-12-26 5:48 ` Shawn Pearce
2006-12-26 6:14 ` Junio C Hamano
2006-12-26 16:14 ` Johannes Schindelin
1 sibling, 1 reply; 14+ messages in thread
From: Shawn Pearce @ 2006-12-26 5:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, git
Junio C Hamano <junkio@cox.net> wrote:
> A sensible way to reuse existing code to implement Shawn's one
> is to add the revisions to rev.pending, and iterate over that
> array like "git show" does. This does not need to touch the
> existing revision walking code at all. The most valuable parts
> of the revision walking code are about ancestry traversal and
> history simplification with pathspec, neither of which makes
> much sense to use when "walking" reflog. Reflog walking might
> want to use the filtering by commit_match() but then it is only
> the matter of renaming the function to a bit more specific name
> and exporting it.
>
> You can largely reuse the display side of the code that way, and
> I think you should be able to hook into the code without making
> it too specific to the reflog (perhaps using object->util and/or
> a callback) if you need to give extra information (e.g. comments
> and commit information from the log).
So what you are proposing is to make the reflog visible in 'git log'
by a new option? Or to just try to reuse all of its display code
but keep the reflog under 'git reflog show' ?
--
Shawn.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-26 5:48 ` Shawn Pearce
@ 2006-12-26 6:14 ` Junio C Hamano
0 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2006-12-26 6:14 UTC (permalink / raw)
To: Shawn Pearce; +Cc: Johannes Schindelin, git
Shawn Pearce <spearce@spearce.org> writes:
> So what you are proposing is to make the reflog visible in 'git log'
> by a new option? Or to just try to reuse all of its display code
> but keep the reflog under 'git reflog show' ?
I am not specifically proposing anything, but the part you
quoted is about the latter.
What Johannes brought up would involve hooking into the usual
log walking machinery to show the commits in "merge order" (more
precisely, "local appearance order"). I do not think it is
about "showing the reflog data", but about using reflog data to
give a different presentation order to the usual log output.
Your "reflog show" is more about showing what are recorded in
the reflog.
It is not like implementing the sorting of the logs in local
appearance order would make your "reflog show" redundant or
useless; both are independently useful, I think.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-25 18:07 ` Junio C Hamano
2006-12-26 5:48 ` Shawn Pearce
@ 2006-12-26 16:14 ` Johannes Schindelin
2006-12-26 19:03 ` Junio C Hamano
1 sibling, 1 reply; 14+ messages in thread
From: Johannes Schindelin @ 2006-12-26 16:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Shawn Pearce
Hi,
On Mon, 25 Dec 2006, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> Also I highly doubt visualization based on parents information rewritten
> >> to match the reflog order is of _any_ use. By rewriting the parenthood,
> >> you are losing the topology and your visualization is no better than
> >> what "tac .git/logs/$ref" would give.
> >
> > Okay, but if they are _not_ rewritten, we can reuse the log machinery to
> > show the revisions in "upstream..master@{2.hours.ago}", but in the order
> > they came into the local repository.
>
> Shawn's code was about showing where the tip of the branch was,
> and I think you are talking about something entirely different,
> which I would address later.
If I read Shawn's mail correctly, it is not only about the tip.
> The most valuable parts of the revision walking code are about ancestry
> traversal and history simplification with pathspec, neither of which
> makes much sense to use when "walking" reflog.
Sorry to be a PITA here, but I think that it _would_ make sense. Quite
often I ask myself "That feature in this file used to work. When and how
was it changed?" Right now, I use git-log with path simplification, but
with reflog walking, I could ask in a more specific way!
> But it _also_ makes sense to use reflog when the primary thing we are
> interested in seeing is not how the tip jumped around, but seeing how
> the branch acquired commits, which I think is what you are suggesting.
> What we would want to have is a sort order different from the existing
> topo or date, which is "reflog order".
I think it should not be a different sort order. As you pointed out
yourself, a "git reset --hard HEAD^" removes the assumption of the commit
list being a DAG.
Rather, I think about introducing a "get_parents(revs, commit)" function
in revision.c, which takes reflog information rather than commit->parents
if "--walk-reflogs" is passed to setup_revisions().
I hope to have a proof of concept later today.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-26 16:14 ` Johannes Schindelin
@ 2006-12-26 19:03 ` Junio C Hamano
2006-12-26 23:20 ` Johannes Schindelin
0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2006-12-26 19:03 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Shawn Pearce
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> Shawn's code was about showing where the tip of the branch was,
>> and I think you are talking about something entirely different,
>> which I would address later.
>
> If I read Shawn's mail correctly, it is not only about the tip.
What I meant was that I did not see anything that mentions
"$ref@{ago}~47" and such; what was shown was only about the
transition between the tip.
>> The most valuable parts of the revision walking code are about ancestry
>> traversal and history simplification with pathspec, neither of which
>> makes much sense to use when "walking" reflog.
>
> Sorry to be a PITA here, but I think that it _would_ make sense. Quite
> often I ask myself "That feature in this file used to work. When and how
> was it changed?" Right now, I use git-log with path simplification, but
> with reflog walking, I could ask in a more specific way!
When you put it that way, it sort of makes sense. Right now,
get_revision() walks the chain of commits using the parent links
and the history simplification (try_to_simplify_commit) looks at
each commit and compares the tree with its parents' trees to
decide if the commit is worth considering.
If we _had_ an object type "reflog entry" which has one "parent
reflog entry" field and an associated "tip commit" object, just
like a commit object has zero or more "parent commit" field and
an associated "tree" object, the same algorithm could be taught
to follow the "parent reflog entry" chain while walking and look
at the tree associated with "tip commit" for the history
simplification purposes.
I am not proposing to introduce a new object type here, but
conceptually we could. Maybe a quick hack would be to represent
each reflog entry as a phony "struct commit" in core,
1. whose tree is taken from the tree of the tip commit,
2. whose buffer is handcrafted by the true commit log message
with data from reflog, and
3. whose parent list points at another phony "commit" that
represents ref@{N+1} reflog entry.
Then we would give a new populate_parent() member to "struct
revinfo" which is called instead of parse_object() to fill the
commit's parent list before traversal. With 1. we do not have
to touch any code for history simplification, with 2. we do not
have to touch pretty-print-commit (the result would include
whatever reflog wants to add in the message automatically), and
with 3. plus populate_parent callback would give us the
traversal.
>> But it _also_ makes sense to use reflog when the primary thing we are
>> interested in seeing is not how the tip jumped around, but seeing how
>> the branch acquired commits, which I think is what you are suggesting.
>> What we would want to have is a sort order different from the existing
>> topo or date, which is "reflog order".
>
> I think it should not be a different sort order. As you pointed out
> yourself, a "git reset --hard HEAD^" removes the assumption of the commit
> list being a DAG.
I think I misunderstood your proposal and the misunderstanding
resulted in an unrelated useful enhancement ;-). If HEAD@{0}
and HEAD@{2} points at the same commit, then obviously commits
reachable from that commit did not come into the branch no later
than HEAD@{2} time (what HEAD@{0} says becomes irrelevant), so
you can define an order that lists commits in the order the
earliest time they appeared on a branch.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-26 19:03 ` Junio C Hamano
@ 2006-12-26 23:20 ` Johannes Schindelin
2006-12-26 23:50 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Schindelin @ 2006-12-26 23:20 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Shawn Pearce
Hi,
On Tue, 26 Dec 2006, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> The most valuable parts of the revision walking code are about
> >> ancestry traversal and history simplification with pathspec, neither
> >> of which makes much sense to use when "walking" reflog.
> >
> > Sorry to be a PITA here, but I think that it _would_ make sense. Quite
> > often I ask myself "That feature in this file used to work. When and
> > how was it changed?" Right now, I use git-log with path
> > simplification, but with reflog walking, I could ask in a more
> > specific way!
>
> When you put it that way, it sort of makes sense. Right now,
> get_revision() walks the chain of commits using the parent links and the
> history simplification (try_to_simplify_commit) looks at each commit and
> compares the tree with its parents' trees to decide if the commit is
> worth considering.
>
> [...]
>
> I am not proposing to introduce a new object type here, but
> conceptually we could. Maybe a quick hack would be to represent
> each reflog entry as a phony "struct commit" in core,
>
> 1. whose tree is taken from the tree of the tip commit,
>
> 2. whose buffer is handcrafted by the true commit log message
> with data from reflog, and
>
> 3. whose parent list points at another phony "commit" that
> represents ref@{N+1} reflog entry.
I see only one problem with this approach: "next..master@{0}" would stop
to work as expected.
> >> But it _also_ makes sense to use reflog when the primary thing we are
> >> interested in seeing is not how the tip jumped around, but seeing how
> >> the branch acquired commits, which I think is what you are
> >> suggesting. What we would want to have is a sort order different
> >> from the existing topo or date, which is "reflog order".
> >
> > I think it should not be a different sort order. As you pointed out
> > yourself, a "git reset --hard HEAD^" removes the assumption of the
> > commit list being a DAG.
>
> I think I misunderstood your proposal and the misunderstanding resulted
> in an unrelated useful enhancement ;-). If HEAD@{0} and HEAD@{2} points
> at the same commit, then obviously commits reachable from that commit
> did not come into the branch no later than HEAD@{2} time (what HEAD@{0}
> says becomes irrelevant), so you can define an order that lists commits
> in the order the earliest time they appeared on a branch.
I fear that this traversal is not as easy as it seems. We cannot just
blindly walk the reflogs, since the simplification relies on being able to
actually rewrite the commit_list. Also, if a commit was seen, it must be
possible to show it _again_. And if you show the commit diff, you rely on
commit->parents actually containing the rewritten parents. And the same
commit could be in revs->commits twice, and the correct reflog has still
to be shown.
So I tend to think that rewriting the parents, buffer _and_ flags is the
way to go.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] git reflog show
2006-12-26 23:20 ` Johannes Schindelin
@ 2006-12-26 23:50 ` Junio C Hamano
0 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2006-12-26 23:50 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> I am not proposing to introduce a new object type here, but
>> conceptually we could. Maybe a quick hack would be to represent
>> each reflog entry as a phony "struct commit" in core,
>>
>> 1. whose tree is taken from the tree of the tip commit,
>>
>> 2. whose buffer is handcrafted by the true commit log message
>> with data from reflog, and
>>
>> 3. whose parent list points at another phony "commit" that
>> represents ref@{N+1} reflog entry.
>
> I see only one problem with this approach: "next..master@{0}" would stop
> to work as expected.
I was not talking about doing this as part of the usual
"rev-list". This is a special hack to support reflog, and that
is Ok, because reflog is a very special hack itself. I was
trying to rephrase what you said about reusing revision
traversal machinery for walking reflog. The actual syntax would
more likely to be:
reflog show master@{20}..master@{4} -- paths...
where you do NOT even allow handle_revision_arg() to interpret
double-dots, nor sha1_hex() to interpret master@{20}. We do not
want the real commit objects when walking reflog entries.
You are going to synthesize an imaginary commit ancestry chain
that corresponds to the reflog entries of 'master' branch (so
you would error out when your replacement handle_revision_arg()
finds either is not a reflog entry and/or talk about different
refs).
In other words, the usual "next..master@{0}" WILL not do this
phony wrapping with "imaginary reflog objects". We know it
cannot work.
>> I think I misunderstood your proposal and the misunderstanding resulted
>> in an unrelated useful enhancement ;-). If HEAD@{0} and HEAD@{2} points
>> at the same commit, then obviously commits reachable from that commit
>> did not come into the branch no later than HEAD@{2} time (what HEAD@{0}
>> says becomes irrelevant), so you can define an order that lists commits
>> in the order the earliest time they appeared on a branch.
>
> I fear that this traversal is not as easy as it seems. We cannot just
> blindly walk the reflogs, since the simplification relies on being able to
> actually rewrite the commit_list. Also, if a commit was seen, it must be
> possible to show it _again_. And if you show the commit diff, you rely on
> commit->parents actually containing the rewritten parents. And the same
> commit could be in revs->commits twice, and the correct reflog has still
> to be shown.
I think you are misunderstanding me completely. This part is
about a separate topic of using reflog when walking the real
history. We do not wrap or do anything funky like that. We
just walk the true history. We do not walk reflog at all.
Then, before you output anything, at the point you would call
topological sort, instead you would sort the commits with the
timestamp of the earliest appearance in the repository (or on
a particular branch), instead of the usual commit date. And
reflog data is how you would determine when each commit appeared
in this repository (or on this particular branch).
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-12-26 23:51 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-23 10:19 [RFC] git reflog show Shawn Pearce
2006-12-23 10:42 ` Junio C Hamano
2006-12-23 14:53 ` Johannes Schindelin
2006-12-24 6:11 ` Shawn Pearce
2006-12-24 12:49 ` Johannes Schindelin
2006-12-24 21:47 ` Junio C Hamano
2006-12-25 14:01 ` Johannes Schindelin
2006-12-25 18:07 ` Junio C Hamano
2006-12-26 5:48 ` Shawn Pearce
2006-12-26 6:14 ` Junio C Hamano
2006-12-26 16:14 ` Johannes Schindelin
2006-12-26 19:03 ` Junio C Hamano
2006-12-26 23:20 ` Johannes Schindelin
2006-12-26 23:50 ` Junio C Hamano
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).