Compare commits
15 commits
aea372a87d
...
f294df0e69
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f294df0e69 | ||
|
|
6e19cd7267 | ||
|
|
6126e1c976 | ||
|
|
10777c32f6 | ||
|
|
6beaeec8e7 | ||
|
|
6682b5ed37 | ||
|
|
6cdd70feaf | ||
|
|
50a3d08aa8 | ||
|
|
2ed3f68748 | ||
|
|
b0ffa1a3e6 | ||
|
|
ecb03d3be4 | ||
|
|
e6ae4a04d3 | ||
|
|
13b5da3d74 | ||
|
|
bb194535e0 | ||
|
|
8241b556b1 |
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
|
@ -14,7 +14,6 @@ jobs:
|
|||
matrix:
|
||||
os: [ubuntu-22.04, macos-15]
|
||||
ghc:
|
||||
- "9.6"
|
||||
- "9.12"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
# 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)
|
||||
bad e = do
|
||||
hPutStrLn stderr $ "fatal: " ++ displayException (e :: IOException)
|
||||
exitWith (ExitFailure 2)
|
||||
exitWith (ExitFailure 129)
|
||||
|
|
|
|||
149
README.md
149
README.md
|
|
@ -21,21 +21,52 @@ Separate `diff`&`patch` functionality is provided too for sending
|
|||
token-granularity patches. (The patches are similar to what `git diff
|
||||
--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
|
||||
|
||||
Original (`old` file):
|
||||
##### Original (`old` file):
|
||||
```
|
||||
Roses are red. Violets are blue.
|
||||
Patch is quite hard. I cannot rhyme.
|
||||
```
|
||||
|
||||
Local changes (`my` file):
|
||||
##### Local changes (`my` file):
|
||||
```
|
||||
Roses are red. Violets are blue.
|
||||
Patching is hard. I still cannot rhyme.
|
||||
```
|
||||
|
||||
Remote changes (`your` file):
|
||||
##### Remote changes (`your` file):
|
||||
```
|
||||
Roses are red.
|
||||
Violets are blue.
|
||||
|
|
@ -43,18 +74,23 @@ Patch is quite hard.
|
|||
I cannot do verses.
|
||||
```
|
||||
|
||||
Token-merged version with `werge merge my orig your` (conflicts on the space
|
||||
change that is too close to the disappearing "still" token):
|
||||
##### Token-merged version
|
||||
|
||||
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.
|
||||
Violets are blue.
|
||||
Patching is hard.<<<<< I still||||| I=====
|
||||
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`.)
|
||||
|
||||
Token-merged version with separate space resolution using `-s` (conflicts get
|
||||
fixed separately):
|
||||
##### Merge with separate space resultion
|
||||
Adding option `-s` to `werge merge` causes it to resolve space conflicts
|
||||
separately, usually helping many cases that would be easily resolvable by a
|
||||
human:
|
||||
```
|
||||
Roses are red.
|
||||
Violets are blue.
|
||||
|
|
@ -62,7 +98,8 @@ Patching is hard.
|
|||
I still cannot do verses.
|
||||
```
|
||||
|
||||
A harder-conflicting file (`theirs`):
|
||||
##### Mixing in unresolvable conflict
|
||||
A harder-conflicting file (`their`):
|
||||
```
|
||||
Roses are red.
|
||||
Violets are blue.
|
||||
|
|
@ -70,7 +107,7 @@ Merging is quite hard.
|
|||
I cannot do verses.
|
||||
```
|
||||
|
||||
`werge merge mine orig theirs -s` highlights the actual unmergeable change:
|
||||
`werge merge my old their -s` highlights the actual unmergeable change:
|
||||
```
|
||||
Roses are red.
|
||||
Violets are blue.
|
||||
|
|
@ -134,18 +171,9 @@ 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
|
||||
user-specifiable tokenizers in a pretty cool way.
|
||||
|
||||
## Installation
|
||||
## Integration with `git`
|
||||
|
||||
```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`
|
||||
### Automerging conflicts
|
||||
|
||||
`werge` can automatically process files that are marked in `git` as merge
|
||||
conflicts:
|
||||
|
|
@ -161,6 +189,85 @@ 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
|
||||
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
|
||||
|
||||
```
|
||||
|
|
|
|||
29
vim/werge.vim
Normal file
29
vim/werge.vim
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
" 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,16 +1,17 @@
|
|||
cabal-version: 3.0
|
||||
name: werge
|
||||
version: 0.2.0.0
|
||||
version: 0.2.1.0
|
||||
synopsis: mergetool for mangled-up bite-size changes
|
||||
license: GPL-3.0-or-later
|
||||
license-file: LICENSE
|
||||
copyright: (c) 2025 Mirek Kratochvil
|
||||
author: Mirek Kratochvil
|
||||
maintainer: exa.exa@gmail.com
|
||||
|
||||
-- copyright:
|
||||
category: Text
|
||||
build-type: Simple
|
||||
extra-doc-files: CHANGELOG.md
|
||||
extra-doc-files: README.md vim/werge.vim
|
||||
|
||||
-- extra-source-files:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue