[PATCH v5 00/10] Xdiff cleanup part2
- From
Ezekiel Newren via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Nov 18, 2025, 22:34 UTC
- Message-ID
- <pull.2070.v5.git.git.1763505262.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.2070.v4.git.git.1763159816.gitgitgadget@gmail.com>
Changes in v5:
* Remove the non-word 'signless', and rephrase that paragraph in unambiguous-types.adoc * Cast to char in xdiffi.c:get_indent() rather than changing the local variable to uint8_t
Changes in v4:
* Update documentation to not mention Unicode except once * Don't move dstart/dend with in the xdfile_t struct * Rephrase justification on changing xrecord_t.ptr's type
Changes in v3:
* Address comments about commit messages and documentation * Add unambiguous-types.adoc to Makefile and Meson * Use markdown style to avoid asciidoc issues
Changes in v2:
* Added documentation about unambiguous types and FFI * Addressed comments on the mailing list
Original cover letter below: ============================
Maintainer note: This patch series builds on top of en/xdiff-cleanup and am/xdiff-hash-tweak (both of which are now in master).
The primary goal of this patch series is to convert every field's type in xrecord_t and xdfile_t to be unambiguous, in preparation to make it more Rust FFI friendly. Additionally the ha field in xrecord_t is split into line_hash and minimal_perfect hash.
The order of some of the fields has changed as called out by the commit messages.
Before:
typedef struct s_xrecord {
char const *ptr;
long size;
unsigned long ha;
} xrecord_t;typedef struct s_xdfile {
xrecord_t *recs;
long nrec;
long dstart, dend;
bool *changed;
long *rindex;
long nreff;
} xdfile_t;After part 2
typedef struct s_xrecord {
uint8_t const *ptr;
size_t size;
uint64_t line_hash;
size_t minimal_perfect_hash;
} xrecord_t;typedef struct s_xdfile {
xrecord_t *recs;
size_t nrec;
ptrdiff_t dstart, dend;
bool *changed;
size_t *reference_index;
size_t nreff;
} xdfile_t;Ezekiel Newren (10): doc: define unambiguous type mappings across C and Rust xdiff: use ptrdiff_t for dstart/dend xdiff: make xrecord_t.ptr a uint8_t instead of char xdiff: use size_t for xrecord_t.size xdiff: use unambiguous types in xdl_hash_record() xdiff: split xrecord_t.ha into line_hash and minimal_perfect_hash xdiff: make xdfile_t.nrec a size_t instead of long xdiff: make xdfile_t.nreff a size_t instead of long xdiff: change rindex from long to size_t in xdfile_t xdiff: rename rindex -> reference_index
Documentation/Makefile | 1 + Documentation/technical/meson.build | 1 + .../technical/unambiguous-types.adoc | 224 ++++++++++++++++++ xdiff-interface.c | 2 +- xdiff/xdiffi.c | 29 ++- xdiff/xemit.c | 28 +-- xdiff/xhistogram.c | 4 +- xdiff/xmerge.c | 30 +-- xdiff/xpatience.c | 14 +- xdiff/xprepare.c | 60 ++--- xdiff/xtypes.h | 15 +- xdiff/xutils.c | 32 +-- xdiff/xutils.h | 6 +- 13 files changed, 336 insertions(+), 110 deletions(-) create mode 100644 Documentation/technical/unambiguous-types.adoc
base-commit: a99f379adf116d53eb11957af5bab5214915f91d Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2070%2Fezekielnewren%2Fxdiff_cleanup_part2-v5 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2070/ezekielnewren/xdiff_cleanup_part2-v5 Pull-Request: https://github.com/git/git/pull/2070
Range-diff vs v4:
1: af732beb69 ! 1: 8b56bf1172 doc: define unambiguous type mappings across C and Rust
@@ Documentation/technical/unambiguous-types.adoc (new)
+has additional semantics and platform-dependent behavior that can cause
+problems, as discussed below.
+
-+C comparison problem: While the sign of `char` is implementation defined, it's
-+also signless (neither signed nor unsigned). When building with
-+`make DEVELOPER=1` it will complain about a "differ in signedness" when `char`
-+is compared with `uint8_t` or `int8_t`.
++The C language leaves the signedness of `char` implementation defined. Because
++our developer build enables -Wsign-compare, comparison of a value of `char`
++type with either signed or unsigned integers may trigger warnings from the
++compiler.
+
+Note: Rust's `char` type is an unsigned 32-bit integer that is used to describe
+Unicode code points.
2: b60a03eb31 = 2: c4193d11f5 xdiff: use ptrdiff_t for dstart/dend
3: 042fbb11d0 ! 3: dd76d4f586 xdiff: make xrecord_t.ptr a uint8_t instead of char
@@ Commit message
Make xrecord_t.ptr uint8_t because it's referring to bytes in memory.
In order to avoid a refactor avalanche, many uses of this field were
- cast to char* or similar. One exception is in get_indent() where the
- local variable `char c` was changed to `uint8_t c`.
+ cast to char* or similar.
Places where casting was unnecessary:
xemit.c:156
@@ xdiff/xdiffi.c: static int get_indent(xrecord_t *rec)
for (i = 0; i < rec->size; i++) {
- char c = rec->ptr[i];
-+ uint8_t c = rec->ptr[i];
++ char c = (char) rec->ptr[i];
if (!XDL_ISSPACE(c))
return ret;
4: c103fa6bea ! 4: 11cec1d2ec xdiff: use size_t for xrecord_t.size
@@ xdiff/xdiffi.c: static int recs_match(xrecord_t *rec1, xrecord_t *rec2)
- for (i = 0; i < rec->size; i++) {
+ for (size_t i = 0; i < rec->size; i++) {
- uint8_t c = rec->ptr[i];
+ char c = (char) rec->ptr[i];
if (!XDL_ISSPACE(c))
@@ xdiff/xdiffi.c: static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags)
5: 2ee9a74653 = 5: 6f267360b7 xdiff: use unambiguous types in xdl_hash_record()
6: f044274bd5 = 6: 78af0f16f4 xdiff: split xrecord_t.ha into line_hash and minimal_perfect_hash
7: f7a3731d94 = 7: 5c19f9ded3 xdiff: make xdfile_t.nrec a size_t instead of long
8: 93f84ae72e = 8: d1f498edb1 xdiff: make xdfile_t.nreff a size_t instead of long
9: 39369becc8 = 9: bc4941c146 xdiff: change rindex from long to size_t in xdfile_t
10: 950d1e6193 = 10: dcc9d6bfaf xdiff: rename rindex -> reference_index-- gitgitgadget