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

Re: [RFC/PATCH 00/48] Libifying git apply

From
Christian Couder <christian.couder@gmail.com>
Date
Mar 11, 2016, 17:34 UTC
Message-ID
<CAP8UFD0MEPpfpCHxkX-EKHb2F+xmObqZa4w1Ub=NQ=7W7OVLYw@mail.gmail.com>
In-Reply-To
<CACsJy8Bn1+zbALH347SNgGqSLR0ixCL0acW+DuUZH1g2HRS0ZA@mail.gmail.com>
On Thu, Mar 10, 2016 at 10:26 AM, Duy Nguyen <pclouds@gmail.com> wrote:
Show 31 quoted lines
> On Thu, Mar 10, 2016 at 12:48 AM, Christian Couder
> <christian.couder@gmail.com> wrote:
>> This is a patch series about libifying "git apply" functionality, to
>> be able to use this functionality in "git am" without spawning new
>> processes. This should make "git am" and "git rebase" significantly
>> faster.
>>
>> This has been discussed in the following thread:
>>
>> http://thread.gmane.org/gmane.comp.version-control.git/287236/
>>
>> This RFC patch series for now just gets rid of the global variables
>> and refactors the code around a bit.
>>
>> As suggested by Junio the global variables in builtin/apply.c are just
>> thrown into a single "apply_state" structure that is passed around the
>> callchain. A new parameter called "state" that is a pointer to the
>> "apply_state" structure comes at the beginning of the helper functions
>> that need it.
>>
>> Before I make further changes to handle erroneous input and make the
>> libified functions not die() and properly clean things up, I'd be
>> happy to get some feedback.
>
> I didn't review individual patches. Instead I redid the whole thing
> (in a slightly different way) and compared my end result to yours. In
> general it looks good but..
>
> 1) I think you should focus the series on moving global vars to struct
> apply_state only. You can save code move patches for the later phase.
> Easier to review.

I am not sure what you mean by "the later phase", but I tend to agree and that's mostly what I did. Most of the code move are at the end of the series so after the global variable related changes. There are a few exceptions because in a few cases it was difficult to understand the code without a refactoring. In such cases I think the refactoring can also actually help the reviewer.

Show 5 quoted lines
> 2) Given that there are only four local variables shadowing global
> ones, p_value, linenr and options, I think it's ok to drop 1/48 and
> 2/48 and keep the good old names. You just need to mention about them
> and what function they are declared in in the relevant "move global
> ..." patch so the reviewer is aware of it.

About 1/48 (builtin/apply: avoid parameter shadowing 'p_value') this is discussed in its own thread. In 2/48 (builtin/apply: avoid parameter shadowing 'linenr'), I change the "good old name" only twice in a small function, and I don't think keeping the old name is a big deal there.

Show 8 quoted lines
> 3) Moving lock_file to struct apply_state, then putting the whole
> struct on stack, could be problematic. I believe there's a global
> linked list keeping references of all lock_file variables until the
> end of time, so we can't destroy lock_file/apply_state until we are
> certain it's safe to do so. We could simply leave lock_file as a
> global var for now (with a note in struct apply_state so we don't
> forget). We can always do fancy stuff like malloc() later on if we
> need to.

Thanks for this information. Though I prefer to do the fancy stuff right away, that is something like:

diff --git a/builtin/apply.c b/builtin/apply.c
index 4f57bce..6029869 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -52,6 +52,12 @@ struct apply_state {
        const char *prefix;
        int prefix_length;

+       /*
+        * Since lockfile.c keeps a linked list of all created
+        * lock_file structures, it isn't safe to free(lock_file).
+        */
+       struct lock_file *lock_file;
+
        int apply;
        int allow_overlap;
        int apply_in_reverse;
@@ -4517,8 +4523,6 @@ static int write_out_results(struct apply_state
*state, struct patch *list)
        return errs;
 }

-static struct lock_file lock_file;
-
 #define INACCURATE_EOF (1<<0)
 #define RECOUNT                (1<<1)

@@ -4566,8 +4570,10 @@ static int apply_patch(struct apply_state *state,
                state->apply = 0;

        state->update_index = state->check_index && state->apply;
-       if (state->update_index && newfd < 0)
-               newfd = hold_locked_index(&lock_file, 1);
+       if (state->update_index && newfd < 0) {
+               state->lock_file = xcalloc(1, sizeof(struct lock_file));
+               newfd = hold_locked_index(state->lock_file, 1);
+       }

        if (state->check_index) {
                if (read_cache() < 0)
@@ -4780,7 +4786,7 @@ static int apply_all_patches(struct apply_state *state,
        }

        if (state->update_index) {
-               if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
+               if (write_locked_index(&the_index, state->lock_file,
COMMIT_LOCK))
                        die(_("Unable to write new index file"));
        }

It makes it possible to remove the 'newfd' variable as it is only used
to check if hold_locked_index() has already been called and now
"state->lock_file == NULL" can be used to do that.

By the way I wonder if I should also change "static struct lock_file
lock" in build_fake_ancestor().

> 4) I noticed on the interdiff that there are translatable strings in
> this file but not marked as such. You're going to spend lots of time
> reading this file and are in a very good positioin to determine if a
> string should be translated (i.e. wrap _() around it) or not. So maybe
> you can have a look at this in the next series too. It's absolutely ok
> if you say "no" here.

I will see if I can do that towards the end of the series, but this is
not at all on my radar for now.

> 5) Minor detail, but we can rename prefix_ to prefix in
> init_apply_state(). There trailing underscore was there in cmd_apply
> because there's the global "prefix", but it's gone now.

