Commit Graph

138 Commits

Author SHA1 Message Date
Jun Wu
7fa918cefd perftweaks: move commit head detection removal logic to core
Summary: Also change the internal API so it no longer accepts the "heads" argument.

Reviewed By: ryanmce

Differential Revision: D6745865

fbshipit-source-id: 368742be49b192f7630421003552d0a10eb0b76d
2018-04-13 21:50:52 -07:00
Matt Harbison
7d8bebd9c1 tests: remove (glob) annotations that were only for '\' matches
# skip-blame because this was mechanically rewritten the following script.  I
ran it on both *.t and *.py, but none of the *.py changes were proper.  All *.t
ones appear to be, and they run without addition failures on both Windows and
Linux.

  import argparse
  import os
  import re

  ap = argparse.ArgumentParser()
  ap.add_argument('path', nargs='+')
  opts = ap.parse_args()

  globre = re.compile(r'^(.*) \(glob\)(.*)$')

  for p in opts.path:
      tmp = p + '.tmp'
      with open(p, 'rb') as src, open(tmp, 'wb') as dst:
          for line in src:
              m = globre.match(line)
              if not m or '$LOCALIP' in line or '*' in line:
                  dst.write(line)
                  continue
              if '?' in line[:-3] or ('?' in line[:-3] and line[-3:] != '(?)'):
                  dst.write(line)
                  continue
              dst.write(m.group(1) + m.group(2) + '\n')
      os.unlink(p)
      os.rename(tmp, p)
2017-12-10 22:50:57 -05:00
Yuya Nishihara
d46d87090c cat: record the current behavior of wildcard matches in subrepos
Mercurial subrepos support any match patterns.
2017-11-25 15:29:34 +09:00
Gregory Szorc
bcd6d015d2 subrepo: use per-type config options to enable subrepos
We change subrepos.allowed from a list of allowed subrepo types to
a combination of a master switch and per-type boolean flag.

If the master switch is set, subrepos can be disabled wholesale.

If subrepos are globally enabled, then per-type options are
consulted. Mercurial repos are enabled by default. Everything else
is disabled by default.
2017-11-06 22:32:41 -08:00
Yuya Nishihara
9752ef714d subrepo: extend config option to disable subrepos by type (SEC)
This allows us to minimize the behavior change introduced by the next patch.

I have no idea which config style is preferred in UX POV, but I decided to
get things done.

 a) list: 'allowed = hg, git, svn'
 b) sub option: 'allowed.hg = True' or 'allowed:hg = True'
 c) per-type action: 'hg = allow', 'git = abort'
2017-11-05 21:48:58 +09:00
Yuya Nishihara
f864544d81 subrepo: add config option to reject any subrepo operations (SEC)
This is an alternative workaround for the issue5730.

Perhaps this is the simplest way of disabling subrepo operations. It does
nothing clever, but just aborts if Mercurial starts accessing to a subrepo.

I think Greg's patch is more useful since it allows us to at least check
out the parent repository. However, that would be confusing if the default
is flipped to checkout=False and subrepos are silently ignored.

