Commit Graph

12 Commits

Author SHA1 Message Date
FUJIWARA Katsunori
b3a7702a57 record: omit meaningless 'commit' suggestion at 'hg commit -i'
Before this patch, 'hg commit -i' under non-interactive mode suggests
'use commit instead', and it obviously meaningless.

This patch makes 'record.record'()' examine 'ui.interactive()' and
show suggestion by itself before calling 'commands.commit()'.

This allows 'commands.commit()' to specify 'None' for 'cmdsuggest'
argument of 'cmdutil.dorecord()' to omit meaningless 'commit'
suggestion at 'hg commit -i'.
2015-07-15 04:45:58 +09:00
FUJIWARA Katsunori
ec0ec0f1d2 cmdutil: apply dirstate.normallookup on (maybe partially) committed files
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                                              ***   ***
       - change "f"                                     N

       - execute 'hg commit -i'
         - backup "f" with timestamp N
         - revert "f" by 'merge.update()'               N
           with 'partially'
         - apply selected hunks                         N
           by 'patch.patch()'

         - 'repo.commit()'
           - 'dirstate.normal("f")'         N
  N+1
           - 'dirstate.write()'             N    N

         - restore "f"                                  N+1
         - restore timestamp of "f"                     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.

This issue can occur when 'hg commit -i' satisfies conditions below:

  - the file is committed partially, and
  - mode and size of the file aren't changed before and after committing

The root cause of this issue is that (maybe partially changed) files
are restored with original timestamp but dirstate isn't updated for
them.

To detect changes of files correctly, this patch applies
'dirstate.normallookup()' on restored files. Status check is needed
before 'dirstate.normallookup()', because status other than "n(ormal)"
should be kept at failure of committing.

This patch doesn't examine whether each files are committed fully or
partially, because interactive hunk selection makes it difficult.

After this change, timetable is changed as below:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
  N                                              ***   ***
       - change "f"                                     N

       - execute 'hg commit -i'
         - backup "f" with timestamp N
         - revert "f" by 'merge.update()'               N
           with 'partially'
         - apply selected hunks                         N
           by 'patch.internalpatch()'

         - 'repo.commit()'
           - 'dirstate.normal("f")'         N
  N+1
           - 'dirstate.write()'             N    N

         - restore "f"                                  N+1
         - restore timestamp of "f"                     N
       ----------------------------------- ---- ----- -----
         - normallookup("f")                -1
         - release wlock
           - 'dirstate.write()'             -1   -1     N
       ----------------------------------- ---- ----- -----

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

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

  - change "f" at N

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

  - apply selected hunks at N

    'patch.internalpatch()' with 'fakepatchtime.py' explicitly changes
    mtime of patched files to "2000-01-01 00:00" (= N).

  - 'dirstate.write()' at N+1 (or "not at N")

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

BTW, in 'test-commit-interactive.t', files are sometimes treated as
modified , even though they are just committed fully via 'hg commit
-i' and 'hg diff' shows nothing for them.

Enabling win32text causes EOL style mismatching below:

  - files are changed in LF style EOL

    => files restored after committing uses LF style EOL (1)

  - 'merge.update()' reverts files in CRLF style EOL
  - 'patch.internalpatch()' changes files in CRLF style EOL

    => 'dirstate.normal()' via 'repo.commit()' uses the size of files
       in CRLF style EOL (2)

Therefore, fully committed files are treated as "modified", because
'lstat()' returns size of (1) restored files in LF style EOL, but
dirstate expects size of (2) committed files in CRLF style EOL.

After this patch, 'dirstate.normallookup()' on committed files forces
subsequent 'hg status' to examine changes exactly, and fully committed
files are treated as clean as expected.

This is reason why this patch also does:

  - add some 'hg status' checking status of fully committed files
  - clear win32text configuration before size/timestamp sensitive examination
2015-07-08 17:07:45 +09:00
Laurent Charignon
1ca77932d5 record: exiting editor with non-zero status should not stop recording session
Before this patch, exiting a hunk edit in record with a non-zero status lead
to the end of the recording session, losing previously-selected hunks to record.
This patch introduces the more desirable behavior of warning the user and
continuing the recording session.
2015-06-05 13:31:18 -07: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
Matt Harbison
40ef0473bf test-commit-interactive: add more globs for no-execbit platforms
The ability to set the exec bit on Windows would be real handy for this test..
2015-04-29 23:55:25 -04:00
Laurent Charignon
a76105b65c record: fix adding new file with record from within a subdir (issue4626)
In my latest change on record (edit newly added file), I forgot the
repo.wjoin() so that record was not computing the paths properly to delete
the backups and was crashing.
2015-04-27 14:02:49 -07:00
Matt Harbison
30dc79b90c test-commit-interactive: stablize output for no-execbit platforms 2015-04-26 15:13:13 -04:00
Laurent Charignon
6fc9e8be66 record: edit patch of newly added files (issue4304)
I tried to fix this issue in the past and had to revert the fix. This is a
second attempt without the regression we found with the first one.

record defines special headers (of file) as headers whose hunk are not shown
to the user for editing, they are used to represent deleted, moved and new
files. Since we want to authorize editing the patch of newly added file we
make the newly added file with some content not special anymore. This entails
that we have to save their content before applying the backup to be able to
revert it if the patch does not apply properly.
We reintroduce the test showing that newly added files can be edited and that
their content is shown to the user.
2015-04-23 14:27:26 -07:00
Laurent Charignon
ec981b8835 record: remove useless line in test
Remove a useless line in test to make the next patch cleaner.
2015-04-23 16:59:11 -07:00
Laurent Charignon
4fc3c4c465 record: fix record with change on moved file crashes (issue4619)
reverting fe807064739c, add a test to prevent the issue from coming back.
2015-04-22 13:56:30 -07:00
Laurent Charignon
f6c2e64e0a record: add new tests for commit interactive (same tests as record) 2015-03-11 15:22:34 -07:00