Compare commits
No commits in common. "f294df0e69fce805ba38641f3b730461fee91e3b" and "aea372a87dd8c10d2e8604b4d0ea81391c11f548" have entirely different histories.
f294df0e69
...
aea372a87d
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
|
@ -14,6 +14,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, macos-15]
|
os: [ubuntu-22.04, macos-15]
|
||||||
ghc:
|
ghc:
|
||||||
|
- "9.6"
|
||||||
- "9.12"
|
- "9.12"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
||||||
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Revision history for werge
|
||||||
|
|
||||||
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
|
* First version. Released on an unsuspecting world.
|
||||||
2
Main.hs
2
Main.hs
|
|
@ -385,4 +385,4 @@ main = catch go bad
|
||||||
go = parseOpts >>= uncurry (flip runCmd)
|
go = parseOpts >>= uncurry (flip runCmd)
|
||||||
bad e = do
|
bad e = do
|
||||||
hPutStrLn stderr $ "fatal: " ++ displayException (e :: IOException)
|
hPutStrLn stderr $ "fatal: " ++ displayException (e :: IOException)
|
||||||
exitWith (ExitFailure 129)
|
exitWith (ExitFailure 2)
|
||||||
|
|
|
||||||
149
README.md
149
README.md
|
|
@ -21,52 +21,21 @@ Separate `diff`&`patch` functionality is provided too for sending
|
||||||
token-granularity patches. (The patches are similar to what `git diff
|
token-granularity patches. (The patches are similar to what `git diff
|
||||||
--word-diff` produces, but can be applied to files.)
|
--word-diff` produces, but can be applied to files.)
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
- To build from source, clone the repo and run `cabal install` in the directory
|
|
||||||
(you need [a way to compile Haskell](https://www.haskell.org/downloads/)).
|
|
||||||
- [Releases](https://github.com/exaexa/werge/releases) come with prebuilt
|
|
||||||
binaries that you may download and run as-is on many Linuxes and Macs.
|
|
||||||
|
|
||||||
Running of `werge` requires working installations of `diff` and `patch`
|
|
||||||
compatible with the ones from [GNU
|
|
||||||
diffutils](https://www.gnu.org/software/diffutils/):
|
|
||||||
- Most Linux distributions contain the correct diffutils
|
|
||||||
- On BSDs you should be able to install these from Ports
|
|
||||||
([FreeBSD](https://cgit.freebsd.org/ports/tree/textproc/diffutils),
|
|
||||||
[OpenBSD](https://openports.eu/ports/textproc/gdiff))
|
|
||||||
- On Macs, install [diffutils from
|
|
||||||
brew](https://formulae.brew.sh/formula/diffutils).
|
|
||||||
|
|
||||||
In any other case, you may set up a path to any compatible `diff` and `patch`
|
|
||||||
(or suitable wrapper scripts) via environment variables `WERGE_DIFF` and
|
|
||||||
`WERGE_PATCH`. (If required, the same applies for `WERGE_GIT`.)
|
|
||||||
|
|
||||||
### Editor integration
|
|
||||||
|
|
||||||
There's a `vim` syntax highlighting file in `vim/werge.vim`. To install, simply
|
|
||||||
copy it to your local `vim` syntax configuration directory (usually to
|
|
||||||
`~/.vim/syntax/werge.vim`). Then, you can activate the syntax in vim with:
|
|
||||||
|
|
||||||
```
|
|
||||||
:set syn=werge
|
|
||||||
```
|
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
##### Original (`old` file):
|
Original (`old` file):
|
||||||
```
|
```
|
||||||
Roses are red. Violets are blue.
|
Roses are red. Violets are blue.
|
||||||
Patch is quite hard. I cannot rhyme.
|
Patch is quite hard. I cannot rhyme.
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Local changes (`my` file):
|
Local changes (`my` file):
|
||||||
```
|
```
|
||||||
Roses are red. Violets are blue.
|
Roses are red. Violets are blue.
|
||||||
Patching is hard. I still cannot rhyme.
|
Patching is hard. I still cannot rhyme.
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Remote changes (`your` file):
|
Remote changes (`your` file):
|
||||||
```
|
```
|
||||||
Roses are red.
|
Roses are red.
|
||||||
Violets are blue.
|
Violets are blue.
|
||||||
|
|
@ -74,23 +43,18 @@ Patch is quite hard.
|
||||||
I cannot do verses.
|
I cannot do verses.
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Token-merged version
|
Token-merged version with `werge merge my orig your` (conflicts on the space
|
||||||
|
change that is too close to the disappearing "still" token):
|
||||||
This is produced with `werge merge my old your` (conflicts on the space change
|
|
||||||
that is too close to the disappearing "still" token):
|
|
||||||
```
|
```
|
||||||
Roses are red.
|
Roses are red.
|
||||||
Violets are blue.
|
Violets are blue.
|
||||||
Patching is hard.<<<<< I still||||| I=====
|
Patching is hard.<<<<< I still||||| I=====
|
||||||
I>>>>> cannot do verses.
|
I>>>>> cannot do verses.
|
||||||
```
|
```
|
||||||
(NOTE: option `-G` gives nicely colored output that is much easier to read.
|
(NOTE: option `-G` gives nicely colored output that is much easier to read.)
|
||||||
Alternatively you can install the syntax highlighting for `vim`.)
|
|
||||||
|
|
||||||
##### Merge with separate space resultion
|
Token-merged version with separate space resolution using `-s` (conflicts get
|
||||||
Adding option `-s` to `werge merge` causes it to resolve space conflicts
|
fixed separately):
|
||||||
separately, usually helping many cases that would be easily resolvable by a
|
|
||||||
human:
|
|
||||||
```
|
```
|
||||||
Roses are red.
|
Roses are red.
|
||||||
Violets are blue.
|
Violets are blue.
|
||||||
|
|
@ -98,8 +62,7 @@ Patching is hard.
|
||||||
I still cannot do verses.
|
I still cannot do verses.
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Mixing in unresolvable conflict
|
A harder-conflicting file (`theirs`):
|
||||||
A harder-conflicting file (`their`):
|
|
||||||
```
|
```
|
||||||
Roses are red.
|
Roses are red.
|
||||||
Violets are blue.
|
Violets are blue.
|
||||||
|
|
@ -107,7 +70,7 @@ Merging is quite hard.
|
||||||
I cannot do verses.
|
I cannot do verses.
|
||||||
```
|
```
|
||||||
|
|
||||||
`werge merge my old their -s` highlights the actual unmergeable change:
|
`werge merge mine orig theirs -s` highlights the actual unmergeable change:
|
||||||
```
|
```
|
||||||
Roses are red.
|
Roses are red.
|
||||||
Violets are blue.
|
Violets are blue.
|
||||||
|
|
@ -171,9 +134,18 @@ because the approach was too complex. Before that, the issue was tackled by
|
||||||
Arek Antoniewicz on MFF CUNI, who used regex-edged DFAs (REDFAs) to construct
|
Arek Antoniewicz on MFF CUNI, who used regex-edged DFAs (REDFAs) to construct
|
||||||
user-specifiable tokenizers in a pretty cool way.
|
user-specifiable tokenizers in a pretty cool way.
|
||||||
|
|
||||||
## Integration with `git`
|
## Installation
|
||||||
|
|
||||||
### Automerging conflicts
|
```sh
|
||||||
|
cabal install
|
||||||
|
```
|
||||||
|
|
||||||
|
Running of `werge` requires a working installation of `diff` compatible
|
||||||
|
with the one from [GNU diffutils](https://www.gnu.org/software/diffutils/). You
|
||||||
|
may set up a path to such `diff` (or a wrapper script) via environment variable
|
||||||
|
`WERGE_DIFF`.
|
||||||
|
|
||||||
|
## Use with `git`
|
||||||
|
|
||||||
`werge` can automatically process files that are marked in `git` as merge
|
`werge` can automatically process files that are marked in `git` as merge
|
||||||
conflicts:
|
conflicts:
|
||||||
|
|
@ -189,85 +161,6 @@ settings it runs `git add` on them. The current changes in the files are
|
||||||
replaced by the merged (or partially merged) state; backups are written
|
replaced by the merged (or partially merged) state; backups are written
|
||||||
automatically to `filename.werge-backup`.
|
automatically to `filename.werge-backup`.
|
||||||
|
|
||||||
Optionally, you can specify exact files to be automerged. That is useful for
|
|
||||||
cases when only some of the conflicting files should be processed by `werge`:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ werge git my/conflicting/file.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
Support for merging complex types of changes (deletes, directory moves,
|
|
||||||
symlinks, ...) via this interface is currently limited. `werge` can be used as
|
|
||||||
a mergetool or a merge driver to ameliorate that.
|
|
||||||
|
|
||||||
### Use as `git difftool` and `git mergetool`
|
|
||||||
|
|
||||||
The `git` config below allows direct use of `werge` as `git difftool -t werge`
|
|
||||||
and `git mergetool -t werge`:
|
|
||||||
```ini
|
|
||||||
[difftool "werge"]
|
|
||||||
cmd = werge diff -G $LOCAL $REMOTE
|
|
||||||
[mergetool "werge"]
|
|
||||||
cmd = werge merge $LOCAL $BASE $REMOTE > $MERGED
|
|
||||||
trustExitCode = true
|
|
||||||
|
|
||||||
# variant for separate resolution of space (solves more conflicts):
|
|
||||||
[mergetool "spacewerge"]
|
|
||||||
cmd = werge merge -s $LOCAL $BASE $REMOTE > $MERGED
|
|
||||||
trustExitCode = true
|
|
||||||
```
|
|
||||||
|
|
||||||
One issue with `git` mergetools is that they are supposed to be interactive,
|
|
||||||
and thus `git` expects them to always produce a completely merged, conflictless
|
|
||||||
result. In turn, if the auto-merging with `git mergetool -t werge` fails with
|
|
||||||
conflicts, `git` assumes a complete failure and restores the original version
|
|
||||||
from the backup. To enable a more useful behavior, use `werge` as a merge
|
|
||||||
driver (see below).
|
|
||||||
|
|
||||||
### Use as a `git` merge driver
|
|
||||||
|
|
||||||
Add this to your git config:
|
|
||||||
```ini
|
|
||||||
[merge "werge"]
|
|
||||||
name = werge
|
|
||||||
driver = werge merge %A %O %B > %P
|
|
||||||
recursive = binary
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, specify that the "werge" driver should be used for certain files in your
|
|
||||||
repository's `.gitattributes`:
|
|
||||||
```
|
|
||||||
*.md merge=werge
|
|
||||||
*.tex merge=werge
|
|
||||||
# ... etc
|
|
||||||
```
|
|
||||||
|
|
||||||
With this in place, `git merge` will automatically run `werge` to merge the
|
|
||||||
marked files in the repository. On conflict, you will have the files marked
|
|
||||||
with the usual (werge's usual) conflict markers, and you will be able to
|
|
||||||
resolve them just as with the normal merging workflow.
|
|
||||||
|
|
||||||
**Hint:** As with `spacewerge` mergetool above, it is beneficial to add a few
|
|
||||||
conflict-resolving options such as `-s` to the `driver`, in order to help the
|
|
||||||
automerges pass nicely.
|
|
||||||
|
|
||||||
### Use with `git rebase`
|
|
||||||
|
|
||||||
The merge driver and mergetools as configured above will also automatically
|
|
||||||
work with `git rebase` that runs in the "merge mode" (which is the default).
|
|
||||||
|
|
||||||
As a possible source of confusion, the "my" and "your" versions are somewhat swapped (as implied by semantics):
|
|
||||||
|
|
||||||
- With `git checkout mybranch; git merge otherbranch`, the conflicts will look
|
|
||||||
roughly like this:
|
|
||||||
```
|
|
||||||
<<<<< mybranch version ||||| merge base ===== otherbranch version >>>>>
|
|
||||||
```
|
|
||||||
- With `git checkout mybranch; git rebase otherbranch`, the logic is reversed:
|
|
||||||
```
|
|
||||||
<<<<< otherbranch version ||||| common base ===== mybranch version >>>>>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Current `--help` and features
|
## Current `--help` and features
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
" Vim syntax file
|
|
||||||
" Language: werge
|
|
||||||
" Maintainer: Mirek Kratochvil
|
|
||||||
" Last Change: Oct 14, 2025
|
|
||||||
" Version: 1
|
|
||||||
" URL: https://github.com/exaexa/werge
|
|
||||||
|
|
||||||
" quit if a syntax file was already loaded
|
|
||||||
if exists("b:current_syntax")
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
" syntax for the werge files
|
|
||||||
syntax region wergeHunk start=/<<<<</ end=/>>>>>/ contains=wergeRm,wergeDiffAdd,wergeConflictOrigAdd
|
|
||||||
syntax region wergeRm start=/<<<<</hs=e+1 end=/|||||/he=s-1,me=s-1 contained
|
|
||||||
syntax match wergeDiffAdd /|||||\(\_[^>=]\|>\{1,4\}>\@!\|=\{1,4\}=\@!\)*>>>>>/ms=s+5,me=e-5 contained
|
|
||||||
syntax match wergeConflictOrigAdd /|||||\(\_[^=>]\|=\{1,4\}=\@!\|>\{1,4\}>\@!\)*=====\(\_[^=>]\|=\{1,4\}=\@!\|>\{1,4\}>\@!\)*>>>>>/me=e-5 contained contains=wergeConflictOrig,wergeconflictAdd
|
|
||||||
syntax region wergeConflictOrig start=/|||||/hs=e+1 end=/=====/he=s-1,me=s-1 contained
|
|
||||||
syntax region wergeConflictAdd start=/=====/hs=e+1 end=/>>>>>/he=s-1,me=s-1 contained
|
|
||||||
|
|
||||||
" color specification
|
|
||||||
highlight default link wergeHunk Comment
|
|
||||||
highlight default link wergeRm Removed
|
|
||||||
highlight default link wergeDiffAdd Added
|
|
||||||
highlight default link wergeConflictOrigAdd Comment
|
|
||||||
highlight default link wergeConflictOrig Changed
|
|
||||||
highlight default link wergeConflictAdd Added
|
|
||||||
|
|
||||||
let b:current_syntax = "werge"
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: werge
|
name: werge
|
||||||
version: 0.2.1.0
|
version: 0.2.0.0
|
||||||
synopsis: mergetool for mangled-up bite-size changes
|
synopsis: mergetool for mangled-up bite-size changes
|
||||||
license: GPL-3.0-or-later
|
license: GPL-3.0-or-later
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
copyright: (c) 2025 Mirek Kratochvil
|
|
||||||
author: Mirek Kratochvil
|
author: Mirek Kratochvil
|
||||||
maintainer: exa.exa@gmail.com
|
maintainer: exa.exa@gmail.com
|
||||||
|
|
||||||
-- copyright:
|
-- copyright:
|
||||||
category: Text
|
category: Text
|
||||||
build-type: Simple
|
build-type: Simple
|
||||||
extra-doc-files: README.md vim/werge.vim
|
extra-doc-files: CHANGELOG.md
|
||||||
|
|
||||||
-- extra-source-files:
|
-- extra-source-files:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue