Commit Graph

380 Commits

Author SHA1 Message Date
Matt Mackall
3d60dfdd1c merge with stable 2011-11-30 17:15:39 -06:00
Benoit Allard
f3be9c5304 diff: '\ No newline at end of file' is also not part of the header
Diff containing '\ No newline at end of file' were colorized incorrectly.
2011-11-29 19:51:35 +01:00
Nicolas Venegas
2582d1e3d9 mdiff/patch: fix bad hunk handling for unified diffs with zero context
Prior to this patch "hg diff -U0", i.e., zero lines of context, would
output hunk headers with a start line one greater than what GNU patch
and git output. Guido van Rossum documents the unified diff format[1]
as having a start line value "one lower than one would expect" for
zero length hunks.

Comparing the behaviour of the three systems prior to this patch in
transforming

  c1
  c3

to

  c1
  c2
  c3

- GNU "diff -U0" reports the hunk as "@@ -1,0 +2 @@"
- "git diff -U0" reports the hunk as "@@ -1,0 +2 @@"
- "hg diff -U0" reports the hunk as "@@ -2,0 +2,1 @@"

After this patch, "hg diff -U0" reports "@@ -1,0 +2,1 @@".

Since "hg export --config diff.unified=0" outputs zero-context unified
diffs, "hg import" has also been updated to account for start lines
one less than expected for zero length hunk ranges.

[1]: http://www.artima.com/weblogs/viewpost.jsp?thread=164293
2011-11-09 16:55:59 -08:00
Patrick Mezard
cc3315778f annotate: support diff whitespace filtering flags (issue3030)
splitblock() was added to handle blocks returned by bdiff.blocks() which differ
only by blank lines but are not made only of blank lines. I do not know exactly
how it could happen but mdiff.blocks() threshold behaviour makes me think it
can if those blocks are made of very popular lines mixed with popular blank
lines. If it is proven to be wrong, the function can be dropped.

The first implementation made annotate share diff configuration entries. But it
looks like users will user -w/b for annotate but not for diff, on both the
command line and hgweb. Since the latter cannot use command line entries, we
introduce a new [annotate] section duplicating the diff whitespace options.
2011-11-18 12:04:31 +01:00
Patrick Mezard
31705153e3 patch: simplify hunk extents parsing
Do not capture unwanted groups in regexps
2011-11-14 18:16:01 +01:00
Patrick Mezard
1e1f58f358 diffstat: be more picky when marking file as 'binary' (issue2816)
The 'Bin' marker was added to every changed file for which we could not find
any diff changes. This included binary files but also copy/renames and mode
changes. Since Mercurial regular diff format emits a 'Binary file XXX has
changed' line when fed with binary files, we use that and the usual git marker
to tell them from other cases. In particular, new empty files are no longer
reported as binary.

Still, this fix is not complete since copy/renames/mode changes are now
reported as '0' lines changes, instead of 'Bin'.
2011-10-24 13:41:19 +02:00
Kirill Elagin
a331869573 diff: enhance highlighting with color (issue3034)
Now the highlighter knows whether it is in the header of the patch or not.
2011-10-05 09:20:38 +03:00
Matt Mackall
e538620d00 merge with stable 2011-09-27 18:50:18 -05:00
Steffen Daode Nurpmeso
f5ba5be1a8 patch: correctly handle non-tabular Subject: line
The line content of continued Subject: lines was yet joined via
str.replace('\n\t', ' '), which does not handle continuation via
spaces.  So expan the regular expression instead to
handle all allowed forms of mail header line continuation.
2011-09-27 18:41:09 -05:00
Dan Villiom Podlaski Christiansen
c5a1d45b09 patch: handle 'gitpatches' being empty, but not none 2011-09-11 18:49:41 +02:00
Matt Mackall
af293bcf51 merge with stable 2011-09-12 23:02:45 -05:00
Wagner Bruna
56657ac28b patch: fix parsing patch files containing CRs not followed by LFs
Since 75e6e3c16f9c , patch lines containing a CR not followed by a LF
would be incorrectly splitten, causing a failure to apply the patch.
2011-07-04 19:53:39 -03:00
Thomas Arendsen Hein
692a53d202 classes: fix class style problems found by 06e968819ac9
This makes test-wireprotocol.py work on Python 2.4
2011-06-29 15:00:00 +02:00
Peter Arrenbrecht
97a6442c24 patch: fix typo in variable name 2011-06-20 09:30:03 +02:00
Patrick Mezard
86e3700676 patch: make filestore store data in memory and fallback to fs 2011-06-17 20:33:02 +02:00
Patrick Mezard
fd8786d770 import: add --bypass option
This feature is more a way to test patching without a working directory than
something people asked about. Adding a --rev option to specify the parent patch
revision would make it a little more useful.

