Re: [PATCH 2/9] ll-merge: make callers responsible for showing warnings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Dec 21, 2021 at 3:44 PM Junio C Hamano <gitster@xxxxxxxxx> wrote:
>
> "Elijah Newren via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes:
>
> > From: Elijah Newren <newren@xxxxxxxxx>
> >
> > Since some callers may want to send warning messages to somewhere other
> > than stdout/stderr, stop printing "warning: Cannot merge binary files"
> > from ll-merge and instead modify the return status of ll_merge() to
> > indicate when a merge of binary files has occurred.
> >
> > Note that my methodology included first modifying ll_merge() to return
> > a struct, so that the compiler would catch all the callers for me and
> > ensure I had modified all of them.  After modifying all of them, I then
> > changed the struct to an enum.
> >
> > Signed-off-by: Elijah Newren <newren@xxxxxxxxx>
> > ---
> >  apply.c            |  5 ++++-
> >  builtin/checkout.c | 12 ++++++++----
> >  ll-merge.c         | 40 ++++++++++++++++++++++------------------
> >  ll-merge.h         |  9 ++++++++-
> >  merge-blobs.c      |  5 ++++-
> >  merge-ort.c        |  5 ++++-
> >  merge-recursive.c  |  5 ++++-
> >  notes-merge.c      |  5 ++++-
> >  rerere.c           | 10 +++++++---
> >  9 files changed, 65 insertions(+), 31 deletions(-)
> >
> > diff --git a/apply.c b/apply.c
> > index 43a0aebf4ee..12ea9c72a6b 100644
> > --- a/apply.c
> > +++ b/apply.c
> > @@ -3492,7 +3492,7 @@ static int three_way_merge(struct apply_state *state,
> >  {
> >       mmfile_t base_file, our_file, their_file;
> >       mmbuffer_t result = { NULL };
> > -     int status;
> > +     enum ll_merge_result status;
> >
> >       /* resolve trivial cases first */
> >       if (oideq(base, ours))
> > @@ -3509,6 +3509,9 @@ static int three_way_merge(struct apply_state *state,
> >                         &their_file, "theirs",
> >                         state->repo->index,
> >                         NULL);
> > +     if (status == LL_MERGE_BINARY_CONFLICT)
> > +             warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                     "base", "ours", "theirs");
>
> This used to come from ll_merge()
>
> > -                     warning("Cannot merge binary files: %s (%s vs. %s)",
> > -                             path, name1, name2);
> > -                     /* fallthru */
>
> And our call to ll_merge() above (half of it invisible in the
> pre-context of the hunk) gave "ours" and "theirs" to our_label and
> their_label, which in turn are called name1 and name2, respectively,
> in ll_merge_binary() driver.
>
> I am not sure about the "base" string, though.  I suspect that your
> "base" should be a reference to the parameter 'path' of three_way_merge()
> function.

Ah, indeed; thanks for reading carefully.

> > diff --git a/builtin/checkout.c b/builtin/checkout.c
> > index cbf73b8c9f6..3a559d69303 100644
> > --- a/builtin/checkout.c
> > +++ b/builtin/checkout.c
> > @@ -237,6 +237,7 @@ static int checkout_merged(int pos, const struct checkout *state,
> >       struct cache_entry *ce = active_cache[pos];
> >       const char *path = ce->name;
> >       mmfile_t ancestor, ours, theirs;
> > +     enum ll_merge_result merge_status;
> >       int status;
> >       struct object_id oid;
> >       mmbuffer_t result_buf;
> > @@ -267,13 +268,16 @@ static int checkout_merged(int pos, const struct checkout *state,
> >       memset(&ll_opts, 0, sizeof(ll_opts));
> >       git_config_get_bool("merge.renormalize", &renormalize);
> >       ll_opts.renormalize = renormalize;
> > -     status = ll_merge(&result_buf, path, &ancestor, "base",
> > -                       &ours, "ours", &theirs, "theirs",
> > -                       state->istate, &ll_opts);
> > +     merge_status = ll_merge(&result_buf, path, &ancestor, "base",
> > +                             &ours, "ours", &theirs, "theirs",
> > +                             state->istate, &ll_opts);
> >       free(ancestor.ptr);
> >       free(ours.ptr);
> >       free(theirs.ptr);
> > -     if (status < 0 || !result_buf.ptr) {
> > +     if (merge_status == LL_MERGE_BINARY_CONFLICT)
> > +             warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                     path, "ours", "theirs");
>
> This one looks correct.
>
> > +     if (merge_status < 0 || !result_buf.ptr) {
> >               free(result_buf.ptr);
> >               return error(_("path '%s': cannot merge"), path);
> >       }
>
> > diff --git a/merge-blobs.c b/merge-blobs.c
> > index ee0a0e90c94..8138090f81c 100644
> > --- a/merge-blobs.c
> > +++ b/merge-blobs.c
> > @@ -36,7 +36,7 @@ static void *three_way_filemerge(struct index_state *istate,
> >                                mmfile_t *their,
> >                                unsigned long *size)
> >  {
> > -     int merge_status;
> > +     enum ll_merge_result merge_status;
> >       mmbuffer_t res;
> >
> >       /*
> > @@ -50,6 +50,9 @@ static void *three_way_filemerge(struct index_state *istate,
> >                               istate, NULL);
> >       if (merge_status < 0)
> >               return NULL;
> > +     if (merge_status == LL_MERGE_BINARY_CONFLICT)
> > +             warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                     path, ".our", ".their");
>
> OK.
>
> > diff --git a/merge-ort.c b/merge-ort.c
> > index 0342f104836..c24da2ba3cb 100644
> > --- a/merge-ort.c
> > +++ b/merge-ort.c
> > @@ -1743,7 +1743,7 @@ static int merge_3way(struct merge_options *opt,
> >       mmfile_t orig, src1, src2;
> >       struct ll_merge_options ll_opts = {0};
> >       char *base, *name1, *name2;
> > -     int merge_status;
> > +     enum ll_merge_result merge_status;
> >
> >       if (!opt->priv->attr_index.initialized)
> >               initialize_attr_index(opt);
> > @@ -1787,6 +1787,9 @@ static int merge_3way(struct merge_options *opt,
> >       merge_status = ll_merge(result_buf, path, &orig, base,
> >                               &src1, name1, &src2, name2,
> >                               &opt->priv->attr_index, &ll_opts);
> > +     if (merge_status == LL_MERGE_BINARY_CONFLICT)
> > +             warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                     path, name1, name2);
>
> OK; this is your code and I do not have to read it too carefully,
> but all we need is conveniently in the pre-context of the hunk ;-).
>
> > diff --git a/merge-recursive.c b/merge-recursive.c
> > index d9457797dbb..bc73c52dd84 100644
> > --- a/merge-recursive.c
> > +++ b/merge-recursive.c
> > @@ -1044,7 +1044,7 @@ static int merge_3way(struct merge_options *opt,
> >       mmfile_t orig, src1, src2;
> >       struct ll_merge_options ll_opts = {0};
> >       char *base, *name1, *name2;
> > -     int merge_status;
> > +     enum ll_merge_result merge_status;
> >
> >       ll_opts.renormalize = opt->renormalize;
> >       ll_opts.extra_marker_size = extra_marker_size;
> > @@ -1090,6 +1090,9 @@ static int merge_3way(struct merge_options *opt,
> >       merge_status = ll_merge(result_buf, a->path, &orig, base,
> >                               &src1, name1, &src2, name2,
> >                               opt->repo->index, &ll_opts);
> > +     if (merge_status == LL_MERGE_BINARY_CONFLICT)
> > +             warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                     a->path, name1, name2);
>
> OK.
>
> > diff --git a/notes-merge.c b/notes-merge.c
> > index b4a3a903e86..01d596920ea 100644
> > --- a/notes-merge.c
> > +++ b/notes-merge.c
> > @@ -344,7 +344,7 @@ static int ll_merge_in_worktree(struct notes_merge_options *o,
> >  {
> >       mmbuffer_t result_buf;
> >       mmfile_t base, local, remote;
> > -     int status;
> > +     enum ll_merge_result status;
> >
> >       read_mmblob(&base, &p->base);
> >       read_mmblob(&local, &p->local);
> > @@ -358,6 +358,9 @@ static int ll_merge_in_worktree(struct notes_merge_options *o,
> >       free(local.ptr);
> >       free(remote.ptr);
> >
> > +     if (status == LL_MERGE_BINARY_CONFLICT)
> > +             warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                     oid_to_hex(&p->obj), o->local_ref, o->remote_ref);
>
> This uses another slot in the rotating buffer used by oid_to_hex(),
> but I do not think anybody grabbed a pointer to one of them and held
> onto it before we got here, so it would be OK.
>
> > diff --git a/rerere.c b/rerere.c
> > index d83d58df4fb..46fd01819b8 100644
> > --- a/rerere.c
> > +++ b/rerere.c
> > @@ -609,19 +609,23 @@ static int try_merge(struct index_state *istate,
> >                    const struct rerere_id *id, const char *path,
> >                    mmfile_t *cur, mmbuffer_t *result)
> >  {
> > -     int ret;
> > +     enum ll_merge_result ret;
> >       mmfile_t base = {NULL, 0}, other = {NULL, 0};
> >
> >       if (read_mmfile(&base, rerere_path(id, "preimage")) ||
> >           read_mmfile(&other, rerere_path(id, "postimage")))
> > -             ret = 1;
> > -     else
> > +             ret = LL_MERGE_CONFLICT;
> > +     else {
>
> Let's have {} around the if clause now the corresponding else clause
> needs it.

Will fix.

> >               /*
> >                * A three-way merge. Note that this honors user-customizable
> >                * low-level merge driver settings.
> >                */
> >               ret = ll_merge(result, path, &base, NULL, cur, "", &other, "",
> >                              istate, NULL);
> > +             if (ret == LL_MERGE_BINARY_CONFLICT)
> > +                     warning("Cannot merge binary files: %s (%s vs. %s)",
> > +                             path, "", "");
> > +     }
>
> This is a faithful conversion of what should not happen in practice,
> as the rerere logic would not be able to reach here.  In a binary
> file, we won't be able to identify <<< === >>> blocks, hash the text
> in the conflicted block to come up with the conflict ID to find the
> preimage and postimage files.  These files are the input to the low
> level merge driver call we are making here.
>
> Looking almost good except for a warning message bug I spotted
> earlier.
>
> Thanks.



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux