revert: Revert local changes and/or changes from previous commits

Usage:
  eg revert [[-m PARENT_NUMBER] --in REVISION | --since REVISION]
            [--staged | --unstaged] [--] [PATH...]

Description:
  eg revert undoes edits to your files, without changing the commit history
  or changing which commit is active.  (If you are looking for a different
  kind of 'undo'; they are discussed and contrasted below.)  There are many
  options for what to revert; you may want to jump ahead to the examples
  section below and then come back and read the full description.

  The work eg revert does includes discarding local modifications, removing
  recorded conflict states, undoing add or stage operations (i.e. unstaging
  files), and restoring deleted files to the previously recorded version.
  If you revert changes since some revision prior to the most recent,
  revert will also remove any files which were added in a later revision.

  By default, eg revert will revert edits since the last commit(*).  One
  can specify a different revision to revert file contents back to, or
  revert edits made in a single previous commit(**).  (Advanced usage note:
  eg revert will undo both staged and unstaged changes by default; you can
  request only one of these; see 'eg help topic staging' for more details
  on what staged and unstaged changes are.)

  (*) For an initial or root commit, eg revert will simply undo adds.  When
  in an uncompleted merge state, it is an error to not specify which commit
  to revert relative to (with the --since flag).

. (**) When reverting the changes made *in* a merge commit, the revert
  command needs to know which parent of the merge the revert should be
  relative to.  This can be specified using the -m option.

  To avoid accidental loss of local changes, nothing will be done when no
  arguments are provided to eg revert.  However, eg revert will check for
  various special cases (from the different types of 'undo' below), and try
  to provide an error message tailored to any special circumstances
  relevant to you.

  === Comparison of different types of 'undo' available ===
  * Back up or switch to an earlier commit (eg switch)
  * Make a new commit to reverse the changes of a previous commit (eg
    cherry-pick -R)
  * Remove commits from history (eg reset OR eg rebase --interactive)
  * Reverting edits, without switching commits or changing commit history
    (eg revert)
  * Abort an incomplete operation
    * Incomplete merge:      eg revert --since HEAD
    * Unfinished rebase:     eg rebase --abort
    * Unfinished apply mail: eg am --abort
    * Unfinished bisect:     eg bisect reset

Examples:
  Undo changes since the last commit on the current branch to bar.h and
  foo.c.  This can be done with either of the following methods:
      $ eg revert bar.h foo.c                      # Method #1
      $ eg revert --since HEAD bar.h foo.c         # Method #2, more explicit

  While on the bling branch, revert the changes in the last 3 commits (as
  well as any local changes) to any file under the directory docs.  This
  can be done by:
      $ eg revert --since bling~3 docs

  While on the stable branch, you determine that the seventh commit prior
  to the most recent had a faulty change to foosubdir and baz.txt and you
  simply want to undo it.  This can be accomplished by:
      $ eg revert --in stable~7 -- foosubdir baz.txt

  You decide that all changes to foobar.cpp in your working copy and in the
  last 2 commits are bad and want to revert them.  This is done by:
  of:
      $ eg revert --since HEAD~2 -- foobar.c

  You decide that some of the changes in the merge commit HEAD~4 are bad.
  You would like to revert the changes to baz.py in HEAD~4 relative to its
  second parent.  This can be accomplished as follows:
      $ eg revert -m 2 --in HEAD~4 baz.py
  
  (Advanced) Undo a previous stage, marking changes in foo.c as not
  being ready for commit (this is equivalent to eg unstage foo.c):
      $ eg revert --staged foo.c

  (Advanced) Undo changes since the most recent stage to soopergloo.f77
      $ eg revert --unstaged soopergloo.f77

  (Advanced) You decide that the changes to abracadabra.xml made in commit
  HEAD~8 are bad.  You want to revert those changes in the version of
  abracadabra.xml but only to your working copy.  This is done by:
      $ eg revert --unstaged --in HEAD~8 -- abracadabra.xml

Options:
  --since
    Revert the changes made since the specified commit, including any local
    changes.  This takes the difference between the specified commit and
    the current version of the files and reverses these changes.

  --in
    Revert the changes made in the specified commit.  This takes the
    difference between the parent of the specified commit and the specified
    commit and reverse applies it.

  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.

  -m PARENT_NUMBER
    When reverting the changes made in a merge commit, the revert command
    needs to know which parent of the merge the revert should be relative
    to.  Use this flag with the parent number (1, 2, 3...) to specify which
    parent commit to revert relative to.

    Can only be used with the --in option.

  --staged
    Make changes only to the staged (explicitly marked as ready to be
    committed) version of files.

  --unstaged
    Make changes only to the unstaged version of files, i.e. only to the
    working copy.

  --
    This option can be used to separate command-line options and commits
    from the list of files, (useful when filenames might be mistaken for
    command-line options or be mistaken as a branch or tag name).

  PATH...
    One or more files or directories.  The changes reverted will be limited
    to the listed files or files below the listed directories.

Differences from git revert:
  eg revert is similar to the revert command of svn, hg, bzr, or darcs.  It
  is not provided by any one git command; it overlaps with about five
  different git commands in specific cases.  git users wanting the
  functionality in eg revert will typically be guided by expert git users
  towards whichever git command seems like the most natural fit for the
  particular case the user asks about.  Quite often, such users will
  continue using the command they are given for subsequent situations...and
  will often stumble across multiple cases where the git command no longer
  matches the wanted revert behavior.

  git does provide a command called revert, which is a subset of the
  behavior of eg cherry-pick:
    git revert COMMIT
  is the same as
    eg cherry-pick -R COMMIT
  which is, modulo the automatic commit message provided by git revert, the
  same as
    eg revert --in COMMIT && eg commit
  Note that while eg revert --in may look similar to git revert, the former
  is about undoing changes in just the working copy, is typically
  restricted to a specific subset of files, and is usually just one change
  of many towards testing or creating something new to be committed.  The
  latter is always concerned with reverse applying an entire commit, and is
  almost always used to immediately record that change.

  Note that git revert commands are invalid syntax in eg (since eg revert
  always requires the --since or --in flags to be specified whenever a
  commit is).  This means that eg can catch such cases and notify git
  users to adopt the eg cherry-pick -R command.

  Due to these changes, eg revert should be much more welcoming to users of
  svn, hg, bzr, or darcs.  It also provides a simple discovery mechanism
  for existing git users to allow them to easily work with eg.
  Additionally, these changes also make the reset and checkout/switch
  subcommands of eg easier to understand by limiting their scope instead of
  each having two very different capabilities.  (Technically, eg reset and
  eg checkout still have those capabilities for backwards compatibility, I
  just omit them in the documentation.)

  It seems that perhaps eg revert could be extended further, to accept
  things like
      \$ eg revert --in HEAD~8..HEAD~5 foo.c
  to allow reverting changes made in a range of commits.  The --in could
  even be optional in such a case, since the range makes it clear what is
  wanted.