--- a/hgext/fetch.py Mon Apr 23 01:39:26 2012 +0200
+++ b/hgext/fetch.py Sun Apr 22 20:30:36 2012 -0700
@@ -23,10 +23,9 @@
Otherwise, the working directory is updated to include the new
changes.
- When a merge occurs, the newly pulled changes are assumed to be
- "authoritative". The head of the new changes is used as the first
- parent, with local changes as the second. To switch the merge
- order, use --switch-parent.
+ When a merge is needed, the working directory is first updated to
+ the newly pulled changes. Local changes are then merged into the
+ pulled changes. To switch the merge order, use --switch-parent.
See :hg:`help dates` for a list of formats valid for -d/--date.
--- a/mercurial/bdiff.c Mon Apr 23 01:39:26 2012 +0200
+++ b/mercurial/bdiff.c Sun Apr 22 20:30:36 2012 -0700
@@ -339,10 +339,12 @@
struct line *al, *bl;
struct hunk l, *h;
int an, bn, len = 0, la, lb, count;
+ PyThreadState *_save;
if (!PyArg_ParseTuple(args, "s#s#:bdiff", &sa, &la, &sb, &lb))
return NULL;
+ _save = PyEval_SaveThread();
an = splitlines(sa, la, &al);
bn = splitlines(sb, lb, &bl);
if (!al || !bl)
@@ -361,6 +363,8 @@
la = h->a2;
lb = h->b2;
}
+ PyEval_RestoreThread(_save);
+ _save = NULL;
result = PyBytes_FromStringAndSize(NULL, len);
@@ -385,6 +389,8 @@
}
nomem:
+ if (_save)
+ PyEval_RestoreThread(_save);
free(al);
free(bl);
freehunks(l.next);
--- a/mercurial/merge.py Mon Apr 23 01:39:26 2012 +0200
+++ b/mercurial/merge.py Sun Apr 22 20:30:36 2012 -0700
@@ -110,10 +110,18 @@
folded[fold] = fn
if wctx:
+ # class to delay looking up copy mapping
+ class pathcopies(object):
+ @util.propertycache
+ def map(self):
+ # {dst@mctx: src@wctx} copy mapping
+ return copies.pathcopies(wctx, mctx)
+ pc = pathcopies()
+
for fn in wctx:
fold = util.normcase(fn)
mfn = folded.get(fold, None)
- if mfn and (mfn != fn):
+ if mfn and mfn != fn and pc.map.get(mfn) != fn:
raise util.Abort(_("case-folding collision between %s and %s")
% (mfn, fn))
@@ -568,7 +576,11 @@
action = []
folding = not util.checkcase(repo.path)
if folding:
- _checkcollision(p2, branchmerge and p1)
+ # collision check is not needed for clean update
+ if not branchmerge and force:
+ _checkcollision(p2, None)
+ else:
+ _checkcollision(p2, wc)
if not force:
_checkunknown(repo, wc, p2)
action += _forgetremoved(wc, p2, branchmerge)
--- a/mercurial/patch.py Mon Apr 23 01:39:26 2012 +0200
+++ b/mercurial/patch.py Sun Apr 22 20:30:36 2012 -0700
@@ -230,7 +230,7 @@
elif line.startswith("# Node ID "):
nodeid = line[10:]
elif line.startswith("# Parent "):
- parents.append(line[10:])
+ parents.append(line[9:].lstrip())
elif not line.startswith("# "):
hgpatchheader = False
elif line == '---' and gitsendmail:
--- a/tests/test-casecollision-merge.t Mon Apr 23 01:39:26 2012 +0200
+++ b/tests/test-casecollision-merge.t Sun Apr 22 20:30:36 2012 -0700
@@ -6,104 +6,204 @@
test for branch merging
################################
- $ hg init repo1
- $ cd repo1
-
-create base revision
+test for rename awareness of case-folding collision check:
- $ echo base > base.txt
- $ hg add base.txt
- $ hg commit -m 'base'
+(1) colliding file is one renamed from collided file:
+this is also case for issue3370.
-add same file in different case on both heads
+ $ hg init merge_renameaware_1
+ $ cd merge_renameaware_1
- $ echo a > a.txt
- $ hg add a.txt
- $ hg commit -m 'add a.txt'
-
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m '#0'
+ $ hg rename a tmp
+ $ hg rename tmp A
+ $ hg commit -m '#1'
$ hg update 0
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-
- $ echo A > A.TXT
- $ hg add A.TXT
- $ hg commit -m 'add A.TXT'
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo 'modified at #2' > a
+ $ hg commit -m '#2'
created new head
-merge another, and fail with case-folding collision
+ $ hg merge
+ merging a and A to A
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ hg status -A
+ M A
+ a
+ R a
+ $ cat A
+ modified at #2
+
+ $ hg update --clean 1
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg merge
+ merging A and a to A
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ hg status -A
+ M A
+ a
+ $ cat A
+ modified at #2
+
+ $ cd ..
+
+(2) colliding file is not related to collided file
+
+ $ hg init merge_renameaware_2
+ $ cd merge_renameaware_2
+
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m '#0'
+ $ hg remove a
+ $ hg commit -m '#1'
+ $ echo A > A
+ $ hg add A
+ $ hg commit -m '#2'
+ $ hg update --clean 0
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo 'modified at #3' > a
+ $ hg commit -m '#3'
+ created new head
$ hg merge
- abort: case-folding collision between a.txt and A.TXT
+ abort: case-folding collision between A and a
[255]
+ $ hg parents --template '{rev}\n'
+ 3
+ $ hg status -A
+ C a
+ $ cat a
+ modified at #3
-check clean-ness of working directory
-
- $ hg status
+ $ hg update --clean 2
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg merge
+ abort: case-folding collision between a and A
+ [255]
$ hg parents --template '{rev}\n'
2
+ $ hg status -A
+ C A
+ $ cat A
+ A
+
$ cd ..
+
################################
test for linear updates
################################
- $ hg init repo2
- $ cd repo2
+test for rename awareness of case-folding collision check:
-create base revision (rev:0)
+(1) colliding file is one renamed from collided file
+
+ $ hg init linearupdate_renameaware_1
+ $ cd linearupdate_renameaware_1
- $ hg import --bypass --exact - <<EOF
- > # HG changeset patch
- > # User null
- > # Date 1 0
- > # Node ID e1bdf414b0ea9c831fd3a14e94a0a18e1410f98b
- > # Parent 0000000000000000000000000000000000000000
- > add a
- >
- > diff --git a/a b/a
- > new file mode 100644
- > --- /dev/null
- > +++ b/a
- > @@ -0,0 +1,3 @@
- > +this is line 1
- > +this is line 2
- > +this is line 3
- > EOF
- applying patch from stdin
-
-create rename revision (rev:1)
-
- $ hg import --bypass --exact - <<EOF
- > # HG changeset patch
- > # User null
- > # Date 1 0
- > # Node ID 9dca9f19bb91851bc693544b598b0740629edfad
- > # Parent e1bdf414b0ea9c831fd3a14e94a0a18e1410f98b
- > rename a to A
- >
- > diff --git a/a b/A
- > rename from a
- > rename to A
- > EOF
- applying patch from stdin
-
-update to base revision, and modify 'a'
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m '#0'
+ $ hg rename a tmp
+ $ hg rename tmp A
+ $ hg commit -m '#1'
$ hg update 0
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ echo 'this is added line' >> a
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-update to current tip linearly
-
+ $ echo 'this is added line' >> a
$ hg update 1
merging a and A to A
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-
-check status and contents of file
-
$ hg status -A
M A
$ cat A
- this is line 1
- this is line 2
- this is line 3
+ a
this is added line
+
+ $ cd ..
+
+(2) colliding file is not related to collided file
+
+ $ hg init linearupdate_renameaware_2
+ $ cd linearupdate_renameaware_2
+
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m '#0'
+ $ hg remove a
+ $ hg commit -m '#1'
+ $ echo A > A
+ $ hg add A
+ $ hg commit -m '#2'
+
+ $ hg update 0
+ abort: case-folding collision between a and A
+ [255]
+ $ hg parents --template '{rev}\n'
+ 2
+ $ hg status -A
+ C A
+ $ cat A
+ A
+
+ $ hg update --check 0
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg parents --template '{rev}\n'
+ 0
+ $ hg status -A
+ C a
+ $ cat a
+ a
+
+ $ hg update --clean 2
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg parents --template '{rev}\n'
+ 2
+ $ hg status -A
+ C A
+ $ cat A
+ A
+
+ $ cd ..
+
+(3) colliding file is not related to collided file: added in working dir
+
+ $ hg init linearupdate_renameaware_3
+ $ cd linearupdate_renameaware_3
+
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m '#0'
+ $ hg rename a b
+ $ hg commit -m '#1'
+ $ hg update 0
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+ $ echo B > B
+ $ hg add B
+ $ hg status
+ A B
+ $ hg update
+ abort: case-folding collision between b and B
+ [255]
+
+ $ hg update --check
+ abort: uncommitted local changes
+ [255]
+
+ $ hg update --clean
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg parents --template '{rev}\n'
+ 1
+ $ hg status -A
+ C b
+ $ cat b
+ a
+
+ $ cd ..
--- a/tests/test-impexp-branch.t Mon Apr 23 01:39:26 2012 +0200
+++ b/tests/test-impexp-branch.t Sun Apr 22 20:30:36 2012 -0700
@@ -1,3 +1,6 @@
+ $ echo '[extensions]' >> $HGRCPATH
+ $ echo 'mq =' >> $HGRCPATH
+
$ cat >findbranch.py <<EOF
> import re, sys
>
@@ -55,3 +58,14 @@
applying ../r0.patch
$ hg import --exact ../r1.patch
applying ../r1.patch
+
+Test --exact and patch header separators (issue3356)
+
+ $ hg strip --no-backup .
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ >>> import re
+ >>> p = file('../r1.patch', 'rb').read()
+ >>> p = re.sub(r'Parent\s+', 'Parent ', p)
+ >>> file('../r1-ws.patch', 'wb').write(p)
+ $ hg import --exact ../r1-ws.patch
+ applying ../r1-ws.patch