Change recommended git configuration

`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
fix_newline_splitting
Wilfred Hughes 2024-09-22 13:45:15 +07:00
parent a31948384b
commit 393845ddcb
2 changed files with 93 additions and 45 deletions

@ -1,5 +1,9 @@
## 0.61 (unreleased) ## 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) ## 0.60 (released 1st August 2024)
### Diffing ### Diffing

@ -1,30 +1,45 @@
# Git # 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 ## One-Off Usage
You can use You can set the `diff.external` configuration option when running `git
[`GIT_EXTERNAL_DIFF`](https://git-scm.com/docs/diff-config#Documentation/diff-config.txt-diffexternal) diff`, or set the
for a one-off git command. [`GIT_EXTERNAL_DIFF`](https://git-scm.com/docs/diff-config#Documentation/diff-config.txt-diffexternal) environment variable.
View uncommitted changes with difftastic: 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: 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 View changes from recent commits on the current branch with
difftastic: difftastic:
``` ```
$ GIT_EXTERNAL_DIFF=difft git log -p --ext-diff $ git -c diff.external=difft log -p --ext-diff
``` ```
## Regular Usage ## Regular Usage
@ -32,46 +47,26 @@ $ GIT_EXTERNAL_DIFF=difft git log -p --ext-diff
If you like difftastic, we recommend that you configure git aliases If you like difftastic, we recommend that you configure git aliases
so you can use difftastic more easily. 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 ```ini
[diff] [alias]
tool = difftastic # Difftastic aliases, so `git dlog` is `git log` with difftastic and so on.
dlog = -c diff.external=difft log --ext-diff
[difftool] dshow = -c diff.external=difft show --ext-diff
prompt = false ddiff = -c diff.external=difft diff
[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
``` ```
We recommend that you set up a shorter alias for this command in your The author likes the following additional aliases to reduce typing:
`~/.gitconfig`:
```ini ```ini
# `git dft` is less to type than `git difftool`.
[alias] [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 # Show the most recent commit with difftastic.
equivalent to the one-off commands shown above. ds = -c diff.external=difft show --ext-diff
```ini # `git diff` with difftastic.
# `git dlog` to show `git log -p` with difftastic. dft = -c diff.external=difft diff
[alias]
dlog = -c diff.external=difft log -p --ext-diff
``` ```
## Difftastic By Default ## Difftastic By Default
@ -81,17 +76,66 @@ following to your `~/.gitconfig`.
```ini ```ini
[diff] [diff]
external = difft external = difft
``` ```
This only applies to `git diff`. For other git commands, you still This changes `git diff` to use difftastic, and other commands now only
need to specify `--ext-diff`, or use an alias as described above. require `--ext-diff`.
``` ```
$ git diff $ git diff
$ git show HEAD --ext-diff $ git show --ext-diff
$ git log -p --ext-diff $ git log -p --ext-diff
``` ```
Conversely, if you need to copy/paste a diff in the standard diff format, you If you've configured difftastic as the default diff tool, you can
can use `git diff --no-ext-diff`. 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
```