git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 10/33] refs: extract a function ref_resolves_to_object()

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Apr 16, 2013, 09:27 UTC
Message-ID
<516D1988.5060501@alum.mit.edu>
In-Reply-To
<7v7gk3zqhc.fsf@alter.siamese.dyndns.org>
On 04/15/2013 06:51 PM, Junio C Hamano wrote:
Show 77 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> It is a nice unit of work and soon will be needed from multiple
>> locations.
>>
>> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
>> ---
>>  refs.c | 28 ++++++++++++++++++++--------
>>  1 file changed, 20 insertions(+), 8 deletions(-)
>>
>> diff --git a/refs.c b/refs.c
>> index c523978..dfc8600 100644
>> --- a/refs.c
>> +++ b/refs.c
>> @@ -529,6 +529,22 @@ static void sort_ref_dir(struct ref_dir *dir)
>>  #define DO_FOR_EACH_INCLUDE_BROKEN 0x01
>>  
>>  /*
>> + * Return true iff the reference described by entry can be resolved to
>> + * an object in the database.  Emit a warning if the referred-to
>> + * object does not exist.
>> + */
>> +static int ref_resolves_to_object(struct ref_entry *entry)
>> +{
>> +	if (entry->flag & REF_ISBROKEN)
>> +		return 0;
>> +	if (!has_sha1_file(entry->u.value.sha1)) {
>> +		error("%s does not point to a valid object!", entry->name);
>> +		return 0;
>> +	}
>> +	return 1;
>> +}
>> +
>> +/*
>>   * current_ref is a performance hack: when iterating over references
>>   * using the for_each_ref*() functions, current_ref is set to the
>>   * current reference's entry before calling the callback function.  If
>> @@ -549,14 +565,10 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
>>  	if (prefixcmp(entry->name, base))
>>  		return 0;
>>  
>> -	if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
>> -		if (entry->flag & REF_ISBROKEN)
>> -			return 0; /* ignore broken refs e.g. dangling symref */
>> -		if (!has_sha1_file(entry->u.value.sha1)) {
>> -			error("%s does not point to a valid object!", entry->name);
>> -			return 0;
>> -		}
>> -	}
>> +	if (!((flags & DO_FOR_EACH_INCLUDE_BROKEN) ||
>> +	      ref_resolves_to_object(entry)))
>> +		return 0;
>> +
> 
> The original says "Unless flags tell us to include broken ones,
> return 0 for the broken ones and the ones that point at invalid
> objects".
> 
> The updated says "Unless flags tell us to include broken ones or the
> ref is a good one, return 0".
> 
> Are they the same?  If we have a good one, and if we are not told to
> include broken one, the original just passes the control down to the
> remainder of the function.  The updated one will return 0.
> 
> Oh, wait, that is not the case.  The OR is inside !( A || B ), so
> what it really wants to say is:
> 
> 	if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
>             !ref_resolves_to_object(entry))
> 		return 0;
> 
> that is, "When we are told to exclude broken ones and the one we are
> looking at is broken, return 0".
> 
> Am I the only one who was confused with this, or was the way the
> patch wrote this logic unnecessarily convoluted?

I find either way of writing it hard to read quickly. I find that the construct

    if (!(situation in which the function should continue))
        return

makes it easier to pick out the "situation in which the function should continue". But granted, the nesting of multiple parentheses across lines compromises the clarity.

In projects where I can choose the coding standard, I like to use extra whitespace to help the eye pick out the range of parentheses, like

        if (!(
                (flags & DO_FOR_EACH_INCLUDE_BROKEN) ||
                ref_resolves_to_object(entry)
                ))
                return 0;
