Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Thu, Sep 17, 2015 at 10:38 PM, Matthieu Moy wrote: > Junio C Hamano writes: > >> Matthieu Moy writes: >> >>> But that's still workable: struct ref_sorting could contain a flag >>> "head_first" that would be set by ref_default_sorting() and only it, and >>> then read by cmp_ref_sorting. >> >> Hmm, I am still puzzled. "refname" atom would expand to things like >> "HEAD", "refs/heads/master", etc., so I still do not see a need for >> head_first option at all. "HEAD" will sort before "refs/anything" >> always, no? > > Ah, you mean, the alphabetic order on refname already sorts HEAD first > because other refs will start with "refs/"? So, there's no need for any > special case at all indeed. Nothing to teach compare_refs, it's already > doing it. > > However, just relying on this seems a bit fragile to me: if we ever > allow listing e.g. FETCH_HEAD as a reference, then we would get > > FETCH_HEAD > * (HEAD detached at ...) > master > > which seems weird to me. But we can decide "if sorting on refname, then > HEAD always comes first anyway". Thanks for explaining what I had in mind, Seems like the confusion is sorted, I have nothing more to add to this discussion. Junio is right, sorting by "refname" would indeed work, I was just thinking along the lines of what you're ;) -- Regards, Karthik Nayak -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Matthieu Moy writes: > ... But we can decide "if sorting on refname, then > HEAD always comes first anyway". Sure. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Junio C Hamano writes: > Matthieu Moy writes: > >> But that's still workable: struct ref_sorting could contain a flag >> "head_first" that would be set by ref_default_sorting() and only it, and >> then read by cmp_ref_sorting. > > Hmm, I am still puzzled. "refname" atom would expand to things like > "HEAD", "refs/heads/master", etc., so I still do not see a need for > head_first option at all. "HEAD" will sort before "refs/anything" > always, no? Ah, you mean, the alphabetic order on refname already sorts HEAD first because other refs will start with "refs/"? So, there's no need for any special case at all indeed. Nothing to teach compare_refs, it's already doing it. However, just relying on this seems a bit fragile to me: if we ever allow listing e.g. FETCH_HEAD as a reference, then we would get FETCH_HEAD * (HEAD detached at ...) master which seems weird to me. But we can decide "if sorting on refname, then HEAD always comes first anyway". -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Matthieu Moy writes: > But that's still workable: struct ref_sorting could contain a flag > "head_first" that would be set by ref_default_sorting() and only it, and > then read by cmp_ref_sorting. Hmm, I am still puzzled. "refname" atom would expand to things like "HEAD", "refs/heads/master", etc., so I still do not see a need for head_first option at all. "HEAD" will sort before "refs/anything" always, no? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Junio C Hamano writes: > Matthieu Moy writes: > >> Karthik Nayak writes: >> >>> So either we could introduce a new atom for sorting something like >>> `branch_sort` which uses the FILTER_REFS_(DETACHED_HEAD | BRANCHES | >>> REMOTES) >> >> I don't think you need a new atom. You can just change the sorting >> function to consider that detached HEAD is always first, and when >> comparing two non-detached-HEAD branches, use the atom supplied by the >> user. >> >> That would mean the detached HEAD would be displayed first regardless of >> --sort (which is the case right now). > > I am a bit fuzzy about this. I do not understand why Karthik thinks > a new atom is necessary in the first place, and I do agree that the > best way to go would be to teach the sort function to do "the right > thing", but I am not sure why it has to be "regardless of --sort". I think Karthik meant that branch could default to "--sort=my_magic_atom_that_does_the_right_thing". In this case, the default would be to show HEAD first, but using "--sort" explicitly would change the order and interleave HEAD within other branches. IOW, we have: struct ref_sorting *ref_default_sorting(void) { static const char cstr_name[] = "refname"; struct ref_sorting *sorting = xcalloc(1, sizeof(*sorting)); sorting->next = NULL; sorting->atom = parse_ref_filter_atom(cstr_name, cstr_name + strlen(cstr_name)); return sorting; } and we could - static const char cstr_name[] = "refname"; + static const char cstr_name[] = "some_magic_atom"; But you convinced me that this is not a good idea. > When the user does give a custom --sort criteria, the logic in > default_sort() The logic itself is not in ref_default_sorting() (I guess this is what you meant by "default_sort"): this function just builds a struct ref_sorting that is later used by the more general cmp_ref_sorting. But that's still workable: struct ref_sorting could contain a flag "head_first" that would be set by ref_default_sorting() and only it, and then read by cmp_ref_sorting. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Matthieu Moy writes: > Karthik Nayak writes: > >> So either we could introduce a new atom for sorting something like >> `branch_sort` which uses the FILTER_REFS_(DETACHED_HEAD | BRANCHES | >> REMOTES) > > I don't think you need a new atom. You can just change the sorting > function to consider that detached HEAD is always first, and when > comparing two non-detached-HEAD branches, use the atom supplied by the > user. > > That would mean the detached HEAD would be displayed first regardless of > --sort (which is the case right now). I am a bit fuzzy about this. I do not understand why Karthik thinks a new atom is necessary in the first place, and I do agree that the best way to go would be to teach the sort function to do "the right thing", but I am not sure why it has to be "regardless of --sort". In the original for-each-ref (before it was butchered^W updated with ref-filter), we grab refs and sort with default_sort() when "--sort" is not given. When --sort is given, we just use atoms to compare. I do not think ref-filter broke that pattern, and as long as it kept that pattern, I do not think the solution has to be more than just "teach that default_sort() function, which sorts by refname, to always show HEAD first". When you throw HEAD into the mix, instead of grabbing only from refs/*, you can still give that set to a sorting function, which by default puts "HEAD" before others (just like the sorting function for "branch -a" by default puts local before remote-tracking), and you are done, no? When the user does give a custom --sort criteria, the logic in default_sort() would not kick in, so there is no need for special casing for "HEAD" like the code I questioned in this thread. What am I missing? > Introducing a new atom would mean that "git branch --sort authorname" > would not use this new atom, hence the HEAD would be sorted like the > others. I think that is exactly what people would expect. Perhaps a slightly tricky would be "git branch -a --sort refname". If you have HEAD, refs/heads/master, and refs/remotes/origin/master, I'd expect that it would sort these in that order purely because that is the textual/ascii sort order of the FULL refname. And then at the presentation level you would strip refs/heads and refs/remotes from local and remote-tracking branches, just like "git branch -a" output has always done, from the sorted result when showing. "git branch -a --sort refname:short" would sort using HEAD vs master vs origin/master in the above example and would end up mixing loal and remote-tracking together, but that is what the user is asking for, and the user deserves to get what s/he asked for. Somewhat confused -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Karthik Nayak writes: > So either we could introduce a new atom for sorting something like > `branch_sort` which uses the FILTER_REFS_(DETACHED_HEAD | BRANCHES | > REMOTES) I don't think you need a new atom. You can just change the sorting function to consider that detached HEAD is always first, and when comparing two non-detached-HEAD branches, use the atom supplied by the user. That would mean the detached HEAD would be displayed first regardless of --sort (which is the case right now). Introducing a new atom would mean that "git branch --sort authorname" would not use this new atom, hence the HEAD would be sorted like the others. I don't know if this is good or bad. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Wed, Sep 16, 2015 at 11:53 AM, Karthik Nayak wrote: > On Tue, Sep 15, 2015 at 1:05 AM, Junio C Hamano wrote: >> Karthik Nayak writes: >> >>> + /* >>> + * First we obtain all regular branch refs and if the HEAD is >>> + * detached then we insert that ref to the end of the ref_fist >>> + * so that it can be printed and removed first. >>> + */ >>> for_each_rawref(append_ref, &cb); >>> + if (detached) >>> + head_ref(append_ref, &cb); >>> + index = ref_list.index; >>> + >>> + /* Print detached HEAD before sorting and printing the rest */ >>> + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) >>> && >>> + !strcmp(ref_list.list[index - 1].name, head)) { >>> + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, >>> abbrev, >>> +1, remote_prefix); >>> + index -= 1; >>> + } >>> >>> + qsort(ref_list.list, index, sizeof(struct ref_item), ref_cmp); >> >> This looks somewhat strange. Wouldn't it be more consistent to >> teach ref_cmp that HEAD sorts where in the collection of refs (I >> presume that kind is checked first and then name, so if you give >> REF_DETACHED_HEAD a low number than others, it would automatically >> give you the ordering you want) without all of the above special >> casing? > > Thats nice, we could do that, something like this perhaps: > > qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); > > for (i = 0; i < ref_list.index; i++) { > int current = !detached && (ref_list.list[i].kind == > REF_LOCAL_BRANCH) && > !strcmp(ref_list.list[i].name, head); > /* If detached the first ref_item is the current ref */ > if (detached && i == 0) > current = 1; > print_ref_item(&ref_list.list[i], maxwidth, verbose, >abbrev, current, remote_prefix); > } > Although this solves the problem here, we'd still need to do something similar when we use ref-filter APIs as in [PATCH 7/8]. So either we could introduce a new atom for sorting something like `branch_sort` which uses the FILTER_REFS_(DETACHED_HEAD | BRANCHES | REMOTES) to sort or we could sort after printing the detached head, as done in this series. I'm ok with either. -- Regards, Karthik Nayak -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Tue, Sep 15, 2015 at 1:05 AM, Junio C Hamano wrote: > Karthik Nayak writes: > >> + /* >> + * First we obtain all regular branch refs and if the HEAD is >> + * detached then we insert that ref to the end of the ref_fist >> + * so that it can be printed and removed first. >> + */ >> for_each_rawref(append_ref, &cb); >> + if (detached) >> + head_ref(append_ref, &cb); >> + index = ref_list.index; >> + >> + /* Print detached HEAD before sorting and printing the rest */ >> + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && >> + !strcmp(ref_list.list[index - 1].name, head)) { >> + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, >> abbrev, >> +1, remote_prefix); >> + index -= 1; >> + } >> >> + qsort(ref_list.list, index, sizeof(struct ref_item), ref_cmp); > > This looks somewhat strange. Wouldn't it be more consistent to > teach ref_cmp that HEAD sorts where in the collection of refs (I > presume that kind is checked first and then name, so if you give > REF_DETACHED_HEAD a low number than others, it would automatically > give you the ordering you want) without all of the above special > casing? Thats nice, we could do that, something like this perhaps: qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); for (i = 0; i < ref_list.index; i++) { int current = !detached && (ref_list.list[i].kind == REF_LOCAL_BRANCH) && !strcmp(ref_list.list[i].name, head); /* If detached the first ref_item is the current ref */ if (detached && i == 0) current = 1; print_ref_item(&ref_list.list[i], maxwidth, verbose, abbrev, current, remote_prefix); } -- Regards, Karthik Nayak -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Karthik Nayak writes: > + /* > + * First we obtain all regular branch refs and if the HEAD is > + * detached then we insert that ref to the end of the ref_fist > + * so that it can be printed and removed first. > + */ > for_each_rawref(append_ref, &cb); > + if (detached) > + head_ref(append_ref, &cb); > + index = ref_list.index; > + > + /* Print detached HEAD before sorting and printing the rest */ > + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && > + !strcmp(ref_list.list[index - 1].name, head)) { > + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, > abbrev, > +1, remote_prefix); > + index -= 1; > + } > > + qsort(ref_list.list, index, sizeof(struct ref_item), ref_cmp); This looks somewhat strange. Wouldn't it be more consistent to teach ref_cmp that HEAD sorts where in the collection of refs (I presume that kind is checked first and then name, so if you give REF_DETACHED_HEAD a low number than others, it would automatically give you the ordering you want) without all of the above special casing? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Karthik Nayak writes: > On Mon, Sep 14, 2015 at 12:01 AM, Eric Sunshine > wrote: >> Specifically, I think you're referring to [1] (?). >> >> [1]: >> http://thread.gmane.org/gmane.comp.version-control.git/276363/focus=276676 > > No not that, that is handled in the previous patch series. > > I can't find the reference either, but the comment was along the lines of what > Matthieu just mentioned above, I had another message in mind too. Never mind, the comment is addressed, we don't need to know if it was a real message or a collective hallucination ;-). -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Mon, Sep 14, 2015 at 12:01 AM, Eric Sunshine wrote: > On Sun, Sep 13, 2015 at 12:46 PM, Eric Sunshine > wrote: >> On Sun, Sep 13, 2015 at 8:12 AM, Matthieu Moy >> wrote: >>> Karthik Nayak writes: >>> @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru if (verbose) maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); - qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); + index = ref_list.index; + + /* Print detached HEAD before sorting and printing the rest */ + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && + !strcmp(ref_list.list[index - 1].name, head)) { + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, abbrev, +1, remote_prefix); + index -= 1; + } >>> >>> I think Eric already mentionned it, but I don't remember the conclusion >>> and can't find it in the archives. Wouldn't it be cleaner to actually >>> remove the detached head from the array (do "ref_list.index -= 1" >>> instead of "index -= 1", and possibly free() what needs to be freed? >> >> I think Michael Haggerty mentioned something along those lines... > > Specifically, I think you're referring to [1] (?). > > [1]: > http://thread.gmane.org/gmane.comp.version-control.git/276363/focus=276676 No not that, that is handled in the previous patch series. I can't find the reference either, but the comment was along the lines of what Matthieu just mentioned above, But like I replied on [Patch 6/8] Its taken care of in that particular patch. Here it doesn't seem to be needed. -- Regards, Karthik Nayak -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Sun, Sep 13, 2015 at 12:46 PM, Eric Sunshine wrote: > On Sun, Sep 13, 2015 at 8:12 AM, Matthieu Moy > wrote: >> Karthik Nayak writes: >> >>> @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, >>> int verbose, int abbrev, stru >>> if (verbose) >>> maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); >>> >>> - qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), >>> ref_cmp); >>> + index = ref_list.index; >>> + >>> + /* Print detached HEAD before sorting and printing the rest */ >>> + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) >>> && >>> + !strcmp(ref_list.list[index - 1].name, head)) { >>> + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, >>> abbrev, >>> +1, remote_prefix); >>> + index -= 1; >>> + } >> >> I think Eric already mentionned it, but I don't remember the conclusion >> and can't find it in the archives. Wouldn't it be cleaner to actually >> remove the detached head from the array (do "ref_list.index -= 1" >> instead of "index -= 1", and possibly free() what needs to be freed? > > I think Michael Haggerty mentioned something along those lines... Specifically, I think you're referring to [1] (?). [1]: http://thread.gmane.org/gmane.comp.version-control.git/276363/focus=276676 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Sun, Sep 13, 2015 at 8:12 AM, Matthieu Moy wrote: > Karthik Nayak writes: > >> @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, int >> verbose, int abbrev, stru >> if (verbose) >> maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); >> >> - qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); >> + index = ref_list.index; >> + >> + /* Print detached HEAD before sorting and printing the rest */ >> + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && >> + !strcmp(ref_list.list[index - 1].name, head)) { >> + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, >> abbrev, >> +1, remote_prefix); >> + index -= 1; >> + } > > I think Eric already mentionned it, but I don't remember the conclusion > and can't find it in the archives. Wouldn't it be cleaner to actually > remove the detached head from the array (do "ref_list.index -= 1" > instead of "index -= 1", and possibly free() what needs to be freed? I think Michael Haggerty mentioned something along those lines... -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Sun, Sep 13, 2015 at 5:42 PM, Matthieu Moy wrote: > Karthik Nayak writes: > >> @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, int >> verbose, int abbrev, stru >> if (verbose) >> maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); >> >> - qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); >> + index = ref_list.index; >> + >> + /* Print detached HEAD before sorting and printing the rest */ >> + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && >> + !strcmp(ref_list.list[index - 1].name, head)) { >> + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, >> abbrev, >> +1, remote_prefix); >> + index -= 1; >> + } > > I think Eric already mentionned it, but I don't remember the conclusion > and can't find it in the archives. Wouldn't it be cleaner to actually > remove the detached head from the array (do "ref_list.index -= 1" > instead of "index -= 1", and possibly free() what needs to be freed? > > If you did so, you wouldn't have any possible confusion between the > local variable "index" and ref_list.index in the code below: This is cleared out in [PATCH 6/8]. -- Regards, Karthik Nayak -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Karthik Nayak writes: > @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, int > verbose, int abbrev, stru > if (verbose) > maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); > > - qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); > + index = ref_list.index; > + > + /* Print detached HEAD before sorting and printing the rest */ > + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && > + !strcmp(ref_list.list[index - 1].name, head)) { > + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, > abbrev, > +1, remote_prefix); > + index -= 1; > + } I think Eric already mentionned it, but I don't remember the conclusion and can't find it in the archives. Wouldn't it be cleaner to actually remove the detached head from the array (do "ref_list.index -= 1" instead of "index -= 1", and possibly free() what needs to be freed? If you did so, you wouldn't have any possible confusion between the local variable "index" and ref_list.index in the code below: > - detached = (detached && (kinds & REF_LOCAL_BRANCH)); > - if (detached && match_patterns(pattern, "HEAD")) > - show_detached(&ref_list, maxwidth); > + qsort(ref_list.list, index, sizeof(struct ref_item), ref_cmp); > > - for (i = 0; i < ref_list.index; i++) { > - int current = !detached && > - (ref_list.list[i].kind == REF_LOCAL_BRANCH) && > + for (i = 0; i < index; i++) { > + int current = !detached && (ref_list.list[i].kind == > REF_LOCAL_BRANCH) && > !strcmp(ref_list.list[i].name, head); > print_ref_item(&ref_list.list[i], maxwidth, verbose, > abbrev, current, remote_prefix); -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
Remove show_detached() and make detached HEAD to be rolled into regular ref_list by adding REF_DETACHED_HEAD as a kind of branch and supporting the same in append_ref(). This eliminates the need for an extra function and helps in easier porting of branch.c to use ref-filter APIs. Before show_detached() used to check if the HEAD branch satisfies the '--contains' option, now that is taken care by append_ref(). Based-on-patch-by: Jeff King Mentored-by: Christian Couder Mentored-by: Matthieu Moy Signed-off-by: Karthik Nayak --- builtin/branch.c | 68 +--- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 193296a..6ba7a3f 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -30,6 +30,7 @@ static const char * const builtin_branch_usage[] = { #define REF_LOCAL_BRANCH0x01 #define REF_REMOTE_BRANCH 0x02 +#define REF_DETACHED_HEAD 0x04 static const char *head; static unsigned char head_sha1[20]; @@ -352,8 +353,12 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag break; } } - if (ARRAY_SIZE(ref_kind) <= i) - return 0; + if (ARRAY_SIZE(ref_kind) <= i) { + if (!strcmp(refname, "HEAD")) + kind = REF_DETACHED_HEAD; + else + return 0; + } /* Don't add types the caller doesn't want */ if ((kind & ref_list->kinds) == 0) @@ -535,6 +540,8 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, int color; struct strbuf out = STRBUF_INIT, name = STRBUF_INIT; const char *prefix = ""; + const char *desc = item->name; + char *to_free = NULL; if (item->ignore) return; @@ -547,6 +554,10 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, color = BRANCH_COLOR_REMOTE; prefix = remote_prefix; break; + case REF_DETACHED_HEAD: + color = BRANCH_COLOR_CURRENT; + desc = to_free = get_head_description(); + break; default: color = BRANCH_COLOR_PLAIN; break; @@ -558,7 +569,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, color = BRANCH_COLOR_CURRENT; } - strbuf_addf(&name, "%s%s", prefix, item->name); + strbuf_addf(&name, "%s%s", prefix, desc); if (verbose) { int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf); strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color), @@ -581,6 +592,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose, } strbuf_release(&name); strbuf_release(&out); + free(to_free); } static int calc_maxwidth(struct ref_list *refs, int remote_bonus) @@ -601,25 +613,9 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus) return max; } -static void show_detached(struct ref_list *ref_list, int maxwidth) -{ - struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1); - - if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) { - struct ref_item item; - item.name = get_head_description(); - item.kind = REF_LOCAL_BRANCH; - item.dest = NULL; - item.commit = head_commit; - item.ignore = 0; - print_ref_item(&item, maxwidth, ref_list->verbose, ref_list->abbrev, 1, ""); - free(item.name); - } -} - static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern) { - int i; + int i, index; struct append_ref_cb cb; struct ref_list ref_list; int maxwidth = 0; @@ -643,7 +639,14 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru cb.ref_list = &ref_list; cb.pattern = pattern; cb.ret = 0; + /* +* First we obtain all regular branch refs and if the HEAD is +* detached then we insert that ref to the end of the ref_fist +* so that it can be printed and removed first. +*/ for_each_rawref(append_ref, &cb); + if (detached) + head_ref(append_ref, &cb); /* * The following implementation is currently duplicated in ref-filter. It * will eventually be removed when we port branch.c to use ref-filter APIs. @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru if (verbose) maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); - qsort(ref_list.list, ref_list.index