threads / discuss / 7436

Listing of branch creation time?

Subject: Listing of branch creation time?

## tl;dr

17 messages between Mar 27, 2007 and Jul 23, 2007.

replies: 16people: 7as markdown or json

Bill Lear· Mar 27, 2007, 21:52 UTC · lore

I'm sure the git developers grow tired of working with addle-brained users, but I sometimes forget what the contents of a topic branch are, how old it is, etc. As to content, I can make better branch names, but I think it would be useful to be able to query git as to the creation time of all of my branches, perhaps sorted from newest to oldest.

Would it be reasonable to add an option to git-branch to do this?
Bill
Johannes Schindelin· Mar 27, 2007, 23:03 UTC · re: Bill Lear · lore

[PATCH] git-branch: add --sort-by-date option

With `--sort-by-date`, git-branch prints the refs sorted by date of the refs' tips (newest first). If this option is combined with `-v`, also print the dates of the tips.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	On Tue, 27 Mar 2007, Bill Lear wrote:
	> [...] I sometimes forget what the contents of a topic branch 
	> are, how old it is, etc.  As to content, I can make better 
	> branch names, but I think it would be useful to be able to query 
	> git as to the creation time of all of my branches, perhaps 
	> sorted from newest to oldest.
	This is only lightly tested, and I will not have time to work any 
	more on this. So, if this does not what you want, you will have to 
	fix it yourself.
 Documentation/git-branch.txt |    5 +++-
 builtin-branch.c             |   52 +++++++++++++++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 603f87f..ca32d5d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git-branch' [--color | --no-color] [-r | -a]
-	   [-v [--abbrev=<length> | --no-abbrev]]
+	   [-v [--abbrev=<length> | --no-abbrev]] [--sort-by-date]
 'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
 'git-branch' (-m | -M) [<oldbranch>] <newbranch>
 'git-branch' (-d | -D) [-r] <branchname>...
@@ -91,6 +91,9 @@ OPTIONS
 --no-abbrev::
 	Display the full sha1s in output listing rather than abbreviating them.
 
+--sort-by-date::
+	Instead of sorting by name, sort the refs by date of their tips.
+
 <branchname>::
 	The name of the branch to create or delete.
 	The new branch name must pass all checks defined by
diff --git a/builtin-branch.c b/builtin-branch.c
index a4494ee..8deb155 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -12,7 +12,7 @@
 #include "builtin.h"
 
 static const char builtin_branch_usage[] =
-  "git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]]";
+  "git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]] [--sort-by-date]";
 
 #define REF_UNKNOWN_TYPE    0x00
 #define REF_LOCAL_BRANCH    0x01
@@ -236,8 +236,26 @@ static int ref_cmp(const void *r1, const void *r2)
 	return strcmp(c1->name, c2->name);
 }
 
+static int ref_cmp_by_author_date(const void *r1, const void *r2)
+{
+	struct ref_item *i1 = (struct ref_item *)r1;
+	struct ref_item *i2 = (struct ref_item *)r2;
+	struct commit *c1 = lookup_commit(i1->sha1);
+	struct commit *c2 = lookup_commit(i2->sha1);
+	if (!c1 || parse_commit(c1))
+		return +1;
+	if (!c2 || parse_commit(c2))
+		return -1;
+	if (c1->date < c2->date)
+		return +1;
+	else if (c1->date > c2->date)
+		return -1;
+	return 0;
+}
+
+
 static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
-			   int abbrev, int current)
+			   int abbrev, int current, int show_author_date)
 {
 	char c;
 	int color;
@@ -264,11 +282,17 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 
 	if (verbose) {
 		commit = lookup_commit(item->sha1);
-		if (commit && !parse_commit(commit))
+		if (commit && !parse_commit(commit)) {
+			int offset = 0;
+			if (show_author_date)
+				offset = snprintf(subject, sizeof(subject),
+					"%s ", show_date(commit->date, 0,
+					DATE_SHORT));
 			pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
-					    subject, sizeof(subject), 0,
+					    subject + offset,
+					    sizeof(subject) - offset, 0,
 					    NULL, NULL, 0);
-		else
+		} else
 			strcpy(subject, " **** invalid ref ****");
 		printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color),
 		       maxwidth, item->name,
@@ -280,7 +304,8 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 	}
 }
 