but I've never seen this style in the Git project so I haven't used it here.
Since you prefer the other version, I will change it.
Michael
-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
Previous: Junio C HamanoNext: Junio C Hamano
Message 15 of 64 in “Various cleanups around reference packing and peeling”
  1. 00/33 Various cleanups around reference packing and peelingMichael Haggerty, Apr 14, 2013
  2. 01/33 refs: document flags constants REF_*Michael Haggerty, Apr 14, 2013
  3. 02/33 refs: document the fields of struct ref_valueMichael Haggerty, Apr 14, 2013
  4. 03/33 refs: document do_for_each_ref() and do_one_ref()Michael Haggerty, Apr 14, 2013
  5. Junio C HamanoApr 15, 2013
  6. Michael HaggertyApr 16, 2013
  7. 04/33 refs: document how current_ref is usedMichael Haggerty, Apr 14, 2013
  8. 05/33 refs: define constant PEELED_LINE_LENGTHMichael Haggerty, Apr 14, 2013
  9. 06/33 do_for_each_ref_in_dirs(): remove dead codeMichael Haggerty, Apr 14, 2013
  10. 07/33 get_packed_ref(): return a ref_entryMichael Haggerty, Apr 14, 2013
  11. 08/33 peel_ref(): use function get_packed_ref()Michael Haggerty, Apr 14, 2013
  12. 09/33 repack_without_ref(): use function get_packed_ref()Michael Haggerty, Apr 14, 2013
  13. 10/33 refs: extract a function ref_resolves_to_object()Michael Haggerty, Apr 14, 2013
  14. Junio C HamanoApr 15, 2013
  15. Michael HaggertyApr 16, 2013
  16. Junio C HamanoApr 16, 2013
  17. 11/33 refs: extract function peel_object()Michael Haggerty, Apr 14, 2013
  18. 12/33 peel_object(): give more specific information in return valueMichael Haggerty, Apr 14, 2013
  19. Junio C HamanoApr 15, 2013
  20. 13/33 peel_ref(): fix return value for non-peelable, not-current referenceMichael Haggerty, Apr 14, 2013
  21. Junio C HamanoApr 15, 2013
  22. Michael HaggertyApr 16, 2013
  23. 14/33 refs: extract a function peel_entry()Michael Haggerty, Apr 14, 2013
  24. Junio C HamanoApr 15, 2013
  25. Michael HaggertyApr 16, 2013
  26. Junio C HamanoApr 16, 2013
  27. Michael HaggertyApr 16, 2013
  28. 15/33 refs: change the internal reference-iteration APIMichael Haggerty, Apr 14, 2013
  29. Junio C HamanoApr 15, 2013
  30. Michael HaggertyApr 16, 2013
  31. Junio C HamanoApr 16, 2013
  32. 16/33 t3210: test for spurious error messages for dangling packed refsMichael Haggerty, Apr 14, 2013
  33. Junio C HamanoApr 15, 2013
  34. Michael HaggertyApr 16, 2013
  35. Junio C HamanoApr 16, 2013
  36. Jeff KingApr 16, 2013
  37. Junio C HamanoApr 17, 2013
  38. Junio C HamanoApr 17, 2013
  39. 0/2 Add documentation for new expiry option valuesMichael Haggerty, Apr 18, 2013
  40. 1/2 git-gc.txt, git-reflog.txt: document new expiry optionsMichael Haggerty, Apr 18, 2013
  41. 2/2 api-parse-options.txt: document "no-" for non-boolean optionsMichael Haggerty, Apr 18, 2013
  42. prune: introduce OPT_EXPIRY_DATE() and use itJunio C Hamano, Apr 25, 2013
  43. Michael HaggertyApr 17, 2013
  44. 17/33 repack_without_ref(): silence errors for dangling packed refsMichael Haggerty, Apr 14, 2013
  45. Junio C HamanoApr 15, 2013
  46. Michael HaggertyApr 17, 2013
  47. 18/33 search_ref_dir(): return an index rather than a pointerMichael Haggerty, Apr 14, 2013
  48. 19/33 refs: change how packed refs are deletedMichael Haggerty, Apr 14, 2013
  49. 20/33 t3211: demonstrate loss of peeled refs if a packed ref is deletedMichael Haggerty, Apr 14, 2013
  50. 21/33 repack_without_ref(): write peeled refs in the rewritten fileMichael Haggerty, Apr 14, 2013
  51. Junio C HamanoApr 15, 2013
  52. 22/33 refs: extract a function write_packed_entry()Michael Haggerty, Apr 14, 2013
  53. 23/33 pack-refs: rename handle_one_ref() to pack_one_ref()Michael Haggerty, Apr 14, 2013
  54. 24/33 pack-refs: merge code from pack-refs.{c,h} into refs.{c,h}Michael Haggerty, Apr 14, 2013
  55. 25/33 pack_one_ref(): rename "path" parameter to "refname"Michael Haggerty, Apr 14, 2013
  56. 26/33 refs: use same lock_file object for both ref-packing functionsMichael Haggerty, Apr 14, 2013
  57. 27/33 pack_refs(): change to use do_for_each_entry()Michael Haggerty, Apr 14, 2013
  58. 28/33 refs: inline function do_not_prune()Michael Haggerty, Apr 14, 2013
  59. 29/33 pack_one_ref(): use function peel_entry()Michael Haggerty, Apr 14, 2013
  60. 30/33 pack_one_ref(): use write_packed_entry() to do the writingMichael Haggerty, Apr 14, 2013
  61. 31/33 pack_one_ref(): do some cheap tests before a more expensive oneMichael Haggerty, Apr 14, 2013
  62. 32/33 refs: change do_for_each_*() functions to take ref_cache argumentsMichael Haggerty, Apr 14, 2013
  63. Junio C HamanoApr 15, 2013
  64. 33/33 refs: handle the main ref_cache speciallyMichael Haggerty, Apr 14, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.