packages feed

git-mediate 1.1.0 → 1.2.0

raw patch · 9 files changed

+67/−35 lines, 9 filesnew-uploader

Files

ChangeLog.md view
@@ -1,3 +1,11 @@+## 1.2.0 / 2026.08.19++* Add optional automatic resolution of indentation-only conflicts+* Enable splitting conflicts at tilde markers by default+* Fix status reporting for split conflicts+* Prefer Git's `zdiff3` conflict style while continuing to accept `diff3`+* Avoid opening the editor when no unresolved conflicts remain+ ## 1.1.0 / 2024.09.20  * `--split-markers` option to help users split large conflicts to smaller parts
README.md view
@@ -1,11 +1,13 @@-# Introduction+# git-mediate [![Hackage version](https://img.shields.io/hackage/v/git-mediate.svg?label=Hackage)](https://hackage.haskell.org/package/git-mediate) [![homebrew](https://img.shields.io/homebrew/v/git-mediate.svg)](https://formulae.brew.sh/formula/git-mediate) +## Introduction+ Handling conflicts is difficult! -One useful way to handle them, is to use git's diff3 conflict style:+One useful way to handle them, is to use git's {z,}diff3 conflict style:  ```shell-git config --global merge.conflictstyle diff3+git config --global merge.conflictstyle zdiff3 ```  And then when you get a conflict, it looks like:@@ -66,26 +68,27 @@ When all conflicts have been resolved in a file, "git add" will be used on it automatically. -## Simpler case+### Simpler case  You might just resolve the conflicts manually and remove the merge markers from all of the conflicts.  In such a case, just run git-mediate, and it will "git add" the file for you. -# Installation+## Installation -## Using package managers+### Using package managers  * macOS: `brew install git-mediate` * Linux (debian): `apt-get install git-mediate`+* Linux (arch): `yay -S git-mediate` (see https://aur.archlinux.org/packages/git-mediate) -## Using haskell-stack+### Using haskell-stack  1. Install [haskell stack](https://docs.haskellstack.org/en/stable/) 2. Run: `stack install git-mediate` -## From sources+### From sources  Clone it: @@ -96,25 +99,25 @@  Option #2: Build & install using cabal: `cabal install` (make sure `~/.cabal/bin` is in your `$PATH`) -# Use+## Use  Call the git-mediate from a git repository with conflicts. -# Additional features+## Additional features -## Open editor+### Open editor  You can use the `-e` flag to invoke your `$EDITOR` on every conflicted file that could not be automatically resolved. -## Show conflict diffs+### Show conflict diffs  Sometimes, the conflict is just a giant block of incomprehensible text next to another giant block of incomprehensible text.  You can use the `-d` flag to show the conflict in diff-from-base form. Then, you can manually apply the changes you see in both the base and wherever needed, and use git-mediate again to make sure you've updated everything appropriately. -# License+## License -Copyright (C) 2014-2023  Eyal Lotem+Copyright (C) 2014-2024  Eyal Lotem  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
git-mediate.cabal view
@@ -2,7 +2,7 @@ -- further documentation, see https://cabal.readthedocs.io/  name:                git-mediate-version:             1.1.0+version:             1.2.0 synopsis:            Tool to help resolving git conflicts description:         Git conflict resolution has never been easier                      .
src/Environment.hs view
@@ -36,7 +36,7 @@  setConflictStyle :: IO () setConflictStyle =-    callProcess "git" ["config", "--global", "merge.conflictstyle", "diff3"]+    callProcess "git" ["config", "--global", "merge.conflictstyle", "zdiff3"]  checkConflictStyle :: Options -> IO () checkConflictStyle opts =@@ -46,14 +46,14 @@             do                 unless opts.shouldSetConflictStyle $                     fail $ concat-                    [ "merge.conflictstyle must be diff3 but is "+                    [ "merge.conflictstyle must be zdiff3/diff3 but is "                     , show conflictStyle                     , ". Use -s to automatically set it globally"                     ]                 setConflictStyle                  newConflictStyle <- getConflictStyle-                when (newConflictStyle /= "diff3") $+                when (newConflictStyle /= "zdiff3") $                     fail $ concat                     [ "Attempt to set conflict style failed. Perhaps you have"                     , " an incorrect merge.conflictstyle configuration "
src/Main.hs view
@@ -65,7 +65,9 @@     do         when (opts.shouldDumpDiffs || opts.shouldDumpDiff2) $             traverse_ (dumpDiffs colorEnable opts path (length conflicts)) (zip [1 ..] conflicts)-        openEditor opts path ((Conflict.lineNo . Conflict.sideA . markers . head) conflicts)+        case conflicts of+            [] -> pure ()+            c:_ -> openEditor opts path ((Conflict.lineNo . Conflict.sideA . markers) c)  overwrite :: FilePath -> String -> IO () overwrite fileName content =
src/Opts.hs view
@@ -48,7 +48,7 @@     <*> colorParser     <*> O.switch         ( O.long "style" <> O.short 's'-            <> O.help "Configure git's global merge.conflictstyle to diff3 if needed"+            <> O.help "Configure git's global merge.conflictstyle to zdiff3 if needed"         )     <*> O.optional         ( O.strOption
src/Resolution.hs view
@@ -43,10 +43,24 @@         n = length base         addedBothSides x y = [x <> drop n y | drop (length x - n) x == base && take n y == base] +resolveReduced :: ResolutionOptions -> Sides [String] -> Maybe [String]+resolveReduced opts sides+    | opts.indentation =+        map . (<>) <$> resolveGen prefixes <*> resolveGenLines opts unprefixed+    | otherwise = resolveGenLines opts sides+    where+        prefixes = takeWhile (== ' ') . commonPrefix <$> sides+        unprefixed = map . drop . length <$> prefixes <*> sides++commonPrefix :: Eq a => [[a]] -> [a]+commonPrefix [] = []+commonPrefix [x] = x+commonPrefix (x:xs) = map fst . takeWhile (uncurry (==)) . zip x $ commonPrefix xs+ resolveConflict :: ResolutionOptions -> Conflict -> Resolution resolveConflict opts c     | matchTop == 0 && matchBottom == 0 || not opts.reduce =-        maybe (NoResolution c) (Resolution . unlines) (resolveGenLines opts c.bodies)+        maybe (NoResolution c) (Resolution . unlines) (resolveReduced opts c.bodies)     | otherwise =         case resolveGenLines opts reduced.bodies of         Just x -> Resolution $ formatRes x@@ -125,7 +139,7 @@  lineBreakFix :: Conflict -> Conflict lineBreakFix c-    | any null (toList c.bodies)+    | any null c.bodies     || allSame (toList endings) = c     | otherwise =         case resolveGen endings of@@ -149,17 +163,20 @@     foldMap go     where         go (Left line) = NewContent mempty (unlines [line])-        go (Right conflict)-            | opts.splitMarkers =-                r <> splitProgress-            | otherwise = resolve conflict-                where-                    s = splitConflict conflict-                    r = foldMap resolve s-                    splitProgress =-                        case s of-                        (_:_:_) -> NewContent (Result 0 1 0) mempty-                        _ -> mempty+        go (Right conflict) =+            r+            { result =+                case parts of+                [_] -> r.result+                _ | r.result.failedToResolve + r.result.reducedConflicts > 0 ->+                        mempty {reducedConflicts = 1} -- The split is a reduction+                    | otherwise -> mempty {resolvedSuccessfully = 1}+            }+            where+                parts+                    | opts.splitMarkers = splitConflict conflict+                    | otherwise = [conflict]+                r = foldMap resolve parts         resolve conflict =             formatResolution $ resolveConflict opts $             (if opts.lineEndings then lineBreakFix else id) $
src/ResolutionOpts.hs view
@@ -14,6 +14,7 @@     , lineEndings :: Bool     , addedLines :: Bool     , splitMarkers :: Bool+    , indentation :: Bool     }  parser :: OptUtils.Parser ResolutionOptions@@ -27,7 +28,8 @@     <*> OptUtils.envSwitch "line-endings" True "line-ending characters conflict resolution"     <*> OptUtils.envSwitch "lines-added-around" False         "resolve conflicts where one change prepended lines to the base and the other appended"-    <*> OptUtils.envSwitch "split-markers" False "split conflicts at tilde-split-markers"+    <*> OptUtils.envSwitch "split-markers" True "split conflicts at tilde-split-markers"+    <*> OptUtils.envSwitch "indentation" False "indentation conflict resolution"  isResolving :: ResolutionOptions -> Bool isResolving o = o.trivial || o.reduce || isJust o.untabify || o.lineEndings || o.addedLines
stack.yaml view
@@ -1,4 +1,4 @@ flags: {} packages: - '.'-resolver: lts-22.30+resolver: lts-24.55