Werge: small mergetool helper

Following the advice that this should be shown to more haskellers ( @Kleidukos looking at you – I assume it was you on fedi ), sharing my relatively new mergehelper here for comments:

In short, you can make diffs and patches that look like from wdiff or git diff --word-diff (the “change blocks” are limited to very small tokens), but also apply them (as with patch) and use this to have diverging changes automerged (as with diff3 or git merge), with the benefit that smaller changes are much less likely to conflict.

For illustration, diff of some changes in linux:

One cool extra feature is that this discerns blank characters from actual “contents”, so you can separate out various blanks-only conflicts and automerge (or resolve) them separately. In turn, you can perfectly merge changes in TeX or markdown paragraphs that are e.g. justified at 80cpl, without the mergetool exploding on mismatched line endings etc. (Spoiler: I made this tool for solving a single-shot megamerge of latex and markdown that I had to do here. Bonus: some files got converted to the other format (and sometimes back) between the branches. :sweat_smile:)

There are other approaches to this issue (someone on IRC pointed me to mergiraf) but most of these seem language-specific and kindof “structured” (if I got it right, mergiraf uses tree-sitter parses). Somehow I’m happier with this one being completely unconcerned about the actual structure of the language below.

Next steps: No idea. Any comments on the algorithms are very welcome, I’m not really good at diffy&patchy theory. If you find this useful or discover a cool usecase where such merges could help, let me know. :smiley:
Thanks for any suggestions!


PS. looking at the screenshot with code – is there a way to copypaste ANSI-colored terminal stuff into the posts here? (ansi2html but for markdown, somehow?)

13 Likes

Nice to see you finally posted it! :slight_smile:

1 Like

Haskell community is relatively small and building cabal project for an average dude might be too much. So to find more potential users I would release a static build and send the link to git monthly news.

2 Likes

I would release a static build

Hi, actually I was wondering how to do this “properly” – is there some recommendable pipeline or so? I’m now doing a plain old cabal build in github actions and just packing up the executable. But that’s simply because I didn’t find anything better now (and it seems to be roughly what pandoc does :smiley: )

Static build is not that awful as it seems. After a few days of googling and trying I was able to setup static build in the project mentioned above.
Commit with SHA 2853a5d contains changes related to static build setup.

For Linux it’s actually fairly easy, you can use an Alpine runner like in get-tested/.github/workflows/release.yml at main · Kleidukos/get-tested · GitHub.

macOS does not support nor endorse static builds.

@dyaitskov in the end I didn’t do a fully static build (or at least I hope since I didn’t specify anything :D) but it seems to kinda work for more OSes etc, can you please check if these work for you?

(no windows yet, I don’t want to touch that until absolutely necessary :smiley: )

Thanks for the opportunity, but I live in Alaska and have limited traffic, surf web without pictures - downloading a few extra docker images does not sound cool.

This seems to work on all linuxes I tried, no container needed. The libraries are the generic system ones that should be pretty much everywhere:

$ ldd ./werge-v0.2.0.0_ubuntu-22.04_ghc-9.12
linux-vdso.so.1 (0x00007fec24fac000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fec24e96000)
libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fec24e0c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fec24c16000)
/lib64/ld-linux-x86-64.so.2 (0x00007fec24fae000)

What’s your setup?

For the fully static build I’m getting lots of warnings like

(.text+0x21): warning: Using 'getgrnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

and unfortunately cabal (with –-enable-executable-static ) seems to die with

(.text+0x26): undefined reference to `__xmknod'

any hints?

You should use an Alpine Linux CI runner to produce your statically-linked binaries. You can also follow these instructions: Getting your Haskell executable statically linked without Nix · Hasufell's blog

ghc should be built with specific flags to support static link. So get docker image or use nix from the commit.

practice showed that –-enable-executable-static is not needed in ghc 9.12 for static build.

ah ok great, so this needs a completely different ghc. I was confused on that one, the findable documentation isn’t very guiding.

I’ll try to integrate what @Kleidukos linked ASAP. Thanks!

1 Like

See System library dependencies not documented · Issue #265 · haskell/unix · GitHub . You need to use a GHC bindist for Ubuntu 22.04 or newer, which are currently either GHC 9.6.7 or 9.12.2.

1 Like