What this change introduces is patch.repobackend class which let patches be
applied against repository revisions. The caller must supply a filestore object
to receive patched content, which can be turned into a memctx with
patch.makememctx() helper.
2011-06-14 23:26:35 +02:00
Patrick Mezard
9a9794b348 patch: extend filtestore to store an optional copy source
This will help wrapping filestores in memctx.
2011-06-14 23:24:34 +02:00
Patrick Mezard
3680e66462 patch: generalize the use of patchmeta in applydiff()
- Add patchmeta.copy() and emit copies from iterhunks. Modifying patchmeta
  instances in applydiff() makes things simpler.
- Rename selectfile() into makepatchmeta(). It is responsible for creating
  patchmeta for regular patches.
- Pass patchmeta objects to patchfile() directly

patchmeta instances were associated with git patches, for regular patches we
had to pass additional variables to tell the patch intent to patchfile().
Instead, we generate patchmeta for regular patches and pass them. This will
also help with patch filtering by matcher objects.
2011-06-11 14:17:25 +02:00
Patrick Mezard
c72a5b0080 patch: stop updating changed files set in applydiff()
This information is more correctly returned by backends.

The extra updated file removed from test-mq-merge.t output came from changes
from git patches being counted before being really applied in some cases.
2011-06-11 14:14:13 +02:00
Patrick Mezard
6aaca90508 patch: turn patch() touched files dict into a set 2011-06-11 14:14:11 +02:00
Patrick Mezard
7acb34dda5 patch: dot not ignore hunk of files marked as 'deleted'
git 'deleted' flag was processed unconditionnally and the file removed even if
the related hunk was not matching.
2011-06-05 22:26:01 +02:00
Patrick Mezard
f3d2dd1ca2 patch: fix patchmeta/hunk synchronization in iterhunks()
Synchronizing on bfile does not work on file removal where bfile is /dev/null.
We match items on afile or bfile instead. The incorrect code makes iterhunks()
to emit patchmeta and hunks separately in some cases. This is currently hidden
by applydiff() being too tolerant when processing patchmeta, and will be fixed
later.
2011-06-05 22:24:19 +02:00
Patrick Mezard
fc7fde3949 patch: remove unnecessary exists() call in selectfile() 2011-06-05 22:24:11 +02:00
Patrick Mezard
62588fedca patch: remove redundant islink() call 2011-06-05 13:27:06 +02:00
Martin Geisler
af8a35e078 check-code: flag 0/1 used as constant Boolean expression 2011-06-01 12:38:46 +02:00
Patrick Mezard
ab82a700d3 patch: do not patch unknown files (issue752) 2011-05-27 21:50:11 +02:00
Patrick Mezard
d4b7db6294 patch: use temporary files to handle intermediate copies
git patches may require copies to be handled out-of-order. For instance, take
the following sequence:

  * modify a
  * copy a into b

Here, we have to generate b from a before its modification. To do so,
applydiff() was scanning for copy metadata and performing the copies before
processing the other changes in-order. While smart and efficient, this approach
complicates things by handling file copies and file creations at different
places and times. While a new file must not exist before being patched a copied
file already exists before applying the first hunk.

Instead of copying the files at their final destination before patching, we
store them in a temporary file location and retrieve them when patching. The
filestore always stores file content in real files but nothing prevents adding
a cache layer. The filestore class was kept separate from fsbackend for at
least two reasons:

- This class is likely to be reused as a temporary result store for a future
  repository patching call (entries just have to be extended to contain copy
  sources).

- Delegating this role to backends might be more efficient in a repository
  backend case: the source files are already available in the repository itself
  and do not need to be copied again. It also means that third-parties backend
  would have to implement two other methods. If we ever decide to merge the
  filestore feature into backend, a minimalistic approach would be to compose
  with filestore directly. Keep in mind this copy overhead only applies for
  copy/rename sources, and may even be reduced to copy sources which have to
  handled ahead of time.
2011-05-27 21:50:10 +02:00
Patrick Mezard
e6f284be06 patch: refactor file creation/removal detection
The patcher has to know if a file is being created or removed to check if the
target already exists, or to actually unlink the file when a hunk emptying it
is applied. This was done by embedding the creation/removal information in the
first (and only) hunk attached to the file.

There are two problems with this approach:

- creation/removal is really a property of the file being patched and not its
  hunk.

- for regular patches, file creation cannot be deduced at parsing time: there
  are case where the *stripped* file paths must be compared. Modifying hunks
  after their creation is clumsy and prevent further refactorings related to
  copies handling.