I don't like the config name 'allowed', but I couldn't get any better name.
2017-11-05 21:22:07 +09:00
Matt Harbison
408a3898be subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)
Previously, only the top level repo was shared, and then any subrepos were
cloned on demand.  This is problematic because commits to the parent repo would
write an updated .hgsubstate to the share source, but the corresponding subrepo
commit would be stuck in the local subrepo.  That would prevent an update in the
source repo.  We already go to great lengths to avoid having inconsistent repos
(e.g., `hg push -r rev` will push _everything_ in a subrepo, even if it isn't
referenced in one of the parent's outgoing commits).  Therefore, this seems like
a bug fix, and there's no option to get the old behavior.  I can't imagine the
previous behavior was useful to anybody.

There shouldn't be an issue with svn, since it is centralized.  Maybe --git-dir
can be used for git subrepos, but I'll leave that to someone more familiar with
git.

An integer was previously being implicitly returned from commands.share(), which
caused dispatch() to start crashing when changing over to returning the shared
repo.  All error paths appear to raise, so this can be hardcoded to success.
The clone command checks for 'is None' in a similar pattern, but since
hg.clone() always returns a tuple, that seems wrong?

.. fix:: Issue 5675

   Creating a share of a repository with a Mercurial subrepository will now
   share the subrepository.

and

.. bc::

   Mercurial subrepositories are now shared instead of cloned when the parent
   repository is shared.  This prevents dangling subrepository references in the
   share source.  Previously shared repositories with cloned subrepositories
   will continue to function unchanged.
2017-10-15 22:48:02 -04:00
Denis Laxalde
9efc7f05e3 transaction-summary: show the range of new revisions upon pull/unbundle (BC)
Upon pull or unbundle, we display a message with the range of new revisions
fetched. This revision range could readily be used after a pull to look out
what's new with 'hg log'. The algorithm takes care of filtering "obsolete"
revisions that might be present in transaction's "changes" but should not be
displayed to the end user.
2017-10-12 09:39:50 +02:00
Yuya Nishihara
509744ddfc ssh: unban the use of pipe character in user@host:port string
This vulnerability was fixed by the previous patch and there were more ways
to exploit than using '|shellcmd'. So it doesn't make sense to reject only
pipe character.

Test cases are updated to actually try to exploit the bug. As the SSH bridge
of git/svn subrepos are not managed by our code, the tests for non-hg subrepos
are just removed.

This may be folded into the original patches.
2017-08-07 22:22:28 +09:00
Sean Farley
f904aef7aa subrepo: add tests for hg rogue ssh urls (SEC)
'ssh://' has an exploit that will pass the url blindly to the ssh
command, allowing a malicious person to have a subrepo with
'-oProxyCommand' which could run arbitrary code on a user's machine. In
addition, at least on Windows, a pipe '|' is able to execute arbitrary
commands.

When this happens, let's throw a big abort into the user's face so that
they can inspect what's going on.
2017-07-31 16:04:44 -07:00
Matt Harbison
86a2e6550a subrepo: make the output references to subrepositories consistent
Well, mostly.  The annotation on subrepo functions tacks on a parenthetical to
the abort message, which seems reasonable for a generic mechanism.  But now all
messages consistently spell out 'subrepository', and double quote the name of
the repo.  I noticed the inconsistency in the change for the last commit.
2017-07-09 16:13:30 -04:00
Pulkit Goyal
f8b6f67b7a update: show the commit to which we updated in case of multiple heads (BC)
Currently when we have multiple heads on the same branch, update tells us that
there some more heads for the current branch but does not tells us the head to
which the repository has been updated to. It makes more sense showing the
head we updated to and then telling there are some more heads.
2017-06-06 22:17:39 +05:30
Matt Harbison
d898f4f6e4 tests: adjust recent output changes for Windows 2017-06-04 20:11:59 -04:00
Yuya Nishihara
eff4d5e967 cat: add formatter support
This is an example showing how formatter can handle the --output option.
git subrepo isn't supported for now.
2017-05-25 21:53:44 +09:00
Matt Harbison
6ade8faab6 test-subrepo: update output for Windows 2017-04-02 02:24:09 -04:00
Simon Farnsworth
ddbe7287e7 subrepo: move prompts out of the if (issue5505)
Prompts weren't available in the else clause
2017-03-20 04:36:55 -07:00
Matt Harbison
c6639930d0 tests: update globs for Windows
The extra glob in test-command-template.t caused it to say no result was
reported.  It used to be (within the past year), that both this and the missing
glob cases could be fixed simply by editing any output in the test, and
re-running it in interactive mode.  But that no longer works, and I had to diff
*.t against *.t.err.  I didn't dig into what changed.
2017-01-08 13:49:53 -05:00
Jun Wu
3ee7ba0bd8 tests: replace "cp -r" with "cp -R"
The POSIX documentation about "cp" [1] says:

  ....

  RATIONALE
    ....
    Earlier versions of this standard included support for the -r option to
    copy file hierarchies. The -r option is historical practice on BSD and
    BSD-derived systems. This option is no longer specified by POSIX.1-2008
    but may be present in some implementations. The -R option was added as a
    close synonym to the -r option, selected for consistency with all other
    options in this volume of POSIX.1-2008 that do recursive directory
    descent.

    The difference between -R and the removed -r option is in the treatment
    by cp of file types other than regular and directory. It was
    implementation-defined how the - option treated special files to allow
    both historical implementations and those that chose to support -r with
    the same abilities as -R defined by this volume of POSIX.1-2008. The
    original -r flag, for historic reasons, did not handle special files any
    differently from regular files, but always read the file and copied its
    contents. This had obvious problems in the presence of special file
    types; for example, character devices, FIFOs, and sockets.
    ....

  ....

  Issue 6
    The -r option is marked obsolescent.
    ....

  Issue 7
    ....
    The obsolescent -r option is removed.
    ....

  (No "Issue 8" yet)

Therefore it's clear that "cp -R" is strictly better than "cp -r".

The issue was discovered when running tests on OS X after 2e4d149e62aa.

[1]: pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html
2016-11-30 19:25:18 +00:00
Kostia Balytskyi
279f8962a7 conflicts: make spacing consistent in conflict markers
The way default marker template was defined before this patch,
the spacing before dash in conflict markes was dependent on
whether changeset is a tip one or not. This is a relevant part
of template:
    '{ifeq(tags, "tip", "", "{tags} "}'
If revision is a tip revision with no other tags, this would
resolve to an empty string, but for revisions which are not tip
and don't have any other tags, this would resolve to a single
space string. In the end this causes weirdnesses like the ones
you can see in the affected tests.

This is a not a big deal, but double spacing may be visually
less pleasant.

Please note that test changes where commit hashes change are
the result of marking files as resolved without removing markers.
2016-11-19 15:41:37 -08:00
Simon Farnsworth
3622717b76 merge: add conflict labels to merge command
Now that we present the conflict labels in prompts, it's useful to have
better names than "local" and "other" for every command.
2016-10-07 08:51:50 -07:00
Simon Farnsworth
dfbb92b63b merge: use labels in subrepo merge
This is the last place that doesn't respect conflict labels in merge output.
Teach subrepos to use subrepo merge output too.
2016-10-08 01:25:28 -07:00
timeless
a57e86590a discovery: use single quotes in use warning 2016-09-20 23:47:30 +00:00
Pierre-Yves David
a8616bb250 tests: remove all remaining usage of experimental.bundle2-exp
The only remaining usage of the experimental config were enforcing bundle2 on.
These are very old remains of when bundle2 was off by default. This was also
useful to highlight the fact that this was a bundle2 run and that a bundle1 one
was nearby. However, we want a future developer working on bundle3 to notice
possible output/behavior change on these tests and take them in account.  So we
do not enforce bundle2 for these runs. We leave a comment around to make sure
dev still notice the bundle1 version.
2016-08-03 15:52:11 +02:00
Pierre-Yves David
69f1aa48c0 tests: use 'legacy.exchange' option in various mixed tests
The new option will stay around. The experimental option was only meant to be
temporary. We update various tests that validate both bundle1 and bundle2
version side by side. This changeset only takes care of enforcing bundle1. The
other use of 'experimental.bundle2-exp=True' will be taken care of in the next
changeset.
2016-08-03 15:39:55 +02:00
Hannes Oldenburg
723f5d01de cmdutil: warnings not issued in cat if subrepopath overlaps
Previously a subrepository "sub" would cause no warnings to
be issued for a file "subnot/a", if it's not present in the
corresponding changeset when calling:

hg cat subnot/a
2016-07-27 08:38:54 +00:00
Hannes Oldenburg
d5c4fdb0dc cmdutil: warnings not issued in remove if subrepopath overlaps
Previously a subrepository "sub" would cause no warnings to be issued
for a file "subnot/a" if it is not removed when calling:

hg remove -S "subnot/a"
2016-07-22 11:29:42 +00:00
Matt Harbison
3652c17658 tests: flag Windows specific lines about background closing as optional 2016-02-29 01:01:20 -05:00
Pierre-Yves David
2e0675043e update: warn about other topological heads on bare update
A concern around the user experience of Mercurial is user getting stuck on there
own topological branch forever. For example, someone pulling another topological
branch, missing that message in pull asking them to merge and getting stuck on
there own local branch.

The current way to "address" this concern was for bare 'hg update' to target the
tipmost (also latest pulled) changesets and complain when the update was not
linear. That way, failure to merge newly pulled changesets would result in some
kind of failure.

Yet the failure was quite obscure, not working in all cases (eg: commit right
after pull) and the behavior was very impractical in the common case
(eg: issue4673).

To be able to change that behavior, we need to provide other ways to alert a
user stucks on one of many topological head. We do so with an extra message after
bare update:

  1 other heads for branch "default"

Bookmark get its own special version:

  1 other divergent bookmarks for "foobar"

There is significant room to improve the message itself, and we should augment
it with hint about how to see theses other heads or handle the situation (see
in-line comment). But having "a" message is already a significant improvement
compared to the existing situation. Once we have it we can iterate on a better
version of it. As having such message is an important step toward changing the
default destination for update and other nicety, I would like to move forward
quickly on getting such message.

This was discussed during London - October 2015 Sprint.
2016-02-02 14:49:02 +00:00
Ruslan Sayfutdinov
3f980f0f17 backout: commit changeset by default (BC)
Add --no-commit flag to prevent it. This should make the hg user
experience a little better. Some discussion can be found here:
http://markmail.org/message/7jm7ro2ias6hxywy
2016-01-15 13:46:33 -08:00
Siddharth Agarwal
807dab9ed1 filemerge: add debug output for whether this is a change/delete conflict
Just like binary and symlink conflicts, change/delete conflicts influence the
tool picked.
2015-11-25 14:25:26 -08:00
Siddharth Agarwal
c97c4cf7f6 merge.mergestate: perform all premerges before any merges (BC)
We perform all that we can non-interactively before prompting the user for input
via their merge tool. This allows for a maximally consistent state when the user
is first prompted.

The test output changes indicate the actual behavior change happening.
2015-10-11 21:56:39 -07:00
Siddharth Agarwal
a6dc53e738 simplemerge: move conflict warning message to filemerge
The current output for a failed merge with conflict markers looks something like:

  merging foo
  warning: conflicts during merge.
  merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
  merging bar
  warning: conflicts during merge.
  merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')

We're going to change the way merges are done to perform all premerges before
all merges, so that the output above would look like:

  merging foo
  merging bar
  warning: conflicts during merge.
  merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
  warning: conflicts during merge.
  merging bar incomplete! (edit conflicts, then use 'hg resolve --mark')

The 'warning: conflicts during merge' line has no context, so is pretty
confusing.

This patch will change the future output to:

  merging foo
  merging bar
  warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
  warning: conflicts while merging bar! (edit, then use 'hg resolve --mark')

The hint on how to resolve the conflicts makes this a bit unwieldy, but solving
that is tricky because we already hint that people run 'hg resolve' to retry
unresolved merges. The 'hg resolve --mark' mostly applies to conflict marker
based resolution.
2015-10-09 13:54:52 -07:00
Siddharth Agarwal
88da24240c filemerge: break overall filemerge into separate premerge and merge steps
This means that in ms.resolve we must call merge after calling premerge. This
doesn't yet mean that all premerges happen before any merges -- however, this
does get us closer to our goal.

The output differences are because we recompute the merge tool. The only
user-visible difference caused by this patch is that if the tool is missing
we'll print the warning twice. Not a huge deal, though.
2015-10-11 20:47:14 -07:00
Pierre-Yves David
30913031d4 error: get Abort from 'error' instead of 'util'
The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be
confused about that and gives all the credit to 'util' instead of the
hardworking 'error'. In a spirit of equity, we break the cycle of injustice and
give back to 'error' the respect it deserves. And screw that 'util' poser.

For great justice.
2015-10-08 12:55:45 -07:00
Siddharth Agarwal
30c73e4dd2 filemerge: normalize 'internal:foo' names to ':foo'
In upcoming patches we're going to present these names in the UI -- it would be
good not to present deprecated names.
2015-10-07 00:01:16 -07:00
FUJIWARA Katsunori
51754ba82b context: write dirstate out explicitly after marking files as clean
To detect change of a file without redundant comparison of file
content, dirstate recognizes a file as certainly clean, if:

  (1) it is already known as "normal",
  (2) dirstate entry for it has valid (= not "-1") timestamp, and
  (3) mode, size and timestamp of it on the filesystem are as same as
      ones expected in dirstate

This works as expected in many cases, but doesn't in the corner case
that changing a file keeps mode, size and timestamp of it on the
filesystem.

The timetable below shows steps in one of typical such situations:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
  N                                              -1    ***
       - make file "f" clean                            N

       - execute 'hg foobar'
         - instantiate 'dirstate'           -1   -1
         - 'dirstate.normal("f")'           N    -1
           (e.g. via dirty check)
         - change "f", but keep size                    N
  N+1
         - release wlock
           - 'dirstate.write()'             N    N

       - 'hg status' shows "f" as "clean"   N    N      N
  ---- ----------------------------------- ---- ----- -----

The most important point is that 'dirstate.write()' is executed at N+1
or later. This causes writing dirstate timestamp N of "f" out
successfully. If it is executed at N, 'parsers.pack_dirstate()'
replaces timestamp N with "-1" before actual writing dirstate out.

Occasional test failure for unexpected file status is typical example
of this corner case. Batch execution with small working directory is
finished in no time, and rarely satisfies condition (2) above.

This issue can occur in cases below;

  - 'hg revert --rev REV' for revisions other than the parent
  - failure of 'merge.update()' before 'merge.recordupdates()'

The root cause of this issue is that files are changed without
flushing in-memory dirstate changes via 'repo.commit()' (even though
omitting 'dirstate.normallookup()' on changed files also causes this
issue).

To detect changes of files correctly, this patch writes in-memory
dirstate changes out explicitly after marking files as clean in
'workingctx._checklookup()', which is invoked via 'repo.status()'.

After this change, timetable is changed as below:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
  N                                              -1    ***
       - make file "f" clean                            N

       - execute 'hg foobar'
         - instantiate 'dirstate'           -1   -1
         - 'dirstate.normal("f")'           N    -1
           (e.g. via dirty check)
       ----------------------------------- ---- ----- -----
         - 'dirsttate.write()'              -1   -1
       ----------------------------------- ---- ----- -----
         - change "f", but keep size                    N
  N+1
         - release wlock
           - 'dirstate.write()'             -1   -1

       - 'hg status'                        -1   -1      N
  ---- ----------------------------------- ---- ----- -----

To reproduce this issue in tests certainly, this patch emulates some
timing critical actions as below:

  - timestamp of "f" in '.hg/dirstate' is -1 at the beginning

    'hg debugrebuildstate' before command invocation ensures it.

  - make file "f" clean at N
  - change "f" at N

    'touch -t 200001010000' before and after command invocation
    changes mtime of "f" to "2000-01-01 00:00" (= N).

  - invoke 'dirstate.write()' via 'repo.status()' at N

    'fakedirstatewritetime.py' forces 'pack_dirstate()' to use
    "2000-01-01 00:00" as "now", only if 'pack_dirstate()' is invoked
    via 'workingctx._checklookup()'.

  - invoke 'dirstate.write()' via releasing wlock at N+1 (or "not at N")

    'pack_dirstate()' via releasing wlock uses actual timestamp at
    runtime as "now", and it should be different from the "2000-01-01
    00:00" of "f".

BTW, this patch also changes 'test-largefiles-misc.t', because adding
'dirstate.write()' makes recent dirstate changes visible to external
process.
2015-07-08 17:01:09 +09:00
Matt Harbison
d7353508b0 scmutil: consistently return subrepos relative to ctx1 from itersubrepos()
Previously, if a subrepo was added in ctx2 and then compared to another without
it (ctx1), the subrepo for ctx2 was returned amongst all of the ctx1 based
subrepos, since no subrepo exists in ctx1 to replace it in the 'subpaths' dict.
The two callers of this, basectx.status() and cmdutil.diffordiffstat(), both
compare the yielded subrepo against ctx2, and thus saw no changes when ctx2's
subrepo was returned.  The tests here previously didn't mention 's/a' for the
'p1()' case.

This appears to have been a known issue, because some diffordiffstat() comments
mention that the subpath disappeared, and "the best we can do is ignore it".  I
originally ran into the issue with some custom convert code to flatten a tree of
subrepos causing hg.putcommit() to abort, but this new behavior seems like the
correct status and diff behavior regardless.  (The abort in convert isn't
something users will see, because convert doesn't currently support subrepos in
the official repo.)
2015-06-03 14:21:15 -04:00
Gilles Moris
c60f7ce967 summary: move the parents phase marker to commit line (issue4688)
The phase of the pending commit depends on the parent of the working directory
and on the phases.newcommit configuration.
First, this information rather depend on the commit line which describe the
pending commit.
Then, we only want to be advertised when the pending phase is going to be higher
than the default new commit phase.

So the format will change from

$ hg summary
parent: 2:ab91dfabc5ad
 foo
parent: 3:24f1031ad244 tip
 bar
branch: default
commit: 1 modified, 1 unknown, 1 unresolved (merge)
update: (current)
phases: 1 secret (secret)

to

parent: 2:ab91dfabc5ad
 foo
parent: 3:24f1031ad244 tip
 bar
branch: default
commit: 1 modified, 1 unknown, 1 unresolved (merge) (secret)
update: (current)
phases: 1 secret
2015-05-29 22:23:58 +02:00
Pierre-Yves David
d83ef60585 subrepo: detect issue3781 case earlier so it apply to bundle2
We are doing some strange special casing of phase push when:

- the source is a subrepo
- the destination is publishing
- some changeset are still draft on the destination

In that case we do not push phases information (to publish the draft changesets)
because it could break simple cycle of 'clone/pull/push' of subrepos. We have to
detect this case earlier to have bundle2 respecting it.

We change the test to check the behavior for both bundle1 and bundle2.
2015-05-27 06:08:14 -07:00
Pierre-Yves David
281365197e progress: get the extremely verbose output out of default debug
When the progress extension is not enabled, each call to 'ui.progress' used to
issue a debug message. This results is a very verbose output and often redundant
in tests. Dropping it makes tests less volatile to factor they do not meant to
test.

We had to alter the sed trick in 'test-rename-merge2.t'. Sed is used to drop all
output from a certain point and hidding the progress output remove its anchor.
So we anchor on something else.
2015-05-09 23:40:40 -07:00
Gilles Moris
7771de9187 summary: add a phase line (draft, secret) to the output
The number of draft and secret changesets are currently not summarized.
This is an important information because the number of drafts give some rough
idea of the number of outgoing changesets in typical workflows, without needing
to probe a remote repository. And a non-zero number of secrets means that
those changeset will not be pushed.

If the repository is "dirty" - some draft or secret changesets exists - then
summary will display a line like:

phases: X draft, Y secret (public)

The phase in parenthesis corresponds to the highest phase of the parents of
the working directory, i.e. the current phase.

By default, the line is not printed if the repository is "clean" - all
changesets are public - but if verbose is activated, it will display:

phases: (public)

On the other hand, nothing will be printed if quiet is in action.

A few tests have been added in test-phases.t to cover the -v and -q cases.
2015-05-14 17:38:38 +02:00
Matt Harbison
d85501c01b subrepo: don't pass the outer repo's --rev or --branch to subrepo incoming()
When passing a --rev, 'hg incoming -S' previously suffered from the same output
truncation or abort that was fixed for 'hg outgoing -S' in the previous patch,
for the same reasons.

Unlike push, subrepos are currently only pulled when the outer repo is updated,
not when the outer repo is pulled.  That makes matching 'hg pull' behavior
impossible.  Listing all incoming csets in the subrepo seems like the most
useful behavior, and is consistent with 'hg outgoing -S'.
2015-04-27 21:34:23 -04:00
Matt Harbison
87ea927ca1 subrepo: don't pass the outer repo's --rev or --branch to subrepo outgoing()
The previous behavior didn't reflect what would actually be pushed- push will
ignore --rev and --branch in the subrepo and push everything.  Therefore,
'push -r {rev}' would not list everything, unless {rev} was also the revision of
the subrepo's tip.  Worse, if a hash was passed in, the command would abort
because that hash would either not be in the outer repo or not in the subrepo.
2015-04-27 21:15:25 -04:00
Matt Harbison
8ed0a9ea81 subrepo: don't write .hgsubstate lines with empty subrepo state (issue4622)
The '' that is used to represent the state of a not-yet-committed
subrepo cannot be written to the file, because the code that parses
the file splits on ' ' and expects two parts.

Given that the .hgsubstate file is automatically rewritten on commit, it seems
a little strange that the file is written out during a merge.
2015-04-24 23:23:55 -04:00
FUJIWARA Katsunori
e269967115 subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty
This patch also centralizes composing dirty reason message like
"uncommitted changes in subrepository 'xxxx'".
2015-03-25 13:55:35 +09:00
FUJIWARA Katsunori
d9071e6959 subrepo: add dirtyreason to centralize composing dirty reason message
This patch newly adds "dirtyreason()" to centralize composing dirty
reason message like "uncommitted changes in subrepository 'xxxx'".

There are 3 similar messages below, and this patch is a part of
preparations for unifying them into (1), too.

  1. uncommitted changes in subrepository 'XXXX'
  2. uncommitted changes in subrepository XXXX
  3. uncommitted changes in subrepo XXXX

This patch chooses adding new method "dirtyreason()" instead of making
"dirty()" return "reason string", because:

  - some of existing "dirty()" implementation is too complicated to do
    so simply, and

  - ill-mannered 3rd party subrepo classes, of which "dirty()" doesn't
    return "reason string", cause meaningless message (even though it
    is rare case)
2015-03-25 13:55:32 +09:00
Matt Harbison
3ea5067ed3 subrepo: add basic support to hgsubrepo for the files command
Paths into the subrepo are not yet supported.

The need to use the workingctx in the subrepo will likely be used more in the
future, with the proposed working directory revset symbol.  It is also needed
with archive, if that code is to be reused to support 'extdiff -S'.
Unfortunately, it doesn't seem possible to put the smarts in subrepo.subrepo(),
as it breaks various status and diff tests.

I opted not to pass the desired revision into the subrepo method explicitly,
because the only ones that do pass an explicit revision are methods like status
and diff, which actually operate on two contexts- the subrepo state and the
explicitly passed revision.
2015-03-18 23:03:41 -04:00
Matt Mackall
6decf56e3e merge with stable 2015-02-27 17:46:03 -06:00
Martin von Zweigbergk
07f7ea01b3 subrepo: add tests for change/remove conflicts
There are currently no tests for change/remove conflicts of subrepos,
and it's pretty broken. Add some tests demonstrating some of the
breakages and fix the most obvious one (a KeyError when trying to look
up a subrepo in the wrong context).
2015-02-17 23:20:55 -08:00
FUJIWARA Katsunori
2ad325e10a merge: mark .hgsubstate as possibly dirty before submerge for consistency
Before this patch, failure of updating subrepos may cause inconsistent
".hgsubstate". For example:

  1. dirstate entry for ".hgsubstate" of the parent repo is filled
     with valid size/date (via "hg state" or so)

  2. "hg update" is invoked at the parent repo

  3. ".hgsubstate" of the parent repo is updated on the filesystem as
     a part of "g"(et) action in "merge.applyupdates"

  4. it is assumed that size/date of ".hgsubstate" on the filesystem
     aren't changed from ones at (1)

     this is not so difficult condition, because just changing hash
     ids (every ids are same in length) in ".hgsubstate" doesn't
     change the file size of it

  5. "subrepo.submerge()" is invoked to update subrepos

  6. failure of updating in one of subrepos raises exception
     (e.g. "untracked file differs")

  7. "hg update" is aborted without updating dirstate of the parent repo

     dirstate entry for ".hgsubstate" still holds size/date at (1)

Then, ".hgsubstate" of the parent repo is treated as "CLEAN"
unexpectedly, because updating ".hgsubstate" at (3) doesn't change
size/date of it on the filesystem: see assumption at (4).

This inconsistent ".hgsubstate" status causes unexpected behavior, for
example:

  - "hg revert" forgets to revert ".hgsubstate"

  - "hg update" misunderstands that (not yet updated) subrepos diverge
    (then, it shows the prompt to confirm user's decision)

To avoid inconsistent ".hgsubstate" status above, this patch marks
".hgsubstate" as possibly dirty before "submerge" invocation.
"normallookup"-ed (= dirty) dirstate should be written out, even if
processing is aborted by failure.

This patch marks ".hgsubstate" as possibly dirty before "submerge",
also when it is removed or merged while merging, for safety. This
should prevent Mercurial from misunderstanding inconsistent
".hgsubstate" as clean.

To satisfy conditions at (1) and (4) above, this patch uses "hg status
--config debug.dirstate.delaywrite=2" (to fill valid size/date into
dirstate) and "touch" (to fix date of the file).
2015-01-30 04:59:05 +09:00