commit: use ui.configbool when checking 'commitsubrepos' setting on --amend

Before this fix, having

   [ui]
   commitsubrepos = False

in the config file lead to

   $ hg ci --amend -mx
   abort: cannot amend recursively

--HG--
branch : stable
patch: fix patch hunk/metdata synchronization (issue3384)

Git patches are parsed in two phases: 1) extract metadata, 2) parse actual
deltas and merge them with the previous metadata. We do this to avoid
dependency issues like "modify a; copy a to b", where "b" must be copied from
the unmodified "a".

Issue3384 is caused by flaky code I wrote to synchronize the patch metadata
with the emitted hunk:

 if (gitpatches and
     (gitpatches[-1][0] == afile or gitpatches[-1][1] == bfile)):
     gp = gitpatches.pop()[2]

With a patch like:

 diff --git a/a b/c
 copy from a
 copy to c
 --- a/a
 +++ b/c
 @@ -1,1 +1,2 @@
  a
 +a
 @@ -2,1 +2,2 @@
  a
 +a
 diff --git a/a b/a
 --- a/a
 +++ b/a
 @@ -1,1 +1,2 @@
  a
 +b

the first hunk of the first block is matched with the metadata for the block
"diff --git a/a b/c", then the second hunk of the first block is matched with
the metadata of the second block "diff --git a/a b/a", because of the "or" in
the code paste above. Turning the "or" into an "and" is not enough as we have
to deal with /dev/null cases for each file.

We I remove this broken piece of code:

 # copy/rename + modify should modify target, not source
 if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
     afile = bfile

because "afile = bfile" set "afile" to stuff like "b/file" instead of "a/file",
and because this only happens for git patches, which afile/bfile are ignored
anyway by applydiff().

v2:
- Avoid a traceback on git metadata desynchronization

--HG--
branch : stable
transplant: do not rollback on patching error (issue3379)

Otherwise, all transplanted revisions are gone and the failing one cannot be
fixed (unless it is the first one).

I do not know what is the expected behaviour with rollback, probably something
pull-like. Non-conflicting cases should work as previously. But something like:

  $ hg transplant r1 r2
  commiting r1 as c1
  failing r2
  $ hg transplant --continue
  committing r2 as c2
  $ hg rollback

would reset the repository to its state before the "transplant --continue"
instead of the whole transplant session. To fix this we might need a way to
open an existing journal file, not sure this is worth the pain.

--HG--
branch : stable
test-rebase: exhibit revisions which should have been skipped

This will be fixed in the next commit.

v2:
- Display emptied grafted revisions
- Use --git flag

--HG--
branch : stable
rebase: skip resolved but emptied revisions

When rebasing, if a conflict occurs and is resolved in a way the rebased
revision becomes empty, it is not skipped, unlike revisions being emptied
without conflicts.

The reason is:
- File 'x' is merged and resolved, merge.update() marks it as 'm' in the
  dirstate.
- rebase.concludenode() calls localrepo.commit(), which calls
  localrepo.status() which calls dirstate.status(). 'x' shows up as 'm' and is
  unconditionnally added to the modified files list, instead of being checked
  again.
- localrepo.commit() detects 'x' as changed an create a new revision where only
  the manifest parents and linkrev differ.

Marking 'x' as modified without checking it makes sense for regular merges. But
in rebase case, the merge looks normal but the second parent is usually
discarded. When this happens, 'm' files in dirstate are a bit irrelevant and
should be considered 'n' possibly dirty instead. That is what the current patch
does.

Another approach, maybe more efficient, would be to pass another flag to
merge.update() saying the 'branchmerge' is a bit of a lie and recordupdate()
should call dirstate.normallookup() instead of merge().

It is also tempting to add this logic to dirstate.setparents(), moving from two
to one parent is what invalidates the 'm' markers. But this is a far bigger
change to make.

v2: succumb to the temptation and move the logic in dirstate.setparents(). mpm
suggested trying _filecommit() first but it is called by commitctx() which
knows nothing about the dirstate and comes too late into the game. A second
approach was to rewrite the 'm' state into 'n' on the fly in dirstate.status()
which failed for graft in the following case:

  $ hg init repo
  $ cd repo
  $ echo a > a
  $ hg ci -qAm0
  $ echo a >> a
  $ hg ci -m1
  $ hg up 0
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  $ hg mv a b
  $ echo c > b
  $ hg ci -m2
  created new head
  $ hg graft 1 --tool internal:local
  grafting revision 1
  $ hg --config extensions.graphlog= glog --template '{rev} {desc|firstline}\n'
  @  3 1
  |
  o  2 2
  |
  | o  1 1
  |/
  o  0 0

  $ hg log -r 3 --debug --patch --git --copies
  changeset:   3:19cd7d1417952af13161b94c32e901769104560c
  tag:         tip
  phase:       draft
  parent:      2:b5c505595c9e9a12d5dd457919c143e05fc16fb8
  parent:      -1:0000000000000000000000000000000000000000
  manifest:    3:3d27ce8d02241aa59b60804805edf103c5c0cda4
  user:        test
  date:        Thu Jan 01 00:00:00 1970 +0000
  extra:       branch=default
  extra:       source=a03df74c41413a75c0a42997fc36c2de97b26658
  description:
  1

