Skip to content

Commit

Permalink
Change recommended git configuration
Browse files Browse the repository at this point in the history
`git-difftool` has strictly less information than `git-diff`.
`git-difftool` therefore produces worse results, and we shouldn't
recommend it.

`git-difftool` does not have file rename information, and sometimes
makes difftastic claim that file permissions have changed (depending
on the permissions of the temporary directory used).

Instead, recommend `git-diff` with an external diff configured, and
update `git-mergetool` instructions to emulate `git-diff` as much as
possible (respecting $MERGED).

Also link to the upstream git bug on segfaults with external diff
tools.

Thanks to @poliorcetics and @gthb for researching this bug and
discussing possible solutions.

Closes #734
Fixes #620
  • Loading branch information
Wilfred committed Sep 23, 2024
1 parent a319483 commit 393845d
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 45 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## 0.61 (unreleased)

**Recommended git configuration has changed! Please update your
`~/.gitconfig` to match the manual, regardless of your difftastic
version.**

## 0.60 (released 1st August 2024)

### Diffing
Expand Down
134 changes: 89 additions & 45 deletions manual/src/git.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,72 @@
# Git

Difftastic has good support for git.
Difftastic can be used an external diff command in git, allowing
difftastic to be used with any git subcommand.

<div class="warning">

Warning: git v2.43.1 and earlier [can
crash](https://github.com/git/git/commit/85a9a63c9268b18b24f25f6a14d6ae9966c3566d)
when using an external diff and file permissions have changed.

If you can't upgrade git, use the `difftool` configuration described
below.

</div>

## One-Off Usage

You can use
[`GIT_EXTERNAL_DIFF`](https://git-scm.com/docs/diff-config#Documentation/diff-config.txt-diffexternal)
for a one-off git command.
You can set the `diff.external` configuration option when running `git
diff`, or set the
[`GIT_EXTERNAL_DIFF`](https://git-scm.com/docs/diff-config#Documentation/diff-config.txt-diffexternal) environment variable.

View uncommitted changes with difftastic:

```
$ GIT_EXTERNAL_DIFF=difft git diff
$ git -c diff.external=difft diff
```

Other git commands also require the `--ext-diff` argument in order to
use `diff.external`.

View changes from the most recent commit with difftastic:

```
$ GIT_EXTERNAL_DIFF=difft git show HEAD --ext-diff
$ git -c diff.external=difft show --ext-diff
```

View changes from recent commits on the current branch with
difftastic:

```
$ GIT_EXTERNAL_DIFF=difft git log -p --ext-diff
$ git -c diff.external=difft log -p --ext-diff
```

## Regular Usage

If you like difftastic, we recommend that you configure git aliases
so you can use difftastic more easily.

Add the following to your `~/.gitconfig` to use difftastic as a
[difftool](https://git-scm.com/docs/git-difftool).

```ini
[diff]
tool = difftastic

[difftool]
prompt = false

[difftool "difftastic"]
cmd = difft "$LOCAL" "$REMOTE"

[pager]
difftool = true
```

You can now use the following command to see changes with difftastic,
equivalent to `git diff`:

```
$ git difftool
[alias]
# Difftastic aliases, so `git dlog` is `git log` with difftastic and so on.
dlog = -c diff.external=difft log --ext-diff
dshow = -c diff.external=difft show --ext-diff
ddiff = -c diff.external=difft diff
```

We recommend that you set up a shorter alias for this command in your
`~/.gitconfig`:
The author likes the following additional aliases to reduce typing:

```ini
# `git dft` is less to type than `git difftool`.
[alias]
dft = difftool
```
# `git log` with patches shown with difftastic.
dl = -c diff.external=difft log -p --ext-diff

For other commands, we also recommend that you set up aliases that are
equivalent to the one-off commands shown above.
# Show the most recent commit with difftastic.
ds = -c diff.external=difft show --ext-diff

```ini
# `git dlog` to show `git log -p` with difftastic.
[alias]
dlog = -c diff.external=difft log -p --ext-diff
# `git diff` with difftastic.
dft = -c diff.external=difft diff
```

## Difftastic By Default
Expand All @@ -81,17 +76,66 @@ following to your `~/.gitconfig`.

```ini
[diff]
external = difft
external = difft
```

This only applies to `git diff`. For other git commands, you still
need to specify `--ext-diff`, or use an alias as described above.
This changes `git diff` to use difftastic, and other commands now only
require `--ext-diff`.

```
$ git diff
$ git show HEAD --ext-diff
$ git show --ext-diff
$ git log -p --ext-diff
```

Conversely, if you need to copy/paste a diff in the standard diff format, you
can use `git diff --no-ext-diff`.
If you've configured difftastic as the default diff tool, you can
opt-out for an individual command with `--no-ext-diff`.

```
$ git diff --no-ext-diff
```

## Difftool

Git also has a [difftool
feature](https://git-scm.com/docs/git-difftool) which allows users to
invoke CLI or GUI comparison tools.

For best results, we recommend using `-c diff.external=difft` as
described above. Git passes more information to the external diff,
including file permission changes and rename information, so
difftastic can show more information.

To define a difftool named `difftastic`, add the following to your
`~/.gitconfig`.

```ini
[difftool "difftastic"]
# See `man git-difftool` for a description of MERGED, LOCAL and REMOTE.
cmd = difft "$MERGED" "$LOCAL" "abcdef1" "100644" "$REMOTE" "abcdef2" "100644"
```

You can now use difftastic as a difftool:

```
$ git difftool -t difftastic
```

For the best results when using difftastic as a difftool, we recommend
the following additional git configuration:

```ini
[difftool]
# Run the difftool immediately, don't ask 'are you sure' each time.
prompt = false

[pager]
# Use a pager if the difftool output is larger than one screenful,
# consistent with the behaviour of `git diff`.
difftool = true

[diff]
# Set difftastic as the default difftool, so we don't need to specify
# `-t difftastic` every time.
tool = difftastic
```

0 comments on commit 393845d

Please sign in to comment.