Should "git log --decorate" indicate whether the HEAD is detached?
As of Git 2.3.0, the output of "git log --decorate" is ambiguous as to whether the HEAD is detached or not.
More specifically, consider the following output of "git log --decorate":
4d860e9 (HEAD, master, dev) Remove trailing whitespace
Whether the HEAD is attached to master or detached, the output is the same. Could/should "git log --decorate" be modified to provide this information? Perhaps something along the lines of
4d860e9 (HEAD -> master, dev) Remove trailing whitespace
or
4d860e9 (HEAD = master, dev) Remove trailing whitespace
in case HEAD is attached to master, and the current output if it is detached? Any thoughts?
(For information, I asked a related question on Stack Overflow a few months ago: http://stackoverflow.com/q/25392580/2541573.)
Also, if such a feature is desirable, would its implementation be a suitable "microproject" for a prospective GSoC-2015 applicant?
Jubobs
Quoted 2 lines · Julien Cretel
As of Git 2.3.0, the output of "git log --decorate" is ambiguous as to whether the HEAD is detached or not.
It sounds as if you are reporting some regression, but has any version of Git ever done so, or is this just a new feature that does not exist yet?
Quoted 8 lines
More specifically, consider the following output of "git log --decorate":
4d860e9 (HEAD, master, dev) Remove trailing whitespace
Whether the HEAD is attached to master or detached, the output is the same. Could/should "git log --decorate" be modified to provide this information? Perhaps something along the lines of
Quoted 6 lines
4d860e9 (HEAD -> master, dev) Remove trailing whitespaceor
4d860e9 (HEAD = master, dev) Remove trailing whitespace
I personally do not see a need for such a differenciation. Why does one even need to know, and is it worth the cost of computing at the runtime?
Most of the time when I am on detached HEAD it is either a few commits behind a tip, or a few commits ahead of a tip.
Quoted 8 lines · Junio C Hamano
Quoted 2 lines · Julien Cretel
As of Git 2.3.0, the output of "git log --decorate" is ambiguous as to whether the HEAD is detached or not.
It sounds as if you are reporting some regression, but has any version of Git ever done so, or is this just a new feature that does not exist yet?
Apologies; I should have explained myself better. I'm not reporting a regression;
as far as I can tell, "git log --decorate" has always been ambiguous in that way.
Quoted 11 lines
Quoted 11 lines
More specifically, consider the following output of "git log --decorate":
4d860e9 (HEAD, master, dev) Remove trailing whitespace
Whether the HEAD is attached to master or detached, the output is the same. Could/should "git log --decorate" be modified to provide this information? Perhaps something along the lines of
4d860e9 (HEAD -> master, dev) Remove trailing whitespace
Quoted 8 lines
Quoted 4 lines
or
4d860e9 (HEAD = master, dev) Remove trailing whitespace
I personally do not see a need for such a differenciation. Why does one even need to know, and is it worth the cost of computing at the runtime?
I believe the "--decorate" flag to be quite popular. I personally like to run "git log --decorate --graph --oneline --all" to quickly get an idea of the state of a repo. In my experience, many users do the same, to the point that they feel the need to define an alias for this command; see the top answers to
http://stackoverflow.com/q/1057564/2541573.
My problem with the current output of "git log --decorate" is the asymmetry, so to speak. If the HEAD is detached but pointing at a commit that isn't any branch's tip, then the user can be sure the HEAD detached; however, if at least one branch points to the current commit, there is no way to tell.
I must admit I haven't given much thought about the cost involved, but I can't imagine performance would take a big hit. Would it?
Quoted 3 lines
Most of the time when I am on detached HEAD it is either a few commits behind a tip, or a few commits ahead of a tip.
Julien Cretel venit, vidit, dixit 17.02.2015 00:40:
Quoted 41 lines · Junio C Hamano
Quoted 8 lines
Quoted 2 lines · Julien Cretel
As of Git 2.3.0, the output of "git log --decorate" is ambiguous as to whether the HEAD is detached or not.
It sounds as if you are reporting some regression, but has any version of Git ever done so, or is this just a new feature that does not exist yet?
Apologies; I should have explained myself better. I'm not reporting a regression;
as far as I can tell, "git log --decorate" has always been ambiguous in that way.Quoted 11 lines
Quoted 11 lines
More specifically, consider the following output of "git log --decorate":
4d860e9 (HEAD, master, dev) Remove trailing whitespace
Whether the HEAD is attached to master or detached, the output is the same. Could/should "git log --decorate" be modified to provide this information? Perhaps something along the lines of
4d860e9 (HEAD -> master, dev) Remove trailing whitespaceQuoted 8 lines
Quoted 4 lines
or
4d860e9 (HEAD = master, dev) Remove trailing whitespace
I personally do not see a need for such a differenciation. Why does one even need to know, and is it worth the cost of computing at the runtime?
I believe the "--decorate" flag to be quite popular. I personally like to run "git log --decorate --graph --oneline --all" to quickly get an idea of the state of a repo. In my experience, many users do the same, to the point that they feel the need to define an alias for this command; see the top answers to
http://stackoverflow.com/q/1057564/2541573.
Quoted 11 lines
My problem with the current output of "git log --decorate" is the asymmetry, so to speak. If the HEAD is detached but pointing at a commit that isn't any branch's tip, then the user can be sure the HEAD detached; however, if at least one branch points to the current commit, there is no way to tell.
I must admit I haven't given much thought about the cost involved, but I can't imagine performance would take a big hit. Would it?
Quoted 3 lines
Most of the time when I am on detached HEAD it is either a few commits behind a tip, or a few commits ahead of a tip.
"git branch" will tell you your branches and which one is checked out (or HEAD); "git status" will tell you the latter.
"git log" is about the DAG which has absolutely nothing to do with what you have currently checked out.
Your expectation may come from the fact that the default argument to "git log" is HEAD; or from what "gitk" and other ui tools do.
On the other hand, our decorations can be considered "wrong" in the following sense: if HEAD is a symref it really points to a (branch) ref, not a commit. In this situation, "HEAD" should be the decoration of the branch ref, not of the commit which the branch ref resolves to.
But that would apply to annotated tags, as well: they point to tag objects (and should decorate them by the logic above) rather than commit objects.
So, what "log --decorate" really and consistently does is resolving ("peeling") any decorating reference until it points to a commit object, and decorate that.
A --decorate-detailed mode which does without the peeling could be elucidating - that would need markers for (branch) refs and tag objects in addition to commit objects, though (and an extension of the machinery).
Michael
[RFC/PATCH] log: decorate detached HEAD differently
"git status" and "git branch" let the user know when the HEAD is detached, while "git log --decorate" does not.
Change the decoration by a detached HEAD to "detached HEAD". This can be seen as giving more information about the decoration item itself in the same way as we prefix tags by "tag: ".
---
This turned out to be easy to do, though I am still undecided. Personally, I like to think of refs as objects (and have implemented refname objects in the past), but that view is not too popular.
So, maybe the analogy between ref peeling and symref resolving (for HEAD) is not that strong after all. They are both indirections, though different technically.
The RFC patch only checks HEAD for being a symref, the output is analogous to the summary of "git commit".
log-tree.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
log-tree.c +7 -1
@@ -118,8 +118,14 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in type =DECORATION_REF_TAG ; else if (!strcmp(refname, "refs/stash")) type =DECORATION_REF_STASH ; - else if (!strcmp(refname, "HEAD")) + else if (!strcmp(refname, "HEAD")) { +char *junk_sha1[20 ]; +char *head; type =DECORATION_REF_HEAD ; + head =resolve_ref_unsafe ("HEAD" ,0 , junk_sha1,NULL ); +if (!strcmp (head,"HEAD" )) + refname ="detached HEAD" ; + }if (!cb_data || *(int *)cb_data ==DECORATE_SHORT_REFS ) refname =prettify_refname (refname);
Signature · 1 line
2.3.0.136.g92a3b58
Quoted 5 lines · Michael J Gruber
"git branch" will tell you your branches and which one is checked out (or HEAD); "git status" will tell you the latter.
"git log" is about the DAG which has absolutely nothing to do with what you have currently checked out.
Yeah, that summarizes my reaction, too. More importantly, "log" is about showing commits and "--decorate" is a way to enrich the presentation of commits---it talks about commits in terms of refs; the command and the option is not about describing refs and their relationships.
I do not terribly mind showing the fact that HEAD points at a branch when --decorate talks about HEAD, partly because we will be showing both HEAD and the branch name _anyway_ in the output. But I am not sure if the extra bit of information is more helpful to the readers or being distracting.
Julien's "HEAD=master, other" vs "HEAD, master, other" may be subdued enough to be undistracting, I would guess. I do not think the distinction between "HEAD = master" and "HEAD -> master" would be useful, on the other hand. We already know that the names listed all refer to the same commit, which means that we do not have to say "HEAD is detached" explicitly as long as we have a way to say "HEAD points at this branch". If HEAD is listed and is not marked to point at another branch that is shown, by definition it is detached, no?
Junio C Hamano venit, vidit, dixit 18.02.2015 18:07:
Quoted 20 lines
Quoted 5 lines · Michael J Gruber
"git branch" will tell you your branches and which one is checked out (or HEAD); "git status" will tell you the latter.
"git log" is about the DAG which has absolutely nothing to do with what you have currently checked out.
Yeah, that summarizes my reaction, too. More importantly, "log" is about showing commits and "--decorate" is a way to enrich the presentation of commits---it talks about commits in terms of refs; the command and the option is not about describing refs and their relationships.
I do not terribly mind showing the fact that HEAD points at a branch when --decorate talks about HEAD, partly because we will be showing both HEAD and the branch name _anyway_ in the output. But I am not sure if the extra bit of information is more helpful to the readers or being distracting.
Quoted 10 lines
Julien's "HEAD=master, other" vs "HEAD, master, other" may be subdued enough to be undistracting, I would guess. I do not think the distinction between "HEAD = master" and "HEAD -> master" would be useful, on the other hand. We already know that the names listed all refer to the same commit, which means that we do not have to say "HEAD is detached" explicitly as long as we have a way to say "HEAD points at this branch". If HEAD is listed and is not marked to point at another branch that is shown, by definition it is detached, no?
Yep, it very well is. Also, that approach would tell you which branch is checked out, though I don't consider that git log's business.
OTOH, it's "backwards" in the sense that it marks the "ordinary" case (HEAD is symref, branch is checked out) specially compared to the "exceptional/dangerous" case (HEAD is ref, detached). And status, branch will point out that latter case more verbously, too.
Michael
Quoted 6 lines · Michael J Gruber
Yep, it very well is. Also, that approach would tell you which branch is checked out, though I don't consider that git log's business.
OTOH, it's "backwards" in the sense that it marks the "ordinary" case (HEAD is symref, branch is checked out) specially compared to the "exceptional/dangerous" case (HEAD is ref, detached).
Both are ordinary and there is nothing exceptional or dangerous about your HEAD temporarily being detached during a "rebase -i" session, for example.
Quoted 2 lines
And status, branch
will point out that latter case more verbously, too.
Yeah, but as you said, that is not "log"'s business.
Junio C Hamano venit, vidit, dixit 18.02.2015 20:49:
Quoted 5 lines
Quoted 3 lines · Michael J Gruber
Yep, it very well is. Also, that approach would tell you which branch is checked out, though I don't consider that git log's business.
Quoted 7 lines
Quoted 3 lines
OTOH, it's "backwards" in the sense that it marks the "ordinary" case (HEAD is symref, branch is checked out) specially compared to the "exceptional/dangerous" case (HEAD is ref, detached).
Both are ordinary and there is nothing exceptional or dangerous about your HEAD temporarily being detached during a "rebase -i" session, for example.
Sure, that's why I put it in quotes. That's only how it is perceived by some users, and I suppose it's that kind of users that we are trying to help here.
Quoted 4 lines
Quoted 2 lines
And status, branch
will point out that latter case more verbously, too.Yeah, but as you said, that is not "log"'s business.
I still think decorations "detached HEAD" resp. "HEAD" for the two cases are more natural, if we want to include any additional information at all. Just think of:
deadbeef (HEAD=master, topicbranch, tag: v1)
log/rev-list is about commit objects. All the refs above resolve to the same commit, so why are only two of them equal?
In fact, they are very unequal, since HEAD would be "ref:
refs/heads/master" whereas master would "deadbeef". They are equal in the other (detached) case! I'm not telling you any news here, I just want to point out how badly misleading that notation is.
So, I would suggest to "decorate the decorations", by saying something like "detached HEAD", and maybe some version of "HEAD at master" (I'd prefer just "HEAD") and possibly more info on the tags ("s-tag" or "signed tag" etc).
Michael
Quoted 4 lines · Junio C Hamano
Julien's "HEAD=master, other" vs "HEAD, master, other" may be subdued enough to be undistracting, I would guess. I do not think the distinction between "HEAD = master" and "HEAD -> master" would be useful, on the other hand.
Just to clarify, I suggested these two notations as alternatives for denoting the same state: "HEAD is attached to master". They were not meant to denote different states. Accordingly, a detached HEAD could be denoted by "HEAD, master, other" (i.e. the same as the current output of "git log --decorate").
Quoted 7 lines · Julien Cretel
Quoted 4 lines · Junio C Hamano
Julien's "HEAD=master, other" vs "HEAD, master, other" may be subdued enough to be undistracting, I would guess. I do not think the distinction between "HEAD = master" and "HEAD -> master" would be useful, on the other hand.
Quoted 5 lines
Just to clarify, I suggested these two notations as alternatives for denoting the same state: "HEAD is attached to master". They were not meant to denote different states. Accordingly, a detached HEAD could be denoted by "HEAD, master, other" (i.e. the same as the current output of "git log --decorate").
That makes it even better than my misunderstood version ;-) A list that is usually "A, B, C" that sometimes has "A, B=C" is inconspicuous enough not to be distracting too much, I would say.
Thanks.
PATCH 1/1 log: decorate detached HEAD differently
"git status" and "git branch" let the user know when the HEAD is detached, as well as the current branch, while "git log --decorate" does not.
Change the decoration by a non-detached HEAD pointing to branch foo to "HEAD->foo". This can be seen as giving more information about the decoration item itself in the same way as we prefix tags by "tag: ".
---
Notes:
v2 decorates the HEAD pointing to master as "HEAD->master", a detached HEAD just as "HEAD". The "->" hopefully conveys the symlink nature - a "=" would be confusing.
Somehow I still prefer "detached HEAD", dunno. Maybe in addition?
Note that now a checked branch is listed twice, once as target of the HEAD, once as branch: They are two different refs and colored differently.
log-tree.c | 8 +++++++- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-)
log-tree.c +7 -1
@@ -118,8 +118,11 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in type =DECORATION_REF_TAG ; else if (!strcmp(refname, "refs/stash")) type =DECORATION_REF_STASH ; - else if (!strcmp(refname, "HEAD")) + else if (!strcmp(refname, "HEAD")) { +unsigned char junk_sha1[20 ]; type =DECORATION_REF_HEAD ; + refname =resolve_ref_unsafe ("HEAD" ,0 , junk_sha1,NULL ); + }if (!cb_data || *(int *)cb_data ==DECORATE_SHORT_REFS ) refname =prettify_refname (refname);
@@ -198,6 +201,9 @@ void format_decorations_extended(struct strbuf *sb,strbuf_addstr (sb,decorate_get_color (use_color, decoration->type));if (decoration->type ==DECORATION_REF_TAG )strbuf_addstr (sb,"tag: " ); +else if (decoration->type ==DECORATION_REF_HEAD && +strcmp (decoration->name,"HEAD" )) +strbuf_addstr (sb,"HEAD->" );strbuf_addstr (sb, decoration->name);strbuf_addstr (sb, color_reset); prefix = separator;
t/t4013/diff.log_--decorate=full_--all +1 -1
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD->refs/heads/master, refs/heads/master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000
t/t4013/diff.log_--decorate_--all +1 -1
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD->master, master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000
t/t4207-log-decoration-colors.sh +1 -1
@@ -44,7 +44,7 @@ test_expect_success setup ' ' cat >expected <<EOF -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD${c_reset}${c_commit},\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD->master${c_reset}${c_commit},\ ${c_tag}tag: v1.0${c_reset}${c_commit},\ ${c_tag}tag: B${c_reset}${c_commit},\ ${c_branch}master${c_reset}${c_commit})${c_reset} B
Signature · 1 line
2.3.1.303.g5174db1
Re: [PATCH] log: decorate detached HEAD differently
Michael J Gruber venit, vidit, dixit 06.03.2015 17:15:
... and maybe the patch title should be different for v2, too:
log: decorate non-detached HEAD differently
Not my day today it seems, but this is my last patch for today.
Michael
Re: [PATCH] log: decorate detached HEAD differently
In reply to Michael J GruberQuoted 15 lines · Michael J Gruber
"git status" and "git branch" let the user know when the HEAD is detached, as well as the current branch, while "git log --decorate" does not.
Change the decoration by a non-detached HEAD pointing to branch foo to "
HEAD->foo". This can be seen as giving more information about the decoration item itself in the same way as we prefix tags by "tag: ".Signed-off-by Michael J Gruber <[email protected]>---
Notes:
v2 decorates the HEAD pointing to master as "HEAD->master", a detached HEAD just as "HEAD". The "->" hopefully conveys the symlink nature - a "=" would be confusing.
Quoted 4 lines
Somehow I still prefer "detached HEAD", dunno. Maybe in addition?
Note that now a checked branch is listed twice, once as target of the HEAD, once as branch: They are two different refs and colored differently.
The pointee of HEAD would always be branch and will always appear on the output when you show HEAD->$name_of_that_branch; is it feasible to drop the duplicate, I wonder?
Quoted 73 lines
log-tree.c | 8 +++++++- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-)log-tree.c +7
-1@@ -118,8 +118,11 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in type =DECORATION_REF_TAG ; else if (!strcmp(refname, "refs/stash")) type =DECORATION_REF_STASH ; - else if (!strcmp(refname, "HEAD")) + else if (!strcmp(refname, "HEAD")) { +unsigned char junk_sha1[20 ]; type =DECORATION_REF_HEAD ; + refname =resolve_ref_unsafe ("HEAD" ,0 , junk_sha1,NULL ); + }if (!cb_data || *(int *)cb_data ==DECORATE_SHORT_REFS ) refname =prettify_refname (refname);@@ -198,6 +201,9 @@ void format_decorations_extended(struct strbuf *sb,strbuf_addstr (sb,decorate_get_color (use_color, decoration->type));if (decoration->type ==DECORATION_REF_TAG )strbuf_addstr (sb,"tag: " ); +else if (decoration->type ==DECORATION_REF_HEAD && +strcmp (decoration->name,"HEAD" )) +strbuf_addstr (sb,"HEAD->" );strbuf_addstr (sb, decoration->name);strbuf_addstr (sb, color_reset); prefix = separator;t/t4013/diff.log_--decorate=full_--all +1
-1@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD->refs/heads/master, refs/heads/master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000t/t4013/diff.log_--decorate_--all +1
-1@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD->master, master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000t/t4207-log-decoration-colors.sh +1
-1@@ -44,7 +44,7 @@ test_expect_success setup ' ' cat >expected <<EOF -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD${c_reset}${c_commit},\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD->master${c_reset}${c_commit},\ ${c_tag}tag: v1.0${c_reset}${c_commit},\ ${c_tag}tag: B${c_reset}${c_commit},\ ${c_branch}master${c_reset}${c_commit})${c_reset} B
Re: [PATCH] log: decorate detached HEAD differently
Junio C Hamano venit, vidit, dixit 06.03.2015 20:03:
Quoted 17 lines
Quoted 15 lines · Michael J Gruber
"git status" and "git branch" let the user know when the HEAD is detached, as well as the current branch, while "git log --decorate" does not.
Change the decoration by a non-detached HEAD pointing to branch foo to "
HEAD->foo". This can be seen as giving more information about the decoration item itself in the same way as we prefix tags by "tag: ".Signed-off-by Michael J Gruber <[email protected]>---
Notes:
v2 decorates the HEAD pointing to master as "HEAD->master", a detached HEAD just as "HEAD". The "->" hopefully conveys the symlink nature - a "=" would be confusing.
Quoted 8 lines
Quoted 4 lines
Somehow I still prefer "detached HEAD", dunno. Maybe in addition?
Note that now a checked branch is listed twice, once as target of the HEAD, once as branch: They are two different refs and colored differently.
The pointee of HEAD would always be branch and will always appear on the output when you show HEAD->$name_of_that_branch; is it feasible to drop the duplicate, I wonder?
It's doable but not nice, because we cannot take the order in which refs are processed for granted.
I also think that we shouldn't simply check whether branch foo is checked out (when decorating with foo) - we need to know whether HEAD is among the refs which are eligible for decoration. That caveat is also true for the "always" above. (I don't think we allow decorating by a subset of all refs right now, but it would be useful, and easy given the for-each-ref machinery.)
Also, HEAD and foo are two different refs, so even if HEAD has the value "foo", I think we should really show them both anyways.
Alternatively, we could decorate by (HEAD, *foo, master, tag: release) if foo is checked out, just like branch does.
Quoted 72 lines
Quoted 72 lines
log-tree.c | 8 +++++++- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-)log-tree.c +7
-1@@ -118,8 +118,11 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in type =DECORATION_REF_TAG ; else if (!strcmp(refname, "refs/stash")) type =DECORATION_REF_STASH ; - else if (!strcmp(refname, "HEAD")) + else if (!strcmp(refname, "HEAD")) { +unsigned char junk_sha1[20 ]; type =DECORATION_REF_HEAD ; + refname =resolve_ref_unsafe ("HEAD" ,0 , junk_sha1,NULL ); + }if (!cb_data || *(int *)cb_data ==DECORATE_SHORT_REFS ) refname =prettify_refname (refname);@@ -198,6 +201,9 @@ void format_decorations_extended(struct strbuf *sb,strbuf_addstr (sb,decorate_get_color (use_color, decoration->type));if (decoration->type ==DECORATION_REF_TAG )strbuf_addstr (sb,"tag: " ); +else if (decoration->type ==DECORATION_REF_HEAD && +strcmp (decoration->name,"HEAD" )) +strbuf_addstr (sb,"HEAD->" );strbuf_addstr (sb, decoration->name);strbuf_addstr (sb, color_reset); prefix = separator;t/t4013/diff.log_--decorate=full_--all +1
-1@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD->refs/heads/master, refs/heads/master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000t/t4013/diff.log_--decorate_--all +1
-1@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD->master, master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000t/t4207-log-decoration-colors.sh +1
-1@@ -44,7 +44,7 @@ test_expect_success setup ' ' cat >expected <<EOF -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD${c_reset}${c_commit},\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD->master${c_reset}${c_commit},\ ${c_tag}tag: v1.0${c_reset}${c_commit},\ ${c_tag}tag: B${c_reset}${c_commit},\ ${c_branch}master${c_reset}${c_commit})${c_reset} B
Re: [PATCH] log: decorate detached HEAD differently
Quoted 6 lines · Michael J Gruber
Junio C Hamano venit, vidit, dixit 06.03.2015 20:03:
Quoted 5 lines
Quoted 3 lines · Michael J Gruber
Note that now a checked branch is listed twice, once as target of the HEAD, once as branch: They are two different refs and colored differently.
Quoted 6 lines
Quoted 3 lines
The pointee of HEAD would always be branch and will always appear on the output when you show HEAD->$name_of_that_branch; is it feasible to drop the duplicate, I wonder?
It's doable but not nice, because we cannot take the order in which refs are processed for granted.
That is true, but when we format them into a single line in the header in response to --decorate (or %d), don't we have all of them already at hand---does the order still matter?
Here is an illustration of what I had in mind, made on a random commit I happened to have checked out that does not have your patches on this topic. Half of the change is a new helper function, and the other half is mostly reindenting.
log-tree.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 8 deletions(-)
log-tree.c +63 -8
@@ -173,6 +173,43 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre }/* +* Do we have HEAD in the output, and also the branch it points at? +* If so, find that decoration entry for that current branch. +*/ +static const struct name_decoration *current_pointed_by_HEAD (const struct name_decoration *decoration) +{ +const struct name_decoration *list, *head =NULL ; +const char *branch_name =NULL ; +unsigned char unused[20 ]; +int rru_flags; + +/* First find HEAD */ +for (list = decoration; list; list = list->next) +if (list->type ==DECORATION_REF_HEAD ) { + head = list; +break ; + } +if (!head) +return NULL ; + +/* Now resolve and find the matching current branch */ + branch_name =resolve_ref_unsafe ("HEAD" ,0 , unused, &rru_flags); +if (!(rru_flags &REF_ISSYMREF )) +return NULL ; +if (!skip_prefix (branch_name,"refs/heads/" , &branch_name)) +return NULL ; + +/* OK, do we have that ref in the list? */ +for (list = decoration; list; list = list->next) +if ((list->type ==DECORATION_REF_LOCAL ) && + !strcmp (branch_name, list->name)) { +return list; + } + +return NULL ; +} + +/* * The caller makes sure there is no funny color before calling. * format_decorations_extended makes sure the same after return. */
@@ -184,6 +221,7 @@ void format_decorations_extended(struct strbuf *sb, const char *suffix) {const struct name_decoration *decoration; +const struct name_decoration *current_and_HEAD;const char *color_commit =diff_get_color (use_color,DIFF_COMMIT ); const char *color_reset =
@@ -192,15 +230,32 @@ void format_decorations_extended(struct strbuf *sb, decoration =get_name_decoration (&commit->object);if (!decoration)return ; + + current_and_HEAD =current_pointed_by_HEAD (decoration);while (decoration) { -strbuf_addstr (sb, color_commit); -strbuf_addstr (sb, prefix); -strbuf_addstr (sb,decorate_get_color (use_color, decoration->type)); -if (decoration->type ==DECORATION_REF_TAG ) -strbuf_addstr (sb,"tag: " ); -strbuf_addstr (sb, decoration->name); -strbuf_addstr (sb, color_reset); - prefix = separator; +/* +* When both current and HEAD are there, only +* show HEAD->current where HEAD would have +* appeaed, skipping the entry for current. +*/ +if (current_and_HEAD && decoration == current_and_HEAD) + ; +else { +strbuf_addstr (sb, color_commit); +strbuf_addstr (sb, prefix); +strbuf_addstr (sb,decorate_get_color (use_color, decoration->type)); +if (decoration->type ==DECORATION_REF_TAG ) +strbuf_addstr (sb,"tag: " ); + +if (current_and_HEAD && + decoration->type ==DECORATION_REF_HEAD ) +strbuf_addf (sb,"HEAD->%s" , current_and_HEAD->name); +else +strbuf_addstr (sb, decoration->name); +strbuf_addstr (sb, color_reset); + + prefix = separator; + } decoration = decoration->next; }strbuf_addstr (sb, color_commit);
Re: [PATCH] log: decorate detached HEAD differently
Junio C Hamano venit, vidit, dixit 10.03.2015 03:03:
Quoted 15 lines
Quoted 6 lines · Michael J Gruber
Junio C Hamano venit, vidit, dixit 06.03.2015 20:03:
Quoted 5 lines
Quoted 3 lines · Michael J Gruber
Note that now a checked branch is listed twice, once as target of the HEAD, once as branch: They are two different refs and colored differently.
Quoted 6 lines
Quoted 3 lines
The pointee of HEAD would always be branch and will always appear on the output when you show HEAD->$name_of_that_branch; is it feasible to drop the duplicate, I wonder?
It's doable but not nice, because we cannot take the order in which refs are processed for granted.
Quoted 8 lines
That is true, but when we format them into a single line in the header in response to --decorate (or %d), don't we have all of them already at hand---does the order still matter?
Here is an illustration of what I had in mind, made on a random commit I happened to have checked out that does not have your patches on this topic. Half of the change is a new helper function, and the other half is mostly reindenting.
Yes, the patch illustrates pretty well what I meant by "doable but not nice" :)
Quoted 5 lines · But I also
Also, HEAD and foo are two different refs, so even if HEAD has the value "foo", I think we should really show them both anyways.
Alternatively, we could decorate by (HEAD, *foo, master, tag: release) if foo is checked out, just like branch does.
I guess I will have to apply your patch and feel what it's like in practical use in order to change my mind...
Michael
PATCH v2 1/2 log-tree: properly reset colors
Except for the separator, all output items reset the color immediately. Do the same for the separator.
This affects only cases where setting color A does not override color B, such as when one is forground and one background.
--- log-tree.c | 1 + t/t4207-log-decoration-colors.sh | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-)
log-tree.c +1 -0
@@ -195,6 +195,7 @@ void format_decorations_extended(struct strbuf *sb,while (decoration) {strbuf_addstr (sb, color_commit);strbuf_addstr (sb, prefix); +strbuf_addstr (sb, color_reset);strbuf_addstr (sb,decorate_get_color (use_color, decoration->type));if (decoration->type ==DECORATION_REF_TAG )strbuf_addstr (sb,"tag: " );
t/t4207-log-decoration-colors.sh +8 -8
@@ -44,15 +44,15 @@ test_expect_success setup ' ' cat >expected <<EOF -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD${c_reset}${c_commit},\ - ${c_tag}tag: v1.0${c_reset}${c_commit},\ - ${c_tag}tag: B${c_reset}${c_commit},\ - ${c_branch}master${c_reset}${c_commit})${c_reset} B -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_tag}tag: A1${c_reset}${c_commit},\ - ${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1 -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_HEAD}HEAD${c_reset}${c_commit},\ + ${c_reset}${c_tag}tag: v1.0${c_reset}${c_commit},\ + ${c_reset}${c_tag}tag: B${c_reset}${c_commit},\ + ${c_reset}${c_branch}master${c_reset}${c_commit})${c_reset} B +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_tag}tag: A1${c_reset}${c_commit},\ + ${c_reset}${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1 +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\ On master: Changes to A.t -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_tag}tag: A${c_reset}${c_commit})${c_reset} A +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_tag}tag: A${c_reset}${c_commit})${c_reset} A EOF # We want log to show all, but the second parent to refs/stash is irrelevant
Signature · 1 line
2.3.2.346.gb6960c9
PATCH v2 2/2 log: decorate HEAD with branch name
In reply to Michael J GruberFrom: Junio C Hamano <[email protected]>
Currently, log decorations do not indicate which branch is checked out and whether HEAD is detached.
When branch foo is checked out, change the "HEAD, foo" part of the decorations to "HEAD -> foo". This serves to indicate both ref decorations (helped by the spacing) as well as their relationshsip. As a consequence, "HEAD" without any " -> " denotes a detached HEAD now.
---
Notes:
The patch is really Junio's now.
I just simplified the if's and added colors and tests. The spaces around "->" should help to make the branch stick out even without colors.
log-tree.c | 77 ++++++++++++++++++++++++++++++++++----- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 6 +-- 3 files changed, 72 insertions(+), 13 deletions(-)
log-tree.c +68 -9
@@ -173,6 +173,43 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre }/* +* Do we have HEAD in the output, and also the branch it points at? +* If so, find that decoration entry for that current branch. +*/ +static const struct name_decoration *current_pointed_by_HEAD (const struct name_decoration *decoration) +{ +const struct name_decoration *list, *head =NULL ; +const char *branch_name =NULL ; +unsigned char unused[20 ]; +int rru_flags; + +/* First find HEAD */ +for (list = decoration; list; list = list->next) +if (list->type ==DECORATION_REF_HEAD ) { + head = list; +break ; + } +if (!head) +return NULL ; + +/* Now resolve and find the matching current branch */ + branch_name =resolve_ref_unsafe ("HEAD" ,0 , unused, &rru_flags); +if (!(rru_flags &REF_ISSYMREF )) +return NULL ; +if (!skip_prefix (branch_name,"refs/heads/" , &branch_name)) +return NULL ; + +/* OK, do we have that ref in the list? */ +for (list = decoration; list; list = list->next) +if ((list->type ==DECORATION_REF_LOCAL ) && + !strcmp (branch_name, list->name)) { +return list; + } + +return NULL ; +} + +/* * The caller makes sure there is no funny color before calling. * format_decorations_extended makes sure the same after return. */
@@ -184,6 +221,7 @@ void format_decorations_extended(struct strbuf *sb, const char *suffix) {const struct name_decoration *decoration; +const struct name_decoration *current_and_HEAD;const char *color_commit =diff_get_color (use_color,DIFF_COMMIT ); const char *color_reset =
@@ -192,16 +230,37 @@ void format_decorations_extended(struct strbuf *sb, decoration =get_name_decoration (&commit->object);if (!decoration)return ; + + current_and_HEAD =current_pointed_by_HEAD (decoration);while (decoration) { -strbuf_addstr (sb, color_commit); -strbuf_addstr (sb, prefix); -strbuf_addstr (sb, color_reset); -strbuf_addstr (sb,decorate_get_color (use_color, decoration->type)); -if (decoration->type ==DECORATION_REF_TAG ) -strbuf_addstr (sb,"tag: " ); -strbuf_addstr (sb, decoration->name); -strbuf_addstr (sb, color_reset); - prefix = separator; +/* +* When both current and HEAD are there, only +* show HEAD->current where HEAD would have +* appeared, skipping the entry for current. +*/ +if (decoration != current_and_HEAD) { +strbuf_addstr (sb, color_commit); +strbuf_addstr (sb, prefix); +strbuf_addstr (sb, color_reset); +strbuf_addstr (sb,decorate_get_color (use_color, decoration->type)); +if (decoration->type ==DECORATION_REF_TAG ) +strbuf_addstr (sb,"tag: " ); + +strbuf_addstr (sb, decoration->name); + +if (current_and_HEAD && + decoration->type ==DECORATION_REF_HEAD ) { +strbuf_addstr (sb, color_reset); +strbuf_addstr (sb, color_commit); +strbuf_addstr (sb," -> " ); +strbuf_addstr (sb, color_reset); +strbuf_addstr (sb,decorate_get_color (use_color, current_and_HEAD->type)); +strbuf_addstr (sb, current_and_HEAD->name); + } +strbuf_addstr (sb, color_reset); + + prefix = separator; + } decoration = decoration->next; }strbuf_addstr (sb, color_commit);
t/t4013/diff.log_--decorate_--all +1 -1
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000
t/t4207-log-decoration-colors.sh +3 -3
@@ -44,10 +44,10 @@ test_expect_success setup ' ' cat >expected <<EOF -${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_HEAD}HEAD${c_reset}${c_commit},\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_HEAD}HEAD${c_reset}${c_commit} ->\ + ${c_reset}${c_branch}master${c_reset}${c_commit},\ ${c_reset}${c_tag}tag: v1.0${c_reset}${c_commit},\ - ${c_reset}${c_tag}tag: B${c_reset}${c_commit},\ - ${c_reset}${c_branch}master${c_reset}${c_commit})${c_reset} B + ${c_reset}${c_tag}tag: B${c_reset}${c_commit})${c_reset} B ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_tag}tag: A1${c_reset}${c_commit},\ ${c_reset}${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\
Signature · 1 line
2.3.2.346.gb6960c9
v2 cover log decorations for HEAD
In reply to Michael J GruberSo it didn't take too long to convince me after all :)
Here comes Junio's version, preceded by a cleanup of the color setting and resetting for decorations.
Junio C Hamano (1):
log: decorate HEAD with branch name
Michael J Gruber (1):
log-tree: properly reset colors
log-tree.c | 76 ++++++++++++++++++++++++++++++++++----- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 16 ++++----- 3 files changed, 77 insertions(+), 17 deletions(-)
Signature · 1 line
2.3.2.346.gb6960c9
Re: [PATCHv2 0/2] log decorations for HEAD
Quoted 8 lines · Michael J Gruber
So it didn't take too long to convince me after all :)
Here comes Junio's version, preceded by a cleanup of the color setting and resetting for decorations.
Junio C Hamano (1):
log: decorate HEAD with branch name
Quoted 7 lines
Michael J Gruber (1):
log-tree: properly reset colorslog-tree.c | 76 ++++++++++++++++++++++++++++++++++----- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 16 ++++----- 3 files changed, 77 insertions(+), 17 deletions(-)
Hmph, is the "do not leak commit color" one the same as 5ee87585 (log --decorate: do not leak "commit" color into the next item, 2015-03-04) aka $gmane/264788 [*1*] or is there something I missed?
[References]
*1* http://thread.gmane.org/gmane.comp.version-control.git/264063/focus=264788
Re: [PATCHv2 0/2] log decorations for HEAD
Junio C Hamano venit, vidit, dixit 10.03.2015 18:06:
Quoted 13 lines
Quoted 11 lines · Michael J Gruber
So it didn't take too long to convince me after all :)
Here comes Junio's version, preceded by a cleanup of the color setting and resetting for decorations.
Junio C Hamano (1):
log: decorate HEAD with branch nameMichael J Gruber (1):
log-tree: properly reset colors
Quoted 9 lines
Quoted 4 lines
log-tree.c | 76 ++++++++++++++++++++++++++++++++++----- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 16 ++++----- 3 files changed, 77 insertions(+), 17 deletions(-)Hmph, is the "do not leak commit color" one the same as
5ee87585(log --decorate: do not leak "commit" color into the next item, 2015-03-04) aka $gmane/264788 [*1*] or is there something I missed?
Uh, I missed that one. The commit msg confuses me somewhat (color.diff vs color.decorate), but the patch to log-tree.c is the same, and so I assume the patch to t4207 is the same, too. 2/2 from here should go on top of 7/7 from there, accordingly.
Quoted 7 lines
[References]
*1* http://thread.gmane.org/gmane.comp.version-control.git/264063/focus=264788
Re: [PATCHv2 0/2] log decorations for HEAD
In reply to Michael J GruberQuoted 12 lines · Michael J Gruber
So it didn't take too long to convince me after all :)
Here comes Junio's version, preceded by a cleanup of the color setting and resetting for decorations.
Junio C Hamano (1):
log: decorate HEAD with branch nameMichael J Gruber (1):
log-tree: properly reset colors
Quoted 8 lines
log-tree.c | 76 ++++++++++++++++++++++++++++++++++----- t/t4013/diff.log_--decorate_--all | 2 +- t/t4207-log-decoration-colors.sh | 16 ++++----- 3 files changed, 77 insertions(+), 17 deletions(-)--
2.3.2.346.gb6960c9
I'm so glad you've implemented this. Thanks again.
I hope I'll get familiar enough with the Git codebase to start posting patches of my own, in the future.
Jubobs