diff: Show changes to file contents

Usage:
  eg diff [--unstaged | --staged] [REVISION] [REVISION] [FILE...]

Description:
  Shows differences between different versions of the project.  By default,
  it shows the differences between the last locally recorded version and the
  version in the working copy.

Examples:
  Show local unrecorded changes
      $ eg diff

  In a project with the current branch being 'master', show the differences
  between the version before the last recorded commit and the working copy.
      $ eg diff master~1
  Or do the same using "HEAD" which is a synonym for the current branch:
      $ eg diff HEAD~1

  Show changes to the file myscript.py between 10 versions before last
  recorded commit and the last recorded commit (assumes the current branch
  is 'master').
      $ eg diff master~10 master myscript.py

  (Advanced) Show changes between staged (ready-to-be-committed) version of
  files and the working copy (use 'eg stage' to stage files).  In other
  words, show the unstaged changes.
      $ eg diff --unstaged

  (Advanced) Show changes between last recorded copy and the staged (ready-
  to-be-committed) version of files (use 'eg stage' to stage files).  In
  other words, show the staged changes.
      $ eg diff --staged

  (Advanced) Show changes between 5 versions before the last recorded
  commit and the currently staged (ready-to-be-committed) version of the
  repository.  (Use 'eg stage' to stage files).
      $ eg diff --staged HEAD~5

Options:
  REVISION
    A reference to a recorded version of the repository, defaulting to HEAD
    (meaning the most recent commit on the current branch).  See 'eg help
    topic revisions' for more details.

  --staged
    Show changes between the last commit and the staged copy of files.
    Cannot be used when two revisions have been specified.

  --unstaged
    Show changes between the staged copy of files and the current working
    directory.  Cannot be used when a revision is specified.

Differences from git diff:
  Changes to eg diff relative to git diff are:
    (1) Different defaults for what to diff relative to
    (2) Providing a more consistent double-dot operator

  Section 1: Different defaults for what to diff relative to

  The following illustrate the two changed defaults of eg diff:
    eg diff            <=> git diff HEAD
    eg diff --unstaged <=> git diff
  (Which is not 100% accurate due to merges; see below.)  In more detail:

  The "--unstaged" option is unique to eg diff; to get the same behavior
  with git diff you simply list no revisions and omit the "--cached" flag.

  When neither --staged nor --unstaged are specified to eg diff and no
  revisions are given, eg diff will pass along the revision "HEAD" to git
  diff.

  The "--staged" option is an alias for "--cached" unique to eg diff; the
  purpose of the alias is to reduce the number of different names in git
  used to refer to the same concept.  (Update: the --staged flag is now
  part of git with the same meaning as in eg.)

  Merges: The above is slightly modified if the user has an incomplete
  merge; if the user has conflicts during a merge (or uses --no-commit when
  calling merge) and then tries "eg diff", it will abort with a message
  telling the user that there is no "last" commit and will provide
  alternative suggestions.

  Section 2: Providing a more consistent double-dot operator

    The .. operator of git diff (e.g. git diff master..devel) means what
    the ... operator of git log means, and vice-versa.  This causes lots of
    confusion.  We fix this by aliasing making the .. operator of eg diff
    do exactly what the ... operator of git diff does.  To see why:
    
    Meanings of git commands, as a reminder (A and B are revisions):
      git diff A..B  <=> git diff A B                      # Endpoint difference
      git diff A...B <=> git diff $(git merge-base A B) B  # Changes from base
    
    Why this is confusing (compare to above):
      git log A..B  <=> git log ^$(git merge-base A B) B   # Changes from base
      git log A...B <=> git log A B ^$(git merge-base A B) # Endpoint difference
    
    So, my translation:
      eg diff A B   <=>  git diff A B    <=> git diff A..B
      eg diff A..B  <=>  git diff A...B
      eg diff A...B <=>  git diff A...B

    Reasons for this change:
      * New users automatically get sane behavior, and use either eg diff A B
        or eg diff A..B, each doing what one would expect.  They do not ever
        realize that A...B is a bit weird because they have no need to try to
        use it; eg diff A B covers their needs.
      * Users worried about switching between eg and git without having to
        modify their command lines can always use either diff A B or
        diff A...B, but never any other form; using this subset ensures that
        both eg and git behave identically.
      * Users only access git diff A..B behavior through eg diff A B, which
        is less typing and makes more sense.
      * Since git diff A..B and git diff A B are the same, the latter is far
        more common, and the former is confusing, odds are that if any git
        user suggests someone use git diff A..B they probably really meant
        git diff A...B

See also
  Run 'git help diff' for a comprehensive list of options available.
  eg diff is designed to accept the same options as git diff, and
  with the same meanings unless specified otherwise in the above
  "Differences" section.