How can I get a side-by-side diff when I do “git d

2019-01-10 01:27发布

When I type "git diff", I'd like to see a side-by-side diff, like with "diff -y", or like to display the diff in an interactive diff tool like "kdiff3". How can this be done?

16条回答
你好瞎i
2楼-- · 2019-01-10 01:51

Several others already mentioned cdiff for git side-by-side diffing but no one gave a full implementation of it.

Setup cdiff:

git clone https://github.com/ymattw/cdiff.git
cd cdiff
ln -s `pwd`/cdiff ~/bin/cdiff
hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
        # or just create a new terminal

Edit ~/.gitconfig inserting these lines:

[pager]
        diff = false
        show = false

[diff]
        tool = cdiff
        external = "cdiff -s $2 $5 #"

[difftool "cdiff"]
        cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"

[alias]
        showw = show --ext-dif

The pager off is needed for cdiff to work with Diff, it is essentially a pager anyway so this is fine. Difftool will work regardless of these settings.

The show alias is needed because git show only supports external diff tools via argument.

The '#' at the end of the diff external command is important. Git's diff command appends a $@ (all available diff variables) to the diff command, but we only want the two filenames. So we call out those two explicitly with $2 and $5, and then hide the $@ behind a comment which would otherwise confuse sdiff. Resulting in an error that looks like:

fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.

Git commands that now produce side-by-side diffing:

git diff <SHA1> <SHA2> 
git difftool <SHA1> <SHA2>
git showw <SHA>

Cdiff usage:

'SPACEBAR' - Advances the page of the current file.
'Q'        - Quits current file, thus advancing you to the next file.

You now have side-by-side diff via git diff and difftool. And you have the cdiff python source code for power user customization should you need it.

查看更多
你好瞎i
3楼-- · 2019-01-10 01:52

Here's an approach. If you pipe through less, the xterm width is set to 80, which ain't so hot. But if you proceed the command with, e.g. COLS=210, you can utilize your expanded xterm.

gitdiff()
{
    local width=${COLS:-$(tput cols)}
    GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}
查看更多
男人必须洒脱
4楼-- · 2019-01-10 01:56

Although Git has an internal implementation of diff, you can set up an external tool instead.

There are two different ways to specify an external diff tool:

  1. setting the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables.
  2. configuring the external diff tool via git config

See also:

When doing a git diff, Git checks both the settings of above environment variables and its .gitconfig file.

By default, Git passes the following seven arguments to the diff program:

path  old-file  old-hex old-mode  new-file  new-hex new-mode

You typically only need the old-file and new-file parameters. Of course most diff tools only take two file names as an argument. This means that you need to write a small wrapper-script, which takes the arguments which Git provides to the script, and hands them on to the external git program of your choice.

Let's say you put your wrapper-script under ~/scripts/my_diff.sh:

#!/bin/bash
# un-comment one diff tool you'd like to use

# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5" 

# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"

# using Meld 
/usr/bin/meld "$2" "$5"

# using VIM
# /usr/bin/vim -d "$2" "$5"

you then need to make that script executable:

chmod a+x ~/scripts/my_diff.sh

you then need to tell Git how and where to find your custom diff wrapper script. You have three choices how to do that: (I prefer editing the .gitconfig file)

  1. Using GIT_EXTERNAL_DIFF, GIT_DIFF_OPTS

    e.g. in your .bashrc or .bash_profile file you can set:

    GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
    export GIT_EXTERNAL_DIFF
    
  2. Using git config

    use "git config" to define where your wrapper script can be found:

    git config --global diff.external ~/scripts/my_diff.sh
    
  3. Editing your ~/.gitconfig file

    you can edit your ~/.gitconfig file to add these lines:

    [diff]
      external = ~/scripts/my_diff.sh
    

Note:

Similarly to installing your custom diff tool, you can also install a custom merge-tool, which could be a visual merging tool to better help visualizing the merge. (see the progit.org page)

See: http://fredpalma.com/518/visual-diff-and-merge-tool/ and https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration

查看更多
家丑人穷心不美
5楼-- · 2019-01-10 01:56
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'

then simply:

git diff
查看更多
登录 后发表回答