diff --git a/mercurial/commands.py b/mercurial/commands.py
index 2dc7a2a96cfd6dcf233e38bc9b7db93e29d04c17_bWVyY3VyaWFsL2NvbW1hbmRzLnB5..69e69b131458023d21ec40aa48fc5299e43ce69b_bWVyY3VyaWFsL2NvbW1hbmRzLnB5 100644
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -204,26 +204,22 @@
 def backout(ui, repo, node=None, rev=None, **opts):
     '''reverse effect of earlier changeset
 
-    The backout command merges the reverse effect of the reverted
-    changeset into the working directory.
-
-    With the --merge option, it first commits the reverted changes
-    as a new changeset. This new changeset is a child of the reverted
-    changeset.
-    The --merge option remembers the parent of the working directory
-    before starting the backout, then merges the new head with that
-    changeset afterwards.
-    This will result in an explicit merge in the history.
-
-    If you backout a changeset other than the original parent of the
-    working directory, the result of this merge is not committed,
-    as with a normal merge. Otherwise, no merge is needed and the
-    commit is automatic.
-
-    Note that the default behavior (without --merge) has changed in
-    version 1.7. To restore the previous default behavior, use
-    :hg:`backout --merge` and then :hg:`update --clean .` to get rid of
-    the ongoing merge.
+    Prepare a new changeset with the effect of REV undone in the
+    current working directory.
+
+    If REV is the parent of the working directory, then this changeset
+    is committed automatically. Otherwise, hg needs to merge the
+    changes and the merged result is left uncommitted.
+
+    By default, the pending changeset will have one parent,
+    maintaining a linear history. With --merge, the pending changeset
+    will instead have two parents: the old parent of the working
+    directory and a child of REV that simply undoes REV.
+
+    Before version 1.7, the default behavior was equivalent to
+    specifying --merge followed by :hg:`update --clean .` to cancel
+    the merge and leave the child of REV as a head to be merged
+    separately.
 
     See :hg:`help dates` for a list of formats valid for -d/--date.
 
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
index 2dc7a2a96cfd6dcf233e38bc9b7db93e29d04c17_bWVyY3VyaWFsL2RpcnN0YXRlLnB5..69e69b131458023d21ec40aa48fc5299e43ce69b_bWVyY3VyaWFsL2RpcnN0YXRlLnB5 100644
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -508,7 +508,7 @@
             if files[i] < subpath:
                 i += 1
                 continue
-            while files and files[i].startswith(subpath):
+            while i < len(files) and files[i].startswith(subpath):
                 del files[i]
             j += 1
 
diff --git a/tests/test-subrepo-recursion.t b/tests/test-subrepo-recursion.t
index 2dc7a2a96cfd6dcf233e38bc9b7db93e29d04c17_dGVzdHMvdGVzdC1zdWJyZXBvLXJlY3Vyc2lvbi50..69e69b131458023d21ec40aa48fc5299e43ce69b_dGVzdHMvdGVzdC1zdWJyZXBvLXJlY3Vyc2lvbi50 100644
--- a/tests/test-subrepo-recursion.t
+++ b/tests/test-subrepo-recursion.t
@@ -413,3 +413,15 @@
   $ rm -r foo
   $ hg status -S
   warning: error "unknown revision '65903cebad86f1a84bd4f1134f62fa7dcb7a1c98'" in subrepository "foo"
+
+Issue2619: IndexError: list index out of range on hg add with subrepos
+The subrepo must sorts after the explicit filename.
+
+  $ cd ..
+  $ hg init test
+  $ cd test
+  $ hg init x
+  $ echo "x = x" >> .hgsub
+  $ hg add .hgsub
+  $ touch a x/a
+  $ hg add a x/a