Instead, we delegate this job to selectfile() which has all the relevant
information, and remove the hunk createfile() and rmfile() methods.
2011-05-27 21:50:09 +02:00
Steven Brown
b13eee65a4 patch: restore the previous output of 'diff --stat'
Restore the previous diffstat behaviour of scaling by the maximum number of
changes to a single file. Changeset 7bb0e22a7988 modified the diffstat to be
scaled by the total number of changes. This seems to have been unintentional.
2011-05-26 22:51:02 +08:00
Matt Mackall
c6e850b04b context: make forget work like commands.forget
Switch users of wctx.delete(..., False) to forget.
2011-05-26 17:15:35 -05:00
Patrick Mezard
32250cd067 patch: remove EOL support from linereader class
This was only used when reading patched files which is now done by backends.
2011-05-24 14:21:04 +02:00
Matt Mackall
6af03bc2e8 patch: use diffstatsum in diffstat 2011-05-21 15:06:38 -05:00
Matt Mackall
7560e9a576 patch: add diffstatsum helper 2011-05-21 15:06:36 -05:00
Matt Mackall
898e0ce783 diffstatdata: no longer a generator
This produces a smallish amount of data and all consumers needed to
buffer it anyway.
2011-05-21 15:01:28 -05:00
Patrick Mezard
272081b65d patch: fast-path git case in selectfile()
We avoid a lot of complicated heuristics in git cases, where these heurestics
may even be broken when copies are involved.
2011-05-19 22:55:13 +02:00
Patrick Mezard
a09607c9ee patch: unify backend file access interface
- Rename readlines() into getfile(), return data and mode
- Make setfile() write a data buffer instead of lines, make mode mandatory.
2011-05-19 22:49:43 +02:00
Patrick Mezard
701e9571f9 patch: merge backend setmode() into writelines()
Copy handling will be easier to handle in a single method.
2011-05-19 22:44:01 +02:00
Patrick Mezard
15861c0232 patch: stop modifying gitpatch objects
gitpatch objects emitted by iterhunks() were referencing file paths unmodified
from the input patch. _applydif() made them usable by modifying the gitpatch
objects in-place with specified path strip level. The same modified objects
were then reused by iterhunks() generator. _applydiff() now copies and update
the paths which completely decouples both routines.

As a side effect, the "git" event now receives only metadata about
copies/renames to perform the necessary copies ahead of time. Other actions are
handled in the "file" event.
2011-05-19 22:44:01 +02:00
Patrick Mezard
3246b5c773 patch: stop handling hunkless git blocks out of stream
Patch changes are emitted by iterhunks() in two separate events: 'file' when
hunks have to be applied and 'git' to describe other modifications like copies
or mode changes. Note that a file which mode is changed and which content is
modified by the same patch will be emitted in both events. It is more
convenient to handle all file modifications in a single event. This patch
"zips" git actions with regular changes so both kinds can be emitted at the
same place.
2011-05-19 22:44:01 +02:00
Patrick Mezard
ac0634bc33 patch: reindent code 2011-05-19 22:44:01 +02:00
Patrick Mezard
ac6f56515a patch: unify iterhunks() afile/bfile handling
git afile/bfile are extracted twice, once when reading a 'diff --git', and
again when reading a unified hunk. The problem is not all git blocks have
unified hunks (renames just have metadata) and they were not extracted the same
way. This is what this patch unifies.
2011-05-19 22:44:01 +02:00
Patrick Mezard
f8df1dcc42 patch: git metadata was ignored if strip > 1
gitpatch objects emitted by iterhunks() are modified in place by applydiff().
Processing them earlier improves iterhunks() isolation. applydiff() modifying
them should still be fixed though.
2011-05-19 22:44:01 +02:00
Patrick Mezard
68fd0dcbe7 patch: construct and parse binary hunks at the same time 2011-05-19 22:44:01 +02:00
Patrick Mezard
452fad17b8 patch: refactor iterhunks() regular and binary files emission 2011-05-19 22:44:01 +02:00
Patrick Mezard
78738c3822 patch: remove patch.patch() cwd argument 2011-05-19 22:44:01 +02:00
Patrick Mezard
6d4d079b0e patch: merge _updatedir() into externalpatch() 2011-05-19 22:44:01 +02:00
Patrick Mezard
2bda8cbde2 patch: add a workingbackend dirstate layer on top of fsbackend
_updatedir() is no longer used by internalpatch()

The change in test-mq-missingfiles.t comes from workingbackend not considering
the missing 'b' file as changed, thus not calling addremove() on it.
2011-05-18 23:48:17 +02:00
Patrick Mezard
34a629b9c0 patch: handle binary copies as regular ones
This introduces a performance regression for large files, as they will be
copied just to be clobbered afterwards since binary patching does not use
deltas.  But it simplifies the code and the previous optimization will be
reintroduced later in a better way.
2011-05-18 23:48:13 +02:00
Patrick Mezard
18202a57db patch: remove files while patching, not in updatedir()
At this point, updatedir() only reads the working directory and update the
dirstate.
2011-05-18 23:48:13 +02:00
Patrick Mezard
514ff73602 patch: set desired mode when patching, not in updatedir()
This patch and the following aim at merging _updatedir() actions into
_applydiff().
2011-05-18 23:48:13 +02:00