Yeah, I think this is worth doing, so it is done in my current series:

https://github.com/chriscool/git/commits/libify-apply21

> Looking forward to seeing you double, triple git-rebase's speed.

Thanks for your reviews and comments,
Christian.
Previous: Duy Nguyen
Message 58 of 58 in “Libifying git apply”
  1. 00/48 Libifying git applyChristian Couder, Mar 9, 2016
  2. 01/48 builtin/apply: avoid parameter shadowing 'p_value' globalChristian Couder, Mar 9, 2016
  3. Junio C HamanoMar 9, 2016
  4. Duy NguyenMar 10, 2016
  5. Christian CouderMar 10, 2016
  6. 02/48 builtin/apply: avoid parameter shadowing 'linenr' globalChristian Couder, Mar 9, 2016
  7. 03/48 builtin/apply: avoid local variable shadowing 'len' parameterChristian Couder, Mar 9, 2016
  8. 04/48 builtin/apply: extract line_by_line_fuzzy_match() from match_fragment()Christian Couder, Mar 9, 2016
  9. Stefan BellerMar 9, 2016
  10. Christian CouderMar 10, 2016
  11. 05/48 builtin/apply: move 'options' variable into cmd_apply()Christian Couder, Mar 9, 2016
  12. 06/48 builtin/apply: introduce 'struct apply_state' to start libifyingChristian Couder, Mar 9, 2016
  13. 07/48 builtin/apply: move 'newfd' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  14. 08/48 builtin/apply: move 'unidiff_zero' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  15. 09/48 builtin/apply: move 'check' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  16. 10/48 builtin/apply: move 'check_index' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  17. 11/48 builtin/apply: move 'apply_in_reverse' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  18. 12/48 builtin/apply: move 'apply_with_reject' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  19. 13/48 builtin/apply: move 'apply_verbosely' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  20. 14/48 builtin/apply: move 'update_index' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  21. 15/48 builtin/apply: move 'allow_overlap' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  22. 16/48 builtin/apply: move 'cached' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  23. 17/48 builtin/apply: move 'diffstat' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  24. 18/48 builtin/apply: move 'numstat' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  25. 19/48 builtin/apply: move 'summary' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  26. 20/48 builtin/apply: move 'threeway' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  27. 21/48 builtin/apply: move 'no-add' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  28. 22/48 builtin/apply: move 'unsafe_paths' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  29. 23/48 builtin/apply: move 'line_termination' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  30. 24/48 builtin/apply: move 'fake_ancestor' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  31. 25/48 builtin/apply: move 'p_context' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  32. 26/48 builtin/apply: move 'apply' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  33. 27/48 builtin/apply: move 'read_stdin' global into cmd_apply()Christian Couder, Mar 9, 2016
  34. 28/48 builtin/apply: move 'lock_file' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  35. 29/48 builtin/apply: move 'patch_input_file' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  36. 30/48 builtin/apply: move 'limit_by_name' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  37. 31/48 builtin/apply: move 'has_include' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  38. 32/48 builtin/apply: move 'p_value' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  39. 33/48 builtin/apply: move 'p_value_known' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  40. 34/48 builtin/apply: move 'root' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  41. 35/48 builtin/apply: move 'whitespace_error' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  42. 36/48 builtin/apply: move 'whitespace_option' into 'struct apply_state'Christian Couder, Mar 9, 2016
  43. 37/48 builtin/apply: remove whitespace_option arg from set_default_whitespace_mode()Christian Couder, Mar 9, 2016
  44. 38/48 builtin/apply: move 'squelch_whitespace_errors' into 'struct apply_state'Christian Couder, Mar 9, 2016
  45. 39/48 builtin/apply: move 'applied_after_fixing_ws' into 'struct apply_state'Christian Couder, Mar 9, 2016
  46. 40/48 builtin/apply: move 'ws_error_action' into 'struct apply_state'Christian Couder, Mar 9, 2016
  47. 41/48 builtin/apply: move 'ws_ignore_action' into 'struct apply_state'Christian Couder, Mar 9, 2016
  48. 42/48 builtin/apply: move 'max_change' and 'max_len' into 'struct apply_state'Christian Couder, Mar 9, 2016
  49. 43/48 builtin/apply: move 'linenr' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  50. 44/48 builtin/apply: move 'fn_table' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  51. 45/48 builtin/apply: move 'symlink_changes' global into 'struct apply_state'Christian Couder, Mar 9, 2016
  52. 46/48 builtin/apply: move 'state' init into init_apply_state()Christian Couder, Mar 9, 2016
  53. 47/48 builtin/apply: move 'state' check into check_apply_state()Christian Couder, Mar 9, 2016
  54. 48/48 builtin/apply: move applying patches into apply_all_patches()Christian Couder, Mar 9, 2016
  55. Junio C HamanoMar 9, 2016
  56. Christian CouderMar 11, 2016
  57. Duy NguyenMar 10, 2016
  58. Christian CouderMar 11, 2016

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.