global: introduce `USE_THE_REPOSITORY_VARIABLE` macro
Use of the `the_repository` variable is deprecated nowadays, and we
slowly but steadily convert the codebase to not use it anymore. Instead,
callers should be passing down the repository to work on via parameters.
It is hard though to prove that a given code unit does not use this
variable anymore. The most trivial case, merely demonstrating that there
is no direct use of `the_repository`, is already a bit of a pain during
code reviews as the reviewer needs to manually verify claims made by the
patch author. The bigger problem though is that we have many interfaces
that implicitly rely on `the_repository`.
Introduce a new `USE_THE_REPOSITORY_VARIABLE` macro that allows code
units to opt into usage of `the_repository`. The intent of this macro is
to demonstrate that a certain code unit does not use this variable
anymore, and to keep it from new dependencies on it in future changes,
be it explicit or implicit
For now, the macro only guards `the_repository` itself as well as
`the_hash_algo`. There are many more known interfaces where we have an
implicit dependency on `the_repository`, but those are not guarded at
the current point in time. Over time though, we should start to add
guards as required (or even better, just remove them).
Define the macro as required in our code units. As expected, most of our
code still relies on the global variable. Nearly all of our builtins
rely on the variable as there is no way yet to pass `the_repository` to
their entry point. For now, declare the macro in "biultin.h" to keep the
required changes at least a little bit more contained.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-06-14 06:50:23 +00:00
|
|
|
#define USE_THE_REPOSITORY_VARIABLE
|
|
|
|
|
2023-02-24 00:09:32 +00:00
|
|
|
#include "git-compat-util.h"
|
merge-ll: rename from ll-merge
A long term (but rather minor) pet-peeve of mine was the name
ll-merge.[ch]. I thought it made it harder to realize what stuff was
related to merging when I was working on the merge machinery and trying
to improve it.
Further, back in d1cbe1e6d8a ("hash-ll.h: split out of hash.h to remove
dependency on repository.h", 2023-04-22), we have split the portions of
hash.h that do not depend upon repository.h into a "hash-ll.h" (due to
the recommendation to use "ll" for "low-level" in its name[1], but which
I used as a suffix precisely because of my distaste for "ll-merge").
When we discussed adding additional "*-ll.h" files, a request was made
that we use "ll" consistently as either a prefix or a suffix. Since it
is already in use as both a prefix and a suffix, the only way to do so
is to rename some files.
Besides my distaste for the ll-merge.[ch] name, let me also note that
the files
ll-fsmonitor.h, ll-hash.h, ll-merge.h, ll-object-store.h, ll-read-cache.h
would have essentially nothing to do with each other and make no sense
to group. But giving them the common "ll-" prefix would group them. Using
"-ll" as a suffix thus seems just much more logical to me. Rename
ll-merge.[ch] to merge-ll.[ch] to achieve this consistency, and to
ensure we get a more logical grouping of files.
[1] https://lore.kernel.org/git/kl6lsfcu1g8w.fsf@chooglen-macbookpro.roam.corp.google.com/
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-05-16 06:34:04 +00:00
|
|
|
#include "merge-ll.h"
|
2006-06-29 05:06:36 +00:00
|
|
|
#include "blob.h"
|
2012-12-06 23:08:01 +00:00
|
|
|
#include "merge-blobs.h"
|
2023-05-16 06:34:06 +00:00
|
|
|
#include "object-store-ll.h"
|
2006-06-29 05:06:36 +00:00
|
|
|
|
|
|
|
static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
|
|
|
|
{
|
|
|
|
void *buf;
|
|
|
|
unsigned long size;
|
2007-02-26 19:55:59 +00:00
|
|
|
enum object_type type;
|
2006-06-29 05:06:36 +00:00
|
|
|
|
2023-03-28 13:58:50 +00:00
|
|
|
buf = repo_read_object_file(the_repository, &obj->object.oid, &type,
|
|
|
|
&size);
|
2006-06-29 05:06:36 +00:00
|
|
|
if (!buf)
|
|
|
|
return -1;
|
2015-03-21 00:28:03 +00:00
|
|
|
if (type != OBJ_BLOB) {
|
|
|
|
free(buf);
|
2006-06-29 05:06:36 +00:00
|
|
|
return -1;
|
2015-03-21 00:28:03 +00:00
|
|
|
}
|
2006-06-29 05:06:36 +00:00
|
|
|
f->ptr = buf;
|
|
|
|
f->size = size;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_mmfile(mmfile_t *f)
|
|
|
|
{
|
|
|
|
free(f->ptr);
|
|
|
|
}
|
|
|
|
|
2018-09-21 15:57:28 +00:00
|
|
|
static void *three_way_filemerge(struct index_state *istate,
|
|
|
|
const char *path,
|
|
|
|
mmfile_t *base,
|
|
|
|
mmfile_t *our,
|
|
|
|
mmfile_t *their,
|
|
|
|
unsigned long *size)
|
2006-06-29 05:06:36 +00:00
|
|
|
{
|
2022-02-02 02:37:30 +00:00
|
|
|
enum ll_merge_result merge_status;
|
2010-01-17 05:45:40 +00:00
|
|
|
mmbuffer_t res;
|
2006-06-29 05:06:36 +00:00
|
|
|
|
2010-03-21 00:40:53 +00:00
|
|
|
/*
|
|
|
|
* This function is only used by cmd_merge_tree, which
|
|
|
|
* does not respect the merge.conflictstyle option.
|
|
|
|
* There is no need to worry about a label for the
|
|
|
|
* common ancestor.
|
|
|
|
*/
|
2010-03-21 00:38:58 +00:00
|
|
|
merge_status = ll_merge(&res, path, base, NULL,
|
2018-09-21 15:57:27 +00:00
|
|
|
our, ".our", their, ".their",
|
2018-09-21 15:57:28 +00:00
|
|
|
istate, NULL);
|
2006-12-12 23:01:41 +00:00
|
|
|
if (merge_status < 0)
|
|
|
|
return NULL;
|
2022-02-02 02:37:30 +00:00
|
|
|
if (merge_status == LL_MERGE_BINARY_CONFLICT)
|
|
|
|
warning("Cannot merge binary files: %s (%s vs. %s)",
|
|
|
|
path, ".our", ".their");
|
2006-12-12 23:01:41 +00:00
|
|
|
|
|
|
|
*size = res.size;
|
|
|
|
return res.ptr;
|
2006-06-29 05:06:36 +00:00
|
|
|
}
|
|
|
|
|
2018-09-21 15:57:28 +00:00
|
|
|
void *merge_blobs(struct index_state *istate, const char *path,
|
|
|
|
struct blob *base, struct blob *our,
|
|
|
|
struct blob *their, unsigned long *size)
|
2006-06-29 05:06:36 +00:00
|
|
|
{
|
|
|
|
void *res = NULL;
|
|
|
|
mmfile_t f1, f2, common;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Removed in either branch?
|
|
|
|
*
|
|
|
|
* NOTE! This depends on the caller having done the
|
|
|
|
* proper warning about removing a file that got
|
|
|
|
* modified in the other branch!
|
|
|
|
*/
|
|
|
|
if (!our || !their) {
|
2007-02-26 19:55:59 +00:00
|
|
|
enum object_type type;
|
2006-06-29 05:06:36 +00:00
|
|
|
if (base)
|
|
|
|
return NULL;
|
|
|
|
if (!our)
|
|
|
|
our = their;
|
2023-03-28 13:58:50 +00:00
|
|
|
return repo_read_object_file(the_repository, &our->object.oid,
|
|
|
|
&type, size);
|
2006-06-29 05:06:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fill_mmfile_blob(&f1, our) < 0)
|
|
|
|
goto out_no_mmfile;
|
|
|
|
if (fill_mmfile_blob(&f2, their) < 0)
|
|
|
|
goto out_free_f1;
|
|
|
|
|
|
|
|
if (base) {
|
|
|
|
if (fill_mmfile_blob(&common, base) < 0)
|
|
|
|
goto out_free_f2_f1;
|
|
|
|
} else {
|
merge-tree: drop generate_common strategy
When merge_blobs sees an add/add conflict, it tries to
create a virtual base object for the 3-way merge that
consists of the common lines of each file. It inherited this
strategy from merge-one-file in 0c79938 (Improved three-way
blob merging code, 2006-06-28), and the point is to minimize
the size of the conflict hunks. That commit talks about "if
libxdiff were to ever grow a compatible three-way merge, it
could probably be directly plugged in".
That has long since happened. So as with merge-one-file in
the previous commit, this extra step is no longer necessary.
Our 3-way merge code is smart enough to do the minimizing
itself if we simply feed it an empty base, which is what the
more modern merge-recursive strategy already does.
Not only does this let us drop some code, but it removes an
overflow bug in generate_common_file(). We allocate a buffer
as large as the smallest of the two blobs, under the
assumption that there cannot be more common content than
what is in the smaller blob. However, xdiff may feed us
more: if neither file ends in a newline, it feeds us the
"\nNo newline at end of file" marker as common content, and
we write it into the output. If the differences between the
files are small than that string, we overflow the output
buffer. This patch solves it by simply dropping the buggy
code entirely.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-23 06:06:55 +00:00
|
|
|
common.ptr = xstrdup("");
|
|
|
|
common.size = 0;
|
2006-06-29 05:06:36 +00:00
|
|
|
}
|
2018-09-21 15:57:28 +00:00
|
|
|
res = three_way_filemerge(istate, path, &common, &f1, &f2, size);
|
2006-06-29 05:06:36 +00:00
|
|
|
free_mmfile(&common);
|
|
|
|
out_free_f2_f1:
|
|
|
|
free_mmfile(&f2);
|
|
|
|
out_free_f1:
|
|
|
|
free_mmfile(&f1);
|
|
|
|
out_no_mmfile:
|
|
|
|
return res;
|
|
|
|
}
|