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

Re: [PATCH 2/3] Move pathspec validation into interactive_add

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 24, 2007, 22:34 UTC
Message-ID
<7vtznbp91f.fsf@gitster.siamese.dyndns.org>
In-Reply-To
<4D81F973-8951-458A-958D-E24C826CA548@wincent.com>
Wincent Colaiuta <win@wincent.com> writes:
Show 15 quoted lines
> El 24/11/2007, a las 20:15, Junio C Hamano escribió:
>
>> Wincent Colaiuta <win@wincent.com> writes:
>>
>>> Instead of throwing away the return status of pathspec_match() I am
>>> keeping it, and any successful match breaks out of the loop early.
>>
>> Leaving it early before checking if all the given pathspecs are
>> used defeats the whole "error-unmatch" business, doesn't it?
>
> No, I probably didn't explain that clearly enough... If you look at
> the patch, I break out of the *inner* loop the first time a particular
> pattern matches. Then I move on to the next pattern, and any single
> invalid pattern will be enough to provide the "error-unmatch"
> indication.
Heh, I missed that the code was doing something so stupid ;-).

The helper function pathspec_match() takes a single path and a set of pathspecs (NULL terminated), and says if the path is covered with that set, while recording which one of the pathspecs caused the match in the ps_matched array.

You are checking first with the full set of patterns, then the full set minus the first pattern, and then the full set minus the first two patterns, and so on. No wonder it is inefficient.

Why are you trying to micro-optimize this part in the first place? Have you benchmarked and determined that iterating over full cache is the bottleneck?

In order to prove that there is a pathspec (or more) that does not match anything in the cache, you need to interate over the whole cache at least once. The only case you can short-cut is when you can tell that all of them have been used before you iterated over all cache entries.

So lose that silly outer loop, and replace the inner function with something like this:

        static int validate_pathspec(const char *prefix, const char **pattern)
        {
                int i, ret = 0, num_patterns;
                char *m;
                if (!pattern || !*pattern)
                        return 0;
                for (num_patterns = 0; pattern[num_patterns]; num_patterns++)
                        ;
                m = xcalloc(1, num_patterns + 1);
                for (i = 0; i < active_nr; i++) {
                        struct cache_entry *ce = active_cache[i];
                        if (pathspec_match(pattern, m, ce->name, 0)) {
                                /*
                                 * You could micro optimize by leaving
                                 * the loop early when you notice that all
				 * patterns are used.
				 *
                                 * if (strlen(m) == num_patterns)
                                 * 	goto ok;
				 *
                                 */ 
				; /* nothing */
			}
                }
                report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
        ok:
                free(m);
                return ret;
        }

My gut feeling is that the micro-optimization is not worth it here, but I didn't try. I think without the micro-optimization the above is the same as I gave you earlier.

Previous: Wincent Colaiuta
Message 18 of 18 in “git-add--interactive pathspec and patch additions”
  1. git-add--interactive pathspec and patch additionsWincent Colaiuta, Nov 23, 2007
  2. 1/7 Add -q/--quiet switch to git-ls-filesWincent Colaiuta, Nov 23, 2007
  3. 2/7 Rename patch_update_file function to patch_update_pathspecWincent Colaiuta, Nov 23, 2007
  4. 3/7 Add path-limiting to git-add--interactiveWincent Colaiuta, Nov 23, 2007
  5. 4/7 Bail if user supplies an invalid pathspecWincent Colaiuta, Nov 23, 2007
  6. 5/7 Teach builtin-add to pass path arguments to git-add--interactiveWincent Colaiuta, Nov 23, 2007
  7. 6/7 Add "--patch" option to git-add--interactiveWincent Colaiuta, Nov 23, 2007
  8. 7/7 Teach builtin-add to handle "--patch" optionWincent Colaiuta, Nov 23, 2007
  9. Wincent ColaiutaNov 23, 2007
  10. Junio C HamanoNov 23, 2007
  11. Wincent ColaiutaNov 23, 2007
  12. 0/3 Updates to git-add--interactiveWincent Colaiuta, Nov 24, 2007
  13. 1/3 Rename patch_update_file function to patch_update_pathspecWincent Colaiuta, Nov 24, 2007
  14. 2/3 Move pathspec validation into interactive_addWincent Colaiuta, Nov 24, 2007
  15. 3/3 Add "--patch" option to git-add--interactiveWincent Colaiuta, Nov 24, 2007
  16. Junio C HamanoNov 24, 2007
  17. Wincent ColaiutaNov 24, 2007
  18. Junio C HamanoNov 24, 2007

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.