expand README
This commit is contained in:
		
							parent
							
								
									44bd3e8c14
								
							
						
					
					
						commit
						554429b9b1
					
				
							
								
								
									
										5
									
								
								Main.hs
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Main.hs
									
									
									
									
									
								
							|  | @ -156,6 +156,11 @@ isKeepTok _ = False | ||||||
| isDelTok (Del, _) = True | isDelTok (Del, _) = True | ||||||
| isDelTok _ = False | isDelTok _ = False | ||||||
| 
 | 
 | ||||||
|  | -- TODO: Diff output is not necessarily deterministic; we could make the chunk | ||||||
|  | -- sequences more unique by rolling them to front (or back), possibly enabling | ||||||
|  | -- more conflict resolution and preventing mismerges. | ||||||
|  | -- | ||||||
|  | -- Example: " a " can be made out of " {+a +}" or "{+ a+} " | ||||||
| chunks :: [(Op, String)] -> [Merged] | chunks :: [(Op, String)] -> [Merged] | ||||||
| chunks [] = [] | chunks [] = [] | ||||||
| chunks xs@((Keep, _):_) = | chunks xs@((Keep, _):_) = | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								Opts.hs
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Opts.hs
									
									
									
									
									
								
							|  | @ -225,7 +225,7 @@ cmdGitMerge = do | ||||||
