Commit Graph

67 Commits

Author SHA1 Message Date
Matt Harbison
d7467d5e8b tests: fix globs for Windows 2015-11-15 21:12:13 -05:00
Christian Delahousse
f5b2078fe3 revert: allow configuring the .orig file location 2015-11-12 17:00:08 -06: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
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
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
Martin von Zweigbergk
f1e241ceae revert: accept just -I/-X without paths or -a/-i (issue4592)
'hg revert -I foo' currently fails with

  abort: no files or directories specified
  (use --all to revert all files, or 'hg update 1' to update)

It doesn't seem intentional that -I/-X without other paths or
--all/--interactive should fail, and it doesn't seem that harmful to
allow it either, so let's just do that.
2015-04-22 16:38:36 -07:00
Martin von Zweigbergk
b1f3f94c3b status: don't list files as both removed and deleted
When calculating status involving the working copy and a revision
other than the parent of the working copy, the files that are not in
the working context manifest ('mf2' in the basectx._buildstatus())
will be reported as removed (note that deleted files _are_ in the
working context manifest). However, if the file is reported as deleted
in the dirstate, it will get that status too (as shown by failing
tests).

Fix by removing deleted files from the 'removed' list after the main
loop in _buildstatus().
2015-01-05 16:52:12 -08:00
Martin von Zweigbergk
06a8686a04 generate-working-copy-states: accept depth arguments on command line
Add a parameter to generate-working-copy-states.py that indicates
how many changesets are wanted. This number impacts all the
subcommands. The current 'filelist' subcommand becomes 'filelist 2',
the current 'base' and 'parent' subcommands become 'state 2 1' and
'state 2 2' respectively, while 'wc' becomes 'state 2 wc'.

See earlier patch for motivation.
2014-11-09 00:10:29 -08:00
Matt Mackall
4abfc94f18 merge with stable 2014-11-27 12:25:01 -06:00
Pierre-Yves David
2d599c1c7d revert: look for copy information for all local modifications
Renaming a file over an existing one marks the file as modified. So we
track rename source in modified file too.
2014-11-25 19:40:54 -08:00
Martin von Zweigbergk
f98c64adb9 test-revert: move embedded script to its own file
Move the gen-revert-cases.py out of test-revert.t into its own file so
we can reuse it from other tests (specifically test-status-rev.t).
2014-11-03 16:27:01 -08:00
Martin von Zweigbergk
15df1657ff test-revert: simplify generation of files
With the recent change in naming of the generated files, it becomes
much easier to generate the files by iterating over all the possible
states than over the state transitions.
2014-10-18 22:00:08 -07:00
Martin von Zweigbergk
f1651673a0 test-revert: make sure all 'tracked' files are really tracked
When a file is missing in the 'parent' version and is tracked but
missing in the working directory, which happens by the 'missing' or
'removed' types, and the 'clean' type in the working directory, the
file does not exist in the working directory (unlike it would had the
'deleted' type been used). Thus, the *_missing_missing_tracked are not
actually tracked and they end up testing the same state as
*_missing_missing_untracked. To make them tracked, add a temporary
file, just like we do for the delete case. For simplicity's sake,
let's make sure the gen-revert-cases.py script always puts a file in
the working directory, whether or not it's going to be deleted.
2014-10-19 22:19:22 -07:00
Martin von Zweigbergk
9d646cd626 test-revert: sort by output filename again
Future patches will change how the output of 'gen-revert-cases.py
filelist' is generated, so now we want the order to depend on just the
filename again.
2014-10-18 18:12:54 -07:00
Martin von Zweigbergk
18adf08aa2 test-revert: name files by state, not by state transition
This is the main patch in a series. See motivation in earlier patch.

In this patch, we actually change the names of the generated
files. For example, the file that is currently called missing_clean
becomes missing_missing_missing-tracked and it's clearer that it
should be tracked. It turns out that since the state was not
previously clear, it ended up testing an untracked state, which was
the same as for missing_clean. We'll fix this in a later patch.

Let's also change the content from (base,parent,wc) to
(content1,content2,content3) to make them all the same length so they
line up when displayed.
2014-10-20 22:54:18 -07:00
Martin von Zweigbergk
a9833ef42f test-revert: temporarily sort by input states instead of output filename
The next patch will change the names of the files produced by the
script in test-revert. In order to reduce the size and increase the
clarity of the next patch, make the order produced by the internal
'gen-revert-cases.py filelist' command independent of the filenames.
2014-10-17 06:27:43 -07:00
Martin von Zweigbergk
d00f670b09 test-revert: put content, not keys, into 'combination'
By putting the file content rather than keys in the 'combination'
list, we restrict the knowledge of 'ctxcontent' and 'wccontent' to the
loop generating the combinations. That will make it easier to replace
the generation code.
2014-10-18 22:23:19 -07:00
Martin von Zweigbergk
c803ef4c1e test-revert: replace 'removed' in working copy with 'untracked-deleted'
The 'wccontent' variable has eight different states, four of them
tracked, and the other four untracked (at least when the file existed
in the parent revision). Among these eight states, 'removed' sticks
out by lacking the 'untracked-' prefix despite resulting in an
untracked state. To make the symmetry clearer, and to prepare for
future patches, rename 'removed' to 'untracked-deleted', which is
exactly what it is.