-static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
+static void print_ref_list(int kinds, int detached, int verbose, int abbrev,
+	int sort_by_date)
 {
 	int i;
 	struct ref_list ref_list;
@@ -289,7 +314,8 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
 	ref_list.kinds = kinds;
 	for_each_ref(append_ref, &ref_list);
 
-	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
+	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item),
+		sort_by_date ? ref_cmp_by_author_date : ref_cmp);
 
 	detached = (detached && (kinds & REF_LOCAL_BRANCH));
 	if (detached) {
@@ -299,7 +325,8 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
 		hashcpy(item.sha1, head_sha1);
 		if (strlen(item.name) > ref_list.maxwidth)
 			      ref_list.maxwidth = strlen(item.name);
-		print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);
+		print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1,
+			sort_by_date);
 		free(item.name);
 	}
 
@@ -308,7 +335,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
 			(ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
 			!strcmp(ref_list.list[i].name, head);
 		print_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose,
-			       abbrev, current);
+			       abbrev, current, sort_by_date);
 	}
 
 	free_ref_list(&ref_list);
@@ -530,6 +557,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
 	int reflog = 0, track;
 	int kinds = REF_LOCAL_BRANCH;
+	int sort_by_date = 0;
 	int i;
 
 	git_config(git_branch_config);
@@ -610,6 +638,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 			branch_use_color = 0;
 			continue;
 		}
+		if (!strcmp(arg, "--sort-by-date")) {
+			sort_by_date = 1;
+			continue;
+		}
 		usage(builtin_branch_usage);
 	}
 
@@ -632,7 +664,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	if (delete)
 		return delete_branches(argc - i, argv + i, force_delete, kinds);
 	else if (i == argc)
-		print_ref_list(kinds, detached, verbose, abbrev);
+		print_ref_list(kinds, detached, verbose, abbrev, sort_by_date);
 	else if (rename && (i == argc - 1))
 		rename_branch(head, argv[i], force_rename);
 	else if (rename && (i == argc - 2))
-- 
1.5.1.rc2.2330.g2388
Bill Lear· Mar 27, 2007, 23:53 UTC · re: Johannes Schindelin · lore

Re: [PATCH] git-branch: add --sort-by-date option

On Wednesday, March 28, 2007 at 01:03:57 (+0200) Johannes Schindelin writes:
>...
>	This is only lightly tested, and I will not have time to work any 
>	more on this. So, if this does not what you want, you will have to 
>	fix it yourself.

Well, thank you kindly for your quick reply. I will patch this in to my git source tree, test it out and see if I can fix anything that comes up.

Bill
Johannes Schindelin· Jul 23, 2007, 23:38 UTC · re: Bill Lear · lore

[PATCH] Teach revision machinery about --no-walk

The flag "no_walk" is present in struct rev_info since a long time, but so far has been in use exclusively by "git show".

With this flag, you can see all your refs, ordered by date of the last commit:

$ git log --abbrev-commit --pretty=oneline --decorate --all --no-walk

which is extremely helpful if you have to juggle with a lot topic branches, and do not remember in which one you introduced that uber debug option, or simply want to get an overview what is cooking.

(Note that the "git log" invocation above does not output the same as
 $ git show --abbrev-commit --pretty=oneline --decorate --all --quiet
 since "git show" keeps the alphabetic order that "--all" returns the
 refs in, even if the option "--date-order" was passed.)

For good measure, this also adds the "--do-walk" option which overrides "--no-walk".

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	On Tue, 27 Mar 2007, Bill Lear wrote:
	> On Wednesday, March 28, 2007 at 01:03:57 (+0200) Johannes Schindelin writes:
	> >...
	> >	This is only lightly tested, and I will not have time to work any 
	> >	more on this. So, if this does not what you want, you will have to
	> >	fix it yourself.
	> 
	> Well, thank you kindly for your quick reply.  I will patch this in to my 
	> git source tree, test it out and see if I can fix anything that comes 
	> up.
	Actually, I tested this a lot in recent times, especially since I 
	started to use topic branches a lot more, to keep Junio happy.
	And then I had an idea: Much better to let "git log" do the work, 
	since it already sorts the commits it shows by date.  There is a 
	flag in the revision machinery, named "no_walk" which would tell 
	it to not traverse all ancestors.
	Since I can make this an alias, it does not matter very much that 
	the command line is so long.  However, since you can use different 
	pretty formats, this might be much more useful than the 
	--sort-by-date option for "git branch".
 Documentation/git-rev-list.txt |    9 +++++++++
 revision.c                     |    8 ++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 0430139..1c19781 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -37,6 +37,7 @@ SYNOPSIS
 	     [ \--merge ]
 	     [ \--reverse ]
 	     [ \--walk-reflogs ]
