shrink-conflicts 0.1.0

Tries to minimise diff3-style git conflicts
Documentation
# Shrink git conflicts

`shrink-conflicts` is a program which tries to minimise diff3-style git
conflicts.

## Workflow

As I work on resolving a conflict, I slowly make all three parts (left,
right, and centre) more and more similar.  As I do this, I repeatedly pass
the conflict through `shrink-conflicts` to have it automatically simplified
(and possibly elliminated).  It's pretty nice.

`shrink-conflicts` reads data on stdin and prints it to stdout (ie. it's a
"filter").  This means you can easily use it from within your text editor:
just pipe the buffer through it.

## Credit

I got the idea from [git-mediate][].  `shrink-conflicts` is a re-implementation
of (part of) git-mediate's functionality.

[git-mediate]: https://github.com/Peaker/git-mediate

## Example

Here's lib.rs:

```rs
impl Conflict {
<<<<<<<
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
        // TODO: Should we be handling the common part too?
        self.left.is_empty() && self.right.is_empty()
    }
|||||||
    fn is_resolved(&self) -> bool {
        self.left.is_empty() && self.right.is_empty()
    }
=======
    fn is_resolved(&self) -> bool {
        self.left.is_empty() && self.common.is_empty() && self.right.is_empty()
    }
>>>>>>>
}
```

Running this file through `shrink-conflicts` will have no effect yet.
Let's copy the doc comment from the left part into the common and right parts.

```rs
impl Conflict {
<<<<<<<
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
        // TODO: Should we be handling the common part too?
        self.left.is_empty() && self.right.is_empty()
    }
|||||||
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
        self.left.is_empty() && self.right.is_empty()
    }
=======
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
        self.left.is_empty() && self.common.is_empty() && self.right.is_empty()
    }
>>>>>>>
}
```

Now when we run this through `shrink-conflicts` it detects that all
three have a common prefix, and pulls it out:

```console
$ shrink-conflicts <lib.rs
impl Conflict {
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
<<<<<<<
        // TODO: Should we be handling the common part too?
        self.left.is_empty() && self.right.is_empty()
|||||||
        self.left.is_empty() && self.right.is_empty()
=======
        self.left.is_empty() && self.common.is_empty() && self.right.is_empty()
>>>>>>>
    }
}
```

Now, let's delete the TODO.

```rs
impl Conflict {
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
<<<<<<<
        self.left.is_empty() && self.right.is_empty()
|||||||
        self.left.is_empty() && self.right.is_empty()
=======
        self.left.is_empty() && self.common.is_empty() && self.right.is_empty()
>>>>>>>
    }
}
```

This time, when we run the file through `shrink-conflicts`, it detects that
the left and common parts are identical, and so selects the right part.

```console
$ shrink-conflicts <lib.rs
impl Conflict {
    /// Is this conflict resolved?
    fn is_resolved(&self) -> bool {
        self.left.is_empty() && self.common.is_empty() && self.right.is_empty()
    }
}
```