Note that, unlike 'remove', 'deleted' is configured in
gen-revert-cases.py to have content in the working directory and that
that content is instead expected to be removed in the test script.
However, no changes are needed to the test script, since it already
contains 'hg forget *untracked*' and 'rm *deleted*', which together
have the same effect as 'hg remove'.

See additional motivation in earlier patch.
2014-10-17 09:02:30 -07:00
Martin von Zweigbergk
d22c2292fd test-revert: removing a missing file has no effect
The tests for removed_deleted and removed_removed test the same state
as removed_clean and removed_untracked-clean, respectively. Drop the
duplicate tests.

See additional motivation in earlier patch.
2014-10-16 23:59:08 -07:00
Martin von Zweigbergk
3e9ffd0775 test-revert: reverting an addition is the same as removing
The tests for added_revert and added_untracked-revert test the same
state as added_deleted and added_removed, respectively. Drop the
duplicate tests.

See additional motivation in earlier patch.
2014-10-17 00:39:26 -07:00
Martin von Zweigbergk
8dd8665fba test-revert: reverting no change means it's clean
This is the first step in a series that aims to put the state, not the
state transitions, in the filenames of the files generated by the
gen-revert-cases.py script. The possible state of a file in a revision
and in the working copy is only whether it exists and what its content
is (the tests don't care check flags). In the dirstate, the only state
is whether it's tracked or not. With the new naming, the file that is
currently called modified_untracked-clean now becomes
content1_content2_content2-untracked, for example.

By putting these states in the filename, it becomes easier to see that
we're not missing or duplicating any state, and to check that the
state is what we think it is. For example, the file that is currently
called missing_clean becomes missing_missing_missing-tracked and it's
clearer that it should be tracked.

Putting the content in the filename will also make the tests of file
content (e.g. "cat ../content-parent.txt") very obvious.

When we put the state in the filename, the filenames clearly need to
be unique. However, it turns out that some states are currently tested
multiple times. The 'revert' transition in the script means to take
the content from the grandparent. If the parent is the same as the
grandparent, there is no change compared to the parent, which is
exactly what 'clean' means. Avoid testing the same state twice.
2014-10-16 23:36:40 -07:00
Mads Kiilerich
523c87c1fe spelling: fixes from proofreading of spell checker issues 2014-04-17 22:47:38 +02:00
Martin von Zweigbergk
03fe36c248 test-revert: remove obsolete comment about known misbehavior
It seems like the last known misbehvior that the comment was referring
to was dealt with in 708ed580cbea (revert: properly back up added
files with local modification, 2014-08-31).
2014-10-19 22:09:03 -07:00
Matt Mackall
1dfcf35d21 test-revert.t: fix wc check-code false positive 2014-11-03 11:06:51 -06:00
Pierre-Yves David
bfd39d13a8 revert: properly back up added files with local modification
These files were previously not backed up because the backup mechanism was not
smart enough. This leads to data lose for the user since uncommitted contents
were discarded.

We now properly move the modified version to <filename>.orig before deleting it.

We have to use a small hack to do a different action if "--no-backup" is
specified. This is needed because the backup process is actually a move (not a
copy) so the file is already missing when we backup. The internet kitten is a
bit disapointed about that, but such is life.

This patch concludes the "lets refactor revert" phases. We can now open the
"Lets find stupid bug with renames and merge" phases.

I'm sure that now that the code is clearer we could do it in another simpler
way, but I consider the current improvement good enough for now.
2014-08-31 13:01:00 +02:00
Pierre-Yves David
9f80242186 revert: simplify handling of added files
There are multiple possible cases for added files. But it's all handled by magic
much lower in the stack. We document them, simplify the codes and move on.
2014-08-02 11:32:24 -07:00
Pierre-Yves David
ff3290bfea revert: use modified information from both statuses
Using status information against the target ensures we are catching all
files with modifications that need reverting.

We still need to distinguish fresh modifications for backup purpose.

test-largefile is affected because it reverted a file that needs no content
change.
2014-06-24 17:27:18 +01:00
Pierre-Yves David
708550e527 revert: also track clean files
Tracking clean files is the simplest way to be able to reports files that need
no changes. So we explicitly retrieve them.

This fixes a couple of test outputs where the lack of changes was not reported.
2014-07-31 15:52:56 -07:00
Pierre-Yves David
5b7e70a4d0 revert: issue "no changes needed" message for files missing on both side
When a file was marked as removed in the working copy and did not existed in the
target of the revert, we did not issued any message pointing that no change was
needed to the file (implicitly saying that revert had changed the file).

We now properly issue a message in this situation. Tests change in and handful
of case where the message was documented as missing.
2014-07-31 16:03:26 -07:00
Pierre-Yves David
c2138bc11f test-revert: add case where file is tracked but deleted in working directory 2014-06-25 17:40:41 +01:00
Pierre-Yves David
8168e29d33 test-revert: add case with untracked files with unique content
This test highlights similar misbehavior as its parent changesets.
2014-06-27 18:25:19 +02:00
Pierre-Yves David
82196ae928 test-revert: add case with untracked files with reverted content
This test highlights similar misbehaviors as its parent changesets.
2014-06-27 18:23:45 +02:00
Pierre-Yves David
d7c162a81f test-revert: add case where file exists but is untracked in working directory
This test highlights a small misbehavior in output when reverting to another
revision not including the untracked file.
2014-06-27 18:10:45 +02:00
Pierre-Yves David
c7b21cc553 test-revert: add case where the file is marked as removed in the wc
Unlike untracked, the file is also missing from the working directory.

This test highlights a small misbehavior in output when reverting to another
revision.
2014-06-27 18:09:46 +02:00
Pierre-Yves David
23f0089dda test-revert: add case where wc content is different from "base" and "parent"
This test highlights a case where backups are not created and the user may
lose data.
2014-06-27 18:08:16 +02:00
Pierre-Yves David
412ed73be5 test-revert: add case where wc content is already reverted to base content
This test highlights multiple misbehaviors of revert. We augment the test
comments accordingly.
2014-06-27 18:07:33 +02:00
Pierre-Yves David
a5684d9c69 test-revert: add case where file exists neither in "base" nor in "parent" 2014-06-27 18:02:09 +02:00
Pierre-Yves David
35119be671 test-revert: add case where the file is removed between "base" and "parent" 2014-06-27 18:01:16 +02:00
Pierre-Yves David
545aab87fe test-revert: add case where file is unchanged between "base" and "parent"
This test highlights a minor misbehavior in the message displayed
during an explicit revert with a target revision.
2014-06-27 18:00:49 +02:00
Pierre-Yves David
beef5d2ab3 test-revert: add case where file is added between "base" and "parent" 2014-06-25 17:37:13 +01:00
Pierre-Yves David
4ab7864481 test-revert: add methodical revert to "base" with explicit file path
We now also test reverting file to another revision's content. However
this differs from previously introduced test by using the explicit path
of each "case file" when calling revert. This should result in the
same result regarding file content and backup creation, but the output
of the `hg revert` call should differ.
2014-06-25 17:31:53 +01:00
Pierre-Yves David
0665e42a28 test-revert: add methodical revert with explicit file path
We now also test reverting file to the working directory parent
content. However this differs from the previously introduced test by using
the explicit path of each "case file" when calling revert. This should
result in the same result regarding file content and backup creation,
but the output of the `hg revert` call should differ.
2014-06-25 17:22:47 +01:00
Pierre-Yves David
dd045fbbfb test-revert: add methodical revert to "base"
We now also test reverting s file to the content of another revision. This is
still done using the `--all` flag.
2014-06-25 17:16:05 +01:00
Pierre-Yves David
c6c8698534 test-revert: add methodical revert to parent for working directory
Now that we can automatically generate states, we need to actually run
revert on them and check the result. While running such tests we are
checking multiple elements. The output of the `hg revert` command, the
resulting content of file, and the creation of backup file.

The first practical test is using the simple case `hg revert --all`, reverting
all files to working directory parent content.
2014-06-25 17:03:55 +01:00
Pierre-Yves David
364e062c1b test-revert: display the list of all generated cases
This will help to track all existing cases.

(still very simple now)
2014-06-25 17:24:18 +01:00
Pierre-Yves David
fa7f47cb83 test-revert: also create a text version of the snapshot
The text version is just a list of existing files with their content. We use a
small custom script for that.

This is going to be very useful for comparing revert results with
revert target content.
2014-06-27 16:08:09 +02:00
Pierre-Yves David
8e229da2ce test-revert: prepare methodical testing of revert cases
We introduce a script to generate revert cases and use it to prepare a test
repo.  See the inline documentation for details.
2014-06-25 16:37:06 +01:00
Pierre-Yves David
a08806c922 test-revert: drop useless comments
There are multiple comments explaining the expected output of commands. This is
an old relic of the pre-unified test era. We remove them for uselessness.
2014-06-25 15:59:21 +01:00
Pierre-Yves David
5681b6942f test-revert: improve comment
We highlight the behavior tested by each sections. (This is a gratuitous
improvement before significant upgrade of the test and massive refactoring of
the revert code)
2014-06-25 15:58:05 +01:00
Pierre-Yves David
ca87e2a8ca revert: use p2 as parent when reverting against it
revert was always using p1 as parent. This created some minor misbehavior when
reverting against p2. See test change for an example of that.

This is also a useful cleanup for coming refactoring to revert.
2014-05-14 10:38:05 -07:00