+	     [ \--no-walk ] [ \--do-walk ]
 	     <commit>... [ \-- <paths>... ]
 
 DESCRIPTION
@@ -398,6 +399,14 @@ These options are mostly targeted for packing of git repositories.
 	Only useful with '--objects'; print the object IDs that are not
 	in packs.
 
+--no-walk::
+
+	Only show the given revs, but do not traverse their ancestors.
+
+--do-walk::
+
+	Overrides a previous --no-walk.
+
 
 include::pretty-formats.txt[]
 
diff --git a/revision.c b/revision.c
index 00b75bc..16f35c7 100644
--- a/revision.c
+++ b/revision.c
@@ -1191,6 +1191,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 				revs->reverse ^= 1;
 				continue;
 			}
+			if (!strcmp(arg, "--no-walk")) {
+				revs->no_walk = 1;
+				continue;
+			}
+			if (!strcmp(arg, "--do-walk")) {
+				revs->no_walk = 0;
+				continue;
+			}
 
 			opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
 			if (opts > 0) {
-- 
1.5.3.rc2.31.gf7d7-dirty
Jeff King· Mar 27, 2007, 23:35 UTC · re: Bill Lear · lore

Re: Listing of branch creation time?

On Tue, Mar 27, 2007 at 03:52:06PM -0600, Bill Lear wrote:
Show 6 quoted lines
> I'm sure the git developers grow tired of working with addle-brained
> users, but I sometimes forget what the contents of a topic branch are,
> how old it is, etc.  As to content, I can make better branch names,
> but I think it would be useful to be able to query git as to the
> creation time of all of my branches, perhaps sorted from newest to
> oldest.

I'm not sure you can always accurately get that information. If you have reflogs turned on, you can look at the oldest reflog for the that ref; however, the reflog may have been pruned. You can also try looking at the commit graph, but then you need a reference branch ("when did I branch from master"), and even that's not entirely useful. You have to look at the latest merge-base, but that tells you the last time you merged with master, not necessarily the first time.

That being said, something like this should work:

-- >8 -- #!/bin/sh

branch_date() {
  git-rev-list -g --pretty=format:'%ct %cd' $1 | tail -n 1
}
git-show-ref --heads |
  while read sha1 branch; do
    echo "$branch `branch_date $branch`"
  done |
  sort -k 2nr |
  while read branch timestamp date; do
    printf '%20s %s\n' ${branch#refs/heads/} "$date"
  done
-- >8 --

Unfortunately, there is a bug in git-rev-list; I've just posted a patch, but the one-liner fix is:

diff --git a/commit.c b/commit.c
index 718e568..a92958c 100644
--- a/commit.c
+++ b/commit.c
@@ -760,7 +760,7 @@ static void fill_person(struct interp *table, const char *msg, int len)
 	if (msg + start == ep)
 		return;
 
-	table[5].value = xstrndup(msg + start, ep - msg + start);
+	table[5].value = xstrndup(msg + start, ep - (msg + start));
 
 	/* parse tz */
 	for (start = ep - msg + 1; start < len && isspace(msg[start]); start++)

With that fix, the script above should hopefully produce what you want.

-Peff
Bill Lear· Mar 28, 2007, 00:00 UTC · re: Jeff King · lore

Re: Listing of branch creation time?

On Tuesday, March 27, 2007 at 19:35:52 (-0400) Jeff King writes:
>...
>That being said, something like this should work:

Ok, thank you. I will try this out and keep this in mind as I test out the patch Johannes posted.

Bill
Jeff King· Mar 28, 2007, 00:01 UTC · re: Bill Lear · lore

Re: Listing of branch creation time?

On Tue, Mar 27, 2007 at 06:00:04PM -0600, Bill Lear wrote:
> Ok, thank you.  I will try this out and keep this in mind as I test
> out the patch Johannes posted.

This is, btw, completely different than what Johannes posted. His patch shows you the date of the _tip_ of each of the branches. My script shows the _oldest_ reflog for the branch. So it depends on whether you want them in order of "last worked on" or "created" (you said "created", but I wonder if "last worked on" is actually more useful).

-Peff
Bill Lear· Mar 28, 2007, 00:08 UTC · re: Jeff King · lore

Re: Listing of branch creation time?

On Tuesday, March 27, 2007 at 20:01:49 (-0400) Jeff King writes:
Show 10 quoted lines
>On Tue, Mar 27, 2007 at 06:00:04PM -0600, Bill Lear wrote:
>
>> Ok, thank you.  I will try this out and keep this in mind as I test
>> out the patch Johannes posted.
>
>This is, btw, completely different than what Johannes posted. His patch
>shows you the date of the _tip_ of each of the branches. My script shows
>the _oldest_ reflog for the branch. So it depends on whether you want
>them in order of "last worked on" or "created" (you said "created", but
>I wonder if "last worked on" is actually more useful).

Ah, yes, good point. I think this all falls under the topic of branch management, and it would be good to have a full suite of reports for people with a rats' nest of branches to keep track of. I'm up to ten topic branches and plan on needing a few more soon.

Queries that help me answer the question of "did I merge this branch?", "when did I merge it?" (i.e., "Can I delete this branch?"), along with creation times and last modified times, I think would be helpful.

Thank you again.
Bill
Jeff King· Mar 28, 2007, 00:10 UTC · re: Bill Lear · lore

Re: Listing of branch creation time?

On Tue, Mar 27, 2007 at 06:08:07PM -0600, Bill Lear wrote:
> Queries that help me answer the question of "did I merge this
> branch?", "when did I merge it?" (i.e., "Can I delete this branch?"),
> along with creation times and last modified times, I think would be
> helpful.

I find that a nice 'gitk branch...origin' answers most of those for me (it's everything in both branches going back to the last time they merged).

-Peff
Bill Lear· Mar 28, 2007, 00:14 UTC · re: Jeff King · lore

Re: Listing of branch creation time?

On Tuesday, March 27, 2007 at 20:10:27 (-0400) Jeff King writes:
Show 10 quoted lines
>On Tue, Mar 27, 2007 at 06:08:07PM -0600, Bill Lear wrote:
>
>> Queries that help me answer the question of "did I merge this
>> branch?", "when did I merge it?" (i.e., "Can I delete this branch?"),
>> along with creation times and last modified times, I think would be
>> helpful.
>
>I find that a nice 'gitk branch...origin' answers most of those for me
>(it's everything in both branches going back to the last time they
>merged).

Hmm, perhaps I should learn to use gitk more, though I must admit to being somewhat of an anti-GUI bigot (i.e., lazy).

Bill
David Lang· Mar 27, 2007, 23:51 UTC · re: Bill Lear · lore

Re: Listing of branch creation time?

On Tue, 27 Mar 2007, Bill Lear wrote:
Show 14 quoted lines
> On Tuesday, March 27, 2007 at 20:10:27 (-0400) Jeff King writes:
>> On Tue, Mar 27, 2007 at 06:08:07PM -0600, Bill Lear wrote:
>>
>>> Queries that help me answer the question of "did I merge this
>>> branch?", "when did I merge it?" (i.e., "Can I delete this branch?"),
>>> along with creation times and last modified times, I think would be
>>> helpful.
>>
>> I find that a nice 'gitk branch...origin' answers most of those for me
>> (it's everything in both branches going back to the last time they
>> merged).
>
> Hmm, perhaps I should learn to use gitk more, though I must admit
> to being somewhat of an anti-GUI bigot (i.e., lazy).

given that we had someone post a tool to the list that creates ascii-art merge diagrams, I wonder if it would scratch anyone's itch to make an ascii output version of gitk?

the code posted was limited to 26 merges, but it would probably be easy enough to do two-letter nodes (although at that point do you _really_ want it on a text screen ;-)

David Lang
Jeff King· Mar 28, 2007, 00:21 UTC · re: David Lang · lore

Re: Listing of branch creation time?

On Tue, Mar 27, 2007 at 03:51:36PM -0800, David Lang wrote:
Show 6 quoted lines
> >Hmm, perhaps I should learn to use gitk more, though I must admit
> >to being somewhat of an anti-GUI bigot (i.e., lazy).
> 
> given that we had someone post a tool to the list that creates ascii-art 
> merge diagrams, I wonder if it would scratch anyone's itch to make an ascii 
> output version of gitk?

I don't like using a GUI either, but I have to admit that the output of gitk is so superior that it's worth it.

However, check out the curses line-drawing support that is in tig now...it just recently has gotten good enough that I might switch to it.

-Peff
Nicolas Pitre· Mar 28, 2007, 01:29 UTC · re: Bill Lear · lore

Re: Listing of branch creation time?

On Tue, 27 Mar 2007, Bill Lear wrote:
> Queries that help me answer the question of "did I merge this
> branch?", "when did I merge it?" (i.e., "Can I delete this branch?"),
> along with creation times and last modified times, I think would be
> helpful.
The reflog is your friend for such questions.
Nicolas
Nicolas Pitre· Mar 28, 2007, 01:25 UTC · re: Jeff King · lore

Re: Listing of branch creation time?

On Tue, 27 Mar 2007, Jeff King wrote:
Show 10 quoted lines
> On Tue, Mar 27, 2007 at 06:00:04PM -0600, Bill Lear wrote:
> 
> > Ok, thank you.  I will try this out and keep this in mind as I test
> > out the patch Johannes posted.
> 
> This is, btw, completely different than what Johannes posted. His patch
> shows you the date of the _tip_ of each of the branches. My script shows
> the _oldest_ reflog for the branch. So it depends on whether you want
> them in order of "last worked on" or "created" (you said "created", but
> I wonder if "last worked on" is actually more useful).

I think "last worked on" is the only thing that makes sense. Anything else is completely ambigous, especially in the presence of forks and merges. And eventually all reflogs will have about the same age when they extend past the expiration period, at which point the "oldest reflog" is not meaningful anymore.

However Johannes' patch uses the author date for sorting. I think branches really should be sorted by committer's date though. The committer's date is a much better indicator of when a given branch has been updated while the author's date might be any time in the past.

Nicolas
Linus Torvalds· Mar 28, 2007, 01:06 UTC · re: Jeff King · lore

Re: Listing of branch creation time?

On Tue, 27 Mar 2007, Jeff King wrote:
>
> You have to look at the latest merge-base, but that tells you the last 
> time you merged with master, not necessarily the first time.

Well, if you know which branch it is a branch off of, don't use merge-base, just do

	git log --reverse -1 origin..branch

which should pick up the first commit that is on that branch but haven't been merged back to the original branch.

The merge-base is the right thing to do for *merging*, but if you keep merging into the branch you are developing on (to keep up-to-date), the above "what is on the branch but not in the origin" is definitely the right thing to do.

Of course, people already pointed out "gitk". And I agree. Quite often, it's worth the full graphical output to do

	gitk origin..branch

to see the big picture. But if you want to work on the command line, the above "git log" command line isn't really that bad to type..

(Personally, if I didn't want the graphical version, I'd likely just do
	git log origin..branch

and then do '>' in the pager to get to the bottom. That way I can then scroll up and down if I decide I want to get a bigger picture)

		Linus
Junio C Hamano· Mar 28, 2007, 02:04 UTC · re: Linus Torvalds · lore

Re: Listing of branch creation time?

Linus Torvalds <torvalds@linux-foundation.org> writes:
Show 12 quoted lines
> On Tue, 27 Mar 2007, Jeff King wrote:
>>
>> You have to look at the latest merge-base, but that tells you the last 
>> time you merged with master, not necessarily the first time.
>
> Well, if you know which branch it is a branch off of, don't use 
> merge-base, just do
>
> 	git log --reverse -1 origin..branch
>
> which should pick up the first commit that is on that branch but haven't 
> been merged back to the original branch.

I suspect you fell into the common trap of confused interaction between --max-count and --reverse here. This will show the latest one commit on the branch that is still not in origin.

Similarly, "git log --reverse -1 master" is _not_ the way to find the root commit of the project.

Show 6 quoted lines
> (Personally, if I didn't want the graphical version, I'd likely just do
>
> 	git log origin..branch
>
> and then do '>' in the pager to get to the bottom. That way I can then 
> scroll up and down if I decide I want to get a bigger picture)

What I use myself is git-topic.perl script from the 'todo' branch. It essentially is:

	for topic
        do
        	git [short]log --no-merges master..$topic
	done
with frills.
Jeff King· Mar 28, 2007, 02:52 UTC · re: Linus Torvalds · lore

Re: Listing of branch creation time?

On Tue, Mar 27, 2007 at 06:06:11PM -0700, Linus Torvalds wrote:
> The merge-base is the right thing to do for *merging*, but if you keep 
> merging into the branch you are developing on (to keep up-to-date), the 
> above "what is on the branch but not in the origin" is definitely the 
> right thing to do.

Of course you're right, I must have had afternoon brain impairment when I wrote that other message.

-Peff

← back to recent threads