|       [ fmap Just . some |       [ fmap Just . some | ||||||
|           $ strArgument |           $ strArgument | ||||||
|           $ metavar "UNMERGED" |           $ metavar "UNMERGED" | ||||||
|               <> help "Unmerged git file (can be specified repeatedly)" |               <> help "Unmerged file tracked by git (can be specified repeatedly)" | ||||||
|       , flag' |       , flag' | ||||||
|           Nothing |           Nothing | ||||||
|           (long "unmerged" |           (long "unmerged" | ||||||
|  |  | ||||||
							
								
								
									
										191
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										191
									
								
								README.md
									
									
									
									
									
								
							|  | @ -1,19 +1,77 @@ | ||||||
| 
 | 
 | ||||||
| # werge (merge weird stuff) | # werge (merge weird stuff) | ||||||
| 
 | 
 | ||||||
| This is a partial work-alike of `diff3` and `git merge` and other merge-y tools that is capable of | This is a partial work-alike of `diff3` and `git merge` and other merge-y tools | ||||||
|  | that is capable of | ||||||
| 
 | 
 | ||||||
| - merging token-size changes instead of line-size ones | - merging token-size changes instead of line-size ones | ||||||
| - largely ignoring changes in blank characters | - largely ignoring changes in blank characters | ||||||
| 
 | 
 | ||||||
| These properties are great for several use-cases: | These properties are great for several use-cases: | ||||||
| 
 | 
 | ||||||
| - merging free-flowing text changes (such as in TeX) irrespective of linebreaks | - merging free-flowing text changes (such as in TeX) irrespective of line breaks | ||||||
|   etc, |   etc, | ||||||
| - merging of changesets that use different code formatters | - merging of change sets that use different code formatters | ||||||
| - minimizing the conflict size of tiny changes to a few characters, making them | - minimizing the conflict size of tiny changes to a few characters, making them | ||||||
|   easier to resolve |   easier to resolve | ||||||
| 
 | 
 | ||||||
|  | ## Demo | ||||||
|  | 
 | ||||||
|  | Original (`old` file): | ||||||
|  | ``` | ||||||
|  | Roses are red. Violets are blue. | ||||||
|  | Patch is quite hard. I cannot rhyme. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Local changes (`my` file): | ||||||
|  | ``` | ||||||
|  | Roses are red. Violets are blue. | ||||||
|  | Patching is hard. I still cannot rhyme. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Remote changes (`your` file): | ||||||
|  | ``` | ||||||
|  | Roses are red. | ||||||
|  | Violets are blue. | ||||||
|  | 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): | ||||||
|  | ``` | ||||||
|  | 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.) | ||||||
|  | 
 | ||||||
|  | Token-merged version with separate space resolution using `-s` (conflicts get | ||||||
|  | fixed separately): | ||||||
|  | ``` | ||||||
|  | Roses are red. | ||||||
|  | Violets are blue. | ||||||
|  | Patching is hard. | ||||||
|  | I still cannot do verses. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | A harder-conflicting file (`theirs`): | ||||||
|  | ``` | ||||||
|  | Roses are red. | ||||||
|  | Violets are blue. | ||||||
|  | Merging is quite hard. | ||||||
|  | I cannot do verses. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | `werge merge mine orig theirs -s` highlights the actual unmergeable change: | ||||||
|  | ``` | ||||||
|  | Roses are red. | ||||||
|  | Violets are blue. | ||||||
|  | <<<<<Patching|||||Patch=====Merging>>>>> is hard. | ||||||
|  | I still cannot do verses. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## How does it work? | ## How does it work? | ||||||
| 
 | 
 | ||||||
| - Instead of lines, the files are torn to small tokens (words, spaces, symbols, | - Instead of lines, the files are torn to small tokens (words, spaces, symbols, | ||||||
|  | @ -21,6 +79,10 @@ These properties are great for several use-cases: | ||||||
| - Some tokens are marked as spaces by the tokenizer, which allows the merge | - Some tokens are marked as spaces by the tokenizer, which allows the merge | ||||||
|   algorithm to be (selectively) more zealous when resolving conflicts on these. |   algorithm to be (selectively) more zealous when resolving conflicts on these. | ||||||
| 
 | 
 | ||||||
|  | This approach differs from various other structured-merge tools by being | ||||||
|  | completely oblivious about the file structure. Werge trades off some merge | ||||||
|  | quality for (a lot of) complexity. | ||||||
|  | 
 | ||||||
| Tokenizers are simple, implementable as linear scanners that print separate | Tokenizers are simple, implementable as linear scanners that print separate | ||||||
| tokens on individual lines that are prefixed with a space mark (`.` for space | tokens on individual lines that are prefixed with a space mark (`.` for space | ||||||
| and `|` for non-space), and also escape newlines and backslashes. A default | and `|` for non-space), and also escape newlines and backslashes. A default | ||||||
|  | @ -61,50 +123,117 @@ 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 | may set up a path to such `diff` (or a wrapper script) via environment variable | ||||||
| `WERGE_DIFF`. | `WERGE_DIFF`. | ||||||
| 
 | 
 | ||||||
| ## Help & features | ## Use with `git` | ||||||
|  | 
 | ||||||
|  | `werge` can automatically process files that are marked in `git` as merge | ||||||
|  | conflicts: | ||||||
|  | 
 | ||||||
|  | ```sh | ||||||
|  | $ git merge somebranch | ||||||
|  | $ werge git -ua | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Options `-ua` (`--unmerged --add`) find all files that are marked as unmerged, | ||||||
|  | tries to merge them token-by-token, and if the merge is successful with current | ||||||
|  | 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`. | ||||||
|  | 
 | ||||||
|  | ## Current `--help` and features | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| werge -- blanks-friendly mergetool for tiny interdwindled changes | werge -- blanks-friendly mergetool for tiny interdwindled changes | ||||||
| 
 | 
 | ||||||
| Usage: werge [(-F|--tok-filter FILTER) | (-i|--simple-tokens) |  | Usage: werge [(-F|--tok-filter FILTER) | (-i|--simple-tokens) |  | ||||||
|                (-I|--full-tokens)] [-s|--spaces (normal|conflict|my|old|your)]  |                (-I|--full-tokens)] [--no-zeal | (-z|--zeal)]  | ||||||
|              [-C|--expand-context N] [--no-zeal | (-z|--zeal)]  |              [-S|--space (keep|my|old|your)]  | ||||||
|              [--label-start STRING] [--label-mo STRING] [--label-oy STRING]  |              [-s | --resolve-space (normal|keep|my|old|your)]  | ||||||
|              [--label-end STRING] [--conflict-overlaps] [--conflict-separate] |              [--conflict-space-overlaps] [--conflict-space-separate]  | ||||||
|              COMMAND |              [--conflict-space-all] [-C|--expand-context N]  | ||||||
|  |              [--resolve (keep|my|old|your)] [--conflict-overlaps]  | ||||||
|  |              [--conflict-separate] [--conflict-all] [-G|--color]  | ||||||
|  |              [--label-start "<<<<<"] [--label-mo "|||||"] [--label-oy "====="]  | ||||||
|  |              [--label-end ">>>>>"] COMMAND | ||||||
| 
 | 
 | ||||||
| Available options: | Available options: | ||||||
|   -F,--tok-filter FILTER   external program to separate the text to tokens |   -F,--tok-filter FILTER   External program to separate the text to tokens | ||||||
|   -i,--simple-tokens       use wider character class to separate the tokens |   -i,--simple-tokens       Use wider character class to separate the tokens | ||||||
|                            (results in larger tokens and ignores case) |                            (results in larger tokens and ignores case) | ||||||
|   -I,--full-tokens         separate characters by all known character classes |   -I,--full-tokens         Separate characters by all known character classes | ||||||
|                            (default) |                            (default) | ||||||
|   -s,--spaces (normal|conflict|my|old|your) |   --no-zeal                avoid zealous mode (default) | ||||||
|                            mode of merging the space-only changes; instead of |   -z,--zeal                Try to zealously minify conflicts, potentially | ||||||
|                            usual resolution one may choose to always conflict or |                            resolving them | ||||||
|                            to default the space from the source files (default: |   -S,--space (keep|my|old|your) | ||||||
|                            normal) |                            Retain spacing from a selected version, or keep all | ||||||
|  |                            space changes for merging (default: keep) | ||||||
|  |   -s                       Shortcut for `--resolve-space keep' (this separates | ||||||
|  |                            space-only conflicts, enabling better automated | ||||||
|  |                            resolution) | ||||||
|  |   --resolve-space (normal|keep|my|old|your) | ||||||
|  |                            Resolve conflicts in space-only tokens separately, | ||||||
|  |                            and either keep unresolved conflicts, or resolve in | ||||||
|  |                            favor of a given version; `normal' resolves the | ||||||
|  |                            spaces together with other tokens, ignoring choices | ||||||
|  |                            in --resolve-space-* (default: normal) | ||||||
|  |   --conflict-space-overlaps | ||||||
|  |                            Never resolve overlapping changes in space-only | ||||||
|  |                            tokens | ||||||
|  |   --conflict-space-separate | ||||||
|  |                            Never resolve separate (non-overlapping) changes in | ||||||
|  |                            space-only tokens | ||||||
|  |   --conflict-space-all     Never resolve any changes in space-only tokens | ||||||
|   -C,--expand-context N    Consider changes that are at most N tokens apart to |   -C,--expand-context N    Consider changes that are at most N tokens apart to | ||||||
|                            be a single change. Zero may cause bad resolutions of |                            be a single change. Zero may cause bad resolutions of | ||||||
|                            near conflicting edits. (default: 1) |                            near conflicting edits (default: 1) | ||||||
|   --no-zeal                avoid zealous mode (default) |   --resolve (keep|my|old|your) | ||||||
|   -z,--zeal                try to zealously minify conflicts, potentially |                            Resolve general conflicts in favor of a given | ||||||
|                            resolving them |                            version, or keep the conflicts (default: keep) | ||||||
|   --label-start STRING     label for beginning of the conflict |   --conflict-overlaps      Never resolve overlapping changes in general tokens | ||||||
|                            (default: "<<<<<") |   --conflict-separate      Never resolve separate (non-overlapping) changes in | ||||||
|   --label-mo STRING        separator of local edits and original |                            general tokens | ||||||
|                            (default: "|||||") |   --conflict-all           Never resolve any changes in general tokens | ||||||
|   --label-oy STRING        separator of original and other people's edits |   -G,--color               Use shorter, gaily colored output markers by default | ||||||
|                            (default: "=====") |                            (requires ANSI color support; good for terminals or | ||||||
|   --label-end STRING       label for end of the conflict (default: ">>>>>") |                            `less -R') | ||||||
|   --conflict-overlaps      do not resolve overlapping changes |   --label-start "<<<<<"    Label for beginning of the conflict | ||||||
|   --conflict-separate      do not resolve separate (non-overlapping) changes |   --label-mo "|||||"       Separator of local edits and original | ||||||
|  |   --label-oy "====="       Separator of original and other people's edits | ||||||
|  |   --label-end ">>>>>"      Label for end of the conflict | ||||||
|   -h,--help                Show this help text |   -h,--help                Show this help text | ||||||
|   --version                Show version information |   --version                Show version information | ||||||
| 
 | 
 | ||||||
| Available commands: | Available commands: | ||||||
|   merge                    diff3-style merge of two changesets |   merge                    diff3-style merge of two changesets | ||||||
|   git                      automerge unmerged files in git conflict |   git                      Automerge unmerged files in git conflict | ||||||
| 
 | 
 | ||||||
| werge is a free software, use it accordingly. | werge is a free software, use it accordingly. | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | #### Manual merging | ||||||
|  | ``` | ||||||
|  | Usage: werge merge MYFILE OLDFILE YOURFILE | ||||||
|  | 
 | ||||||
|  |   diff3-style merge of two changesets | ||||||
|  | 
 | ||||||
|  | Available options: | ||||||
|  |   MYFILE                   Version with local edits | ||||||
|  |   OLDFILE                  Original file version | ||||||
|  |   YOURFILE                 Version with other people's edits | ||||||
|  |   -h,--help                Show this help text | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | #### Git interoperability | ||||||
|  | ``` | ||||||
|  | Usage: werge git (UNMERGED | (-u|--unmerged)) [(-a|--add) | --no-add] | ||||||
|  | 
 | ||||||
|  |   Automerge unmerged files in git conflict | ||||||
|  | 
 | ||||||
|  | Available options: | ||||||
|  |   UNMERGED                 Unmerged file tracked by git (can be specified | ||||||
|  |                            repeatedly) | ||||||
|  |   -u,--unmerged            Process all files marked as unmerged by git | ||||||
|  |   -a,--add                 Run `git add' for fully merged files | ||||||
|  |   --no-add                 Prevent running `git add' | ||||||
|  |   -h,--help                Show this help text | ||||||
|  | ``` | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Mirek Kratochvil
						Mirek Kratochvil