Re: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list

2015-09-17 Thread Karthik Nayak
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

2015-09-17 Thread Junio C Hamano
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

2015-09-17 Thread Matthieu Moy
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

2015-09-17 Thread Junio C Hamano
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

2015-09-17 Thread Matthieu Moy
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

2015-09-17 Thread Junio C Hamano
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

2015-09-17 Thread Matthieu Moy
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

2015-09-17 Thread Karthik Nayak
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

2015-09-15 Thread Karthik Nayak
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

2015-09-14 Thread Junio C Hamano
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

2015-09-14 Thread Matthieu Moy
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

2015-09-14 Thread Karthik Nayak
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

2015-09-13 Thread Eric Sunshine
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

2015-09-13 Thread Eric Sunshine
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

2015-09-13 Thread Karthik Nayak
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

2015-09-13 Thread Matthieu Moy
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

2015-09-13 Thread Karthik Nayak
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