# How to use diff and patch

I edit a lot of text files.
Sometimes it's code, other times it's the written word for RPG or programming books or general correspondence.
Sometimes it's nice to be able make a change but for my collaborator to be able to compare my change with what they originally had written.
Many people default to office suites, like [LibreOffice](https://opensource.com/article/21/9/libreoffice-tips), for this, using comments or change tracking features.
Sometimes a simpler tool makes more sense, though, and for that you can look at programming history for tools like `diff` and `patch`, which provide standardized formatting for tracking and applying changes to shared files.

Even with a simple file, there's complexity in synchronizing two documents.
Some items get changed, others are left alone, new content gets added, and some stay the same but are moved to different places in the document.
It's difficult to replicate changes without blissfully accepting that all changes are equally valid, and replacing the old file with the new one.
It's also monolithically opaque.
There are so many changes that it's difficult to pick out exactly what's changed.

With the `diff` command, you can create a record of how the file has changed, and with `patch` you can "replay" those changes over the old version to bring it up to date with the new version.


## Setup

Suppose you and I are collaborating on a file describing how to make a cup of tea.
So far, the file `tea.md` contains raw copy paste:

```text
Boil water.
Warm the teapot.
Add tea and water to the teapot.
Place a tea cosy over the teapot.
Steep for 6 minutes.
Pour tea into cup.
Add milk.
```

Seems reasonable, but there are always optimizations to be made, so you send the file to me for improvement.
In an effort to clarify the tea-making process, I copy the file as `tea-revision.md` and edit it, ending up with this:

```text
Warm a teapot in the proving drawer of your oven.
Boil water.
Add tea leaves to a tea strainer.
Add strainer and water to teapot.
Steep for 6 minutes. Keep it warm with a tea cosy.
Pour tea into cup.
Optionally, add warm milk.
```

As expected, some items (`Boil water` and `Pour tea into cup`) are unchanged, while other lines (`Warm the teapot`) have had additions. Some lines are completely new, and some lines are the same but in a different order.

## Create a diff

The `diff` tool displays the difference between two files.
There are a few different ways to view the results, but I think the clearest one is the `--unified` (`-u` for short) view, which shows which lines have been added or subtracted.
A line that's changed in any way is treated as a line that has been subtracted, and then added.
By default, `diff` prints its output to the terminal.

Provide `diff` with the old file and then the new file:

```bash
$ diff --unified tea.md tea-revised.md
--- tea.md      2021-11-13 10:26:25.082110219 +1300
+++ tea-revised.md      2021-11-13 10:26:32.049110664 +1300
@@ -1,7 +1,7 @@
+Warm a teapot in the proving drawer of your oven.
Boil water.
-Warm the teapot.
-Add tea and water to the teapot.
-Place a tea cosy over the teapot.
-Steep for 6 minutes.
+Add tea leaves to a tea strainer.
+Add strainer and water to teapot.
+Steep for 6 minutes. Keep it warm with a tea cosy.
Pour tea into cup.
-Add milk.
+Optionally, add warm milk.
```

A plus sign (`+`) at the beginning of a line indicates something that's been added to the old file.
A minus sign (`-`) at the beginning of a line indicates a line that's been removed or changed.

## Create a patch with diff

A patch file is just the output of the `diff --unified` command placed into a file.
You can do this using standard Bash redirection:

```bash
$ diff -u tea.md tea-revised.md > tea.patch
```

The contents of the file are exactly the same as what was output to the terminal.
I like to view patch files in [Emacs](https://opensource.com/article/20/12/emacs), which color codes each line depending on whether it's being added or subtracted.

![emacs.jpg](A patch file in Emacs)

## Applying changes with patch

Once I have a patch file, I could send it to you for you to review and, optionally, apply to your old file.
You apply a patch with the `patch` command:

```bash
$ patch tea.md tea.patch
```

Lines are added, lines are subtracted, and in the end you end up with a file identical to my version:

```bash
$ cat tea.md
Warm a teapot in the proving drawer of your oven.
Boil water.
Add tea leaves to a tea strainer.
Add strainer and water to teapot.
Steep for 6 minutes. Keep it warm with a tea cosy.
Pour tea into cup.
Optionally, add warm milk.
```

There's no limit to how many time a file can be patched.
You could iterate on my changes, generate a new patch, and send that to me for review.
Sending changes rather than results lets each contributor to review what's been done, decide what they want to keep or eliminate, and it accurately documents the process.

## Install

On Linux and macOS, you already have both the `diff` and `patch` commands.
On Windows, you can obtain `diff` and `patch` through [Cygwin](https://cygwin.com), or use Chocolatey to search for [diffutils](https://community.chocolatey.org/packages/diffutils) and [patch](https://community.chocolatey.org/packages/patch).

If you've ever tried to collaborate on files over email or chat, and you've found yourself trying to *describe* where a change needs to be made, then you'll love `diff` and `patch`.
A carefully structured file, such as code or line-delimited [Markdown](https://opensource.com/article/19/9/introduction-markdown), is easy to diff, patch, and maintain.