For divergent renames the following message is printed during merge:
note: possible conflict - file was renamed multiple times to:
newfile
file2
When a file is renamed in one branch and deleted in the other, the file still
exists after a merge. With this change a similar message is printed for mv+rm:
note: possible conflict - file was deleted and renamed to:
newfile
We allow rebase plus collapse, but not collapse only? I imagine people would
rebase first then collapse once they are sure the rebase is correct and it is
the right time to finish it.
I was reluctant to submit this patch for reasons detailed below, but it
improves rebase --collapse usefulness so much it is worth the ugliness.
The fix is ugly because we should be fixing the collapse code path rather than
the merge. Collapsing by merging changesets repeatedly is inefficient compared
to what commit --amend does: commitctx(), update, strip. The problem with the
latter is, to generate the synthetic changeset, copy records are gathered with
copies.pathcopies(). copies.pathcopies() is still implemented with merging in
mind and discards information like file replaced by the copy of another,
criss-cross copies and so forth. I believe this information should not be lost,
even if we decide not to interpret it fully later, at merge time.
The second issue with improving rebase --collapse is the option should not be
there to begin with. Rebasing and collapsing are orthogonal and a dedicated
command would probably enable a better, simpler ui. We should avoid advertizing
rebase --collapse, but with this fix it becomes the best shipped solution to
collapse changesets.
And for the record, available techniques are:
- revert + commit + strip: lose copies
- mq/qfold: repeated patching() (mostly correct, fragile)
- rebase: repeated merges (mostly correct, fragile)
- collapse: revert + tag rewriting wizardry, lose copies
- histedit: repeated patching() (mostly correct, fragile)
- amend: copies.pathcopies() + commitctx() + update + strip
The fix introduced in 3509b9cf8f86 was only partially successful. It is correct
to turn dirstate 'm' merge records into normal/dirty ones but copy records are
lost in the process. To adjust them as well, we need to look in the first
parent manifest to know which files were added and preserve only related
records. But the dirstate does not have access to changesets, the logic has to
moved at another level, in localrepo.
a317664437ee introduced some logic to avoid case-collision detection between
source and destination revisions when it does not make sense: clean or to be
cleaned working directories. Unfortunately, part of it was flawed and the
related test was broken by another bug.
This patch disables cross revision case collision detection for updates without
option or with --check, if the working directory is clean.
if the file in target context causes case-folding collision against
one in working context, current implementation aborts merging with it,
even thouhg collding one (in target) is the file renamed from collided
one (in working).
this patch uses file copy information to know whether colliding file
is renamed from collided one or not: if so, collision between them is
ignored.
this patch also avoids collision detection between current context and
target context, if working context is clean (with --check/-c) or will
be clean (with --clean/-C).
This fixes a regression introduced by df049e784ab6. If no file-level
merge is needed, we can update flags directly, otherwise we have a
conflict to resolve in filemerge.
Previously, we could change a normal file into a corrupt symlink when
trying to merge a symlink flag. Now, we leave the flag alone and let
filemerge deal with it (usually by a prompt).
We also drop a redundant flag setting after filemerge (now dealt with
by ms.resolve) that would cause similar corruption.
The unknown file collision rule was introduced as an extension of the
"should be clean when merging" rule. Unfortunately, it got applied to
the normal update path, which should be happy to merge local changes.
This patch gives us merges for unknown file collisions on update,
while preserving abort for merge and update -c.
This removes use of unknown files for building the synthetic working
directory manifest used by manifestmerge. Instead, we adopt the
strategy used by _checkunknown.
Side-effect: unknown files are no longer moved by remote directory
renames, and now are left alone like ignored files.
Previously, we would do a full working directory walk including
unknown files to perform a merge. In many cases, this was painful
because unknown files greatly outnumbered tracked files and generally
had no useful effect on the merge.
Here we instead wait until we find a file in the destination that's
not tracked locally and detect if it exists and is not ignored. This
is usually cheaper but can be -more- expensive in the case where we're
adding a huge number of files. On the other hand, the cost of statting
the new files should be dwarfed by the cost of eventually writing
them.
In this version, case collisions are detected implicitly by
os.path.exists and wctx[f] lookup.
When doing hg up, if there is a file conflict with untracked files,
currently only the first such conflict is reported. With this patch,
all of them are listed.
With this patch error message is now reported as
a: untracked file differs
b: untracked file differs
abort: untracked files in working directory conflict with files in
requested revision
instead of
abort: untracked file in working directory differs from file in
requested revision: 'a'
This is a follow up to an old attempt to do this here:
http://selenic.com/pipermail/mercurial-devel/2011-August/033625.html
this patch makes branch merging abort when merged changesets have same
file in different case on case insensitive filesystem.
this patch does not prevent linear update which merges between target
and working contexts, because 'branchmerge' is False in such case.
Makes the 'nothing to merge' abort messages in commands.py consistent with
those in merge.py. Also makes commands.merge() and merge.update() use hints.
The tests show the changes.
Some character sets, cp932 (known as Shift-JIS for Japanese) for
example, use 0x41('A') - 0x5A('Z') and 0x61('a') - 0x7A('z') as second
or later character.
In such character set, case collision checking recognizes different
files as CASEFOLDED same file, if filenames are treated as byte
sequence.
win32mbcs extension is not appropriate to handle this problem, because
this problem can occur on other than Windows platform only if
problematic character set is used.
Callers of util.checkcase() use known ASCII filenames as last
component of path, and string.lower() is not applied to directory part
of path. So, util.checkcase() is kept intact, even though it applies
string.lower() to filenames.
merge.update() was missing a few dirtiness checks from workingcontext,
including subrepo cleanliness checks. Using wc.dirty() instead of
one-off checks for various forms of dirtiness will be significantly
safer.
Previously, pull would not update if new branch heads were received,
whereas pull && update would move to the tipmost branch head.
Also change the "crosses branches" abort in merge.update from
"crosses branches (merge branches or use --check to force update)"
to
"crosses branches (merge branches or update --check to force update)"
since it can no longer assume the user is running hg update.
It has substantially different semantics from forget at the command
layer, so change it to avoid confusion.
We can't simply combine it with remove because we need to explicitly
drop non-added files in some cases like commit.
The Mercurial 1.9 release is moving a lot of stuff around anyway and we are
already moving path_auditor from util.py to scmutil.py for that release.
So this seems like a good opportunity to do such a rename. It also strengthens
the current project policy to avoid underbars in names.
These leaks may occur in environments that don't employ a reference
counting GC, i.e. PyPy.
This implies:
- changing opener(...).read() calls to opener.read(...)
- changing opener(...).write() calls to opener.write(...)
- changing open(...).read(...) to util.readfile(...)
- changing open(...).write(...) to util.writefile(...)
This backs out
changeset: 13158:17d1b96c0f12
user: Mads Kiilerich <mads@kiilerich.com>
date: Tue Dec 07 03:29:21 2010 +0100
summary: merge: fast-forward merge with descendant
Before named branches, the invariants were:
a) "merges" always have two parents
b) p1 is not linearly related to p2
Adding named branches made (b) problematic, so the above patch was
introduced, which fixed (b) but broke (a).
After discussion, we decided that the invariants should be:
a) "merges" always have two parents
b) p1 is not linearly related to p2 OR p1 and p2 are on different branches
Add missing calls to close() to many places where files are
opened. Relying on reference counting to catch them soon-ish is not
portable and fails in environments with a proper GC, such as PyPy.