Here, revision 3 is created because there is a copy record for 'b' in the
dirstate and thus 'b' is considered modified. But this information is discarded
at commit time since 'b' content is unchanged. I do not know if discarding this
information is correct or not, but at this time we cannot represent it anyway.

This patch therefore implements the last solution of moving the logic into
dirstate.setparents(). It does not sound crazy as 'm' files makes no sense with
only one parent. It also makes dirstate.merge() calls .lookupnormal() if there
is one parent, to preserve the invariant.

I am a bit concerned about introducing this kind of stateful behaviour to
existing code which historically treated setparents() as a basic setter without
side-effects. And doing that during the code freeze.

--HG--
branch : stable
docs: don't use :hg: at the beginning of lines in notes (issue3397)

It seem like docutils 0.8 interpret ':hg:`command`' roles at the beginning of
indented lines in '.. note::' directives as a field that is an invalid argument
to the directive. It fails with 'Error in "note" directive: invalid option
block.' Docutils 0.7 accepted this arguably incorrect markup.

Reflowing the text makes the problem go away. A leading '\ ' could perhaps also
be used to mask the problem.

--HG--
branch : stable
convert/svn: make svn sink work with svn 1.7

"svn add file" now fails if "file" is already tracked. To filter them we have
to mirror the svn manifest in the sink.

Tested with svn 1.6.12 and 1.7.4.

--HG--
branch : stable
test-convert-svn-sink: add helper to smooth svn xml output

svnxml.py parses "svn log --xml" output and prints the attributes shared among
all tested svn versions. This fixes the test with svn 1.7.

Tested with svn 1.6.12 and 1.7.4.

--HG--
branch : stable
alias: fix shell alias documentation (issue3374)

Described behaviour was the one before shell alias argument handling was
reworked by f853873fc66d mid-2010.

--HG--
branch : stable
i18n: use locale insensitive format for datetimes as intermediate representation (issue3398)

on some non "en" locale environments, "hg convert" is aborted, because
"util.parsedate()" fails.

it fails in "memctx.__init__()" called by "putcommit()" of "convert".

in "hg convert", datetimes gotten from source repository
are usually formatted by "util.datestr()" with default format "%a %b
%d %H:%M:%S %Y %1%2".

but on some environments, "%a" and "%b" may cause locale sensitive
string, and such string may cause parse error in "util.parsedate()".

this path uses "%Y-%m-%d %H:%M:%S %1%2" as intermediate representation
format for datetimes, because it consists only of locale insensitive
elements.

datetimes in above format are only used for passing them from
conversion logic to memctx object, so it doesn't have to be formatted
by locale sensitive one.

this patch just avoids locale sensitivity problem of "datestr()" and
"parsedate()" combintion.

--HG--
branch : stable
largefiles: fix status -S reporting of subrepos (issue3231)

Wrapping the status command will only invoke overridestatus() and set
the lfstatus field for the top level repository.  Wrapping the status
function is required to set the field on child repositories.

Previously, status -S would report large files in a subrepo as '?'
regardless of their actual states, and was inconsistent with what
status would report from within that subrepo.

--HG--
branch : stable
largefiles: notice dirty large files in a subrepo

Summary and commit use dirty() to check the status of a subrepository,
so this overrides dirty() in the subrepo in the same manner as
status() to check the large files instead of their standins.

Previously, if only a large file was changed in a subrepo, summary in
the top level repo would not report the subrepo was dirty and commit
-S would report nothing changed.  If any type of file was changed in
the top repo and only a large file in the subrepo, commit -S would not
commit the changes to the subrepo.

--HG--
branch : stable
i18n-pt_BR: synchronized with 83622954b64d

--HG--
branch : stable
merge with i18n

--HG--
branch : stable
i18n-pt_BR: synchronized with e3c7ca15cde2

--HG--
branch : stable
merge with i18n

--HG--
branch : stable