mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 09:17:30 +03:00
eb2814985f
Summary: This basically takes the last upstream version of my conflictinfo patch and makes it an extension, so we can get it out to FB/Nuclide users a bit faster. @asriram has already been developing with this version as a personal extension for a couple of weeks. I still plan to ship the upstream version through after the freeze ends -- when that happens, we can delete this extension. During the time the two versions overlap, they shouldn't conflict. (The extension version will still run over the internal version until it's disabled, though.) Review-wise, this is similar to the last upstream version, except it adds the "command" key that indicates which command generated the conflicts (based on which mutually-exclusive state file exists), and incorporates most of the feedback. Test Plan: Added a test and ran associated tests. Reviewers: #mercurial, rmcelroy Reviewed By: rmcelroy Subscribers: rmcelroy, asriram, mjpieters Differential Revision: https://phabricator.intern.facebook.com/D4944709 Signature: t1:4944709:1493148790:a4e798f5bd17ada767ae6c96fe8c8ab973960383
690 lines
22 KiB
Perl
690 lines
22 KiB
Perl
1) Make the repo
|
|
$ mkdir basic
|
|
$ cd basic
|
|
$ hg init
|
|
$ . $TESTDIR/require-ext.sh conflictinfo
|
|
$ cat >> .hg/hgrc <<EOF
|
|
> [extensions]
|
|
> conflictinfo=
|
|
> EOF
|
|
|
|
2) Can't run dumpjson outside a conflict
|
|
$ hg resolve --tool internal:dumpjson
|
|
abort: no files or directories specified
|
|
(use --all to re-merge all unresolved files)
|
|
[255]
|
|
|
|
3) Make a simple conflict
|
|
$ echo "Unconflicted base, F1" > F1
|
|
$ echo "Unconflicted base, F2" > F2
|
|
$ hg commit -Aqm "initial commit"
|
|
$ echo "First conflicted version, F1" > F1
|
|
$ echo "First conflicted version, F2" > F2
|
|
$ hg commit -m "first version, a"
|
|
$ hg bookmark a
|
|
$ hg checkout .~1
|
|
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
(leaving bookmark a)
|
|
$ echo "Second conflicted version, F1" > F1
|
|
$ echo "Second conflicted version, F2" > F2
|
|
$ hg commit -m "second version, b"
|
|
created new head
|
|
$ hg bookmark b
|
|
$ hg log -G -T '({rev}) {desc}\nbookmark: {bookmarks}\nfiles: {files}\n\n'
|
|
@ (2) second version, b
|
|
| bookmark: b
|
|
| files: F1 F2
|
|
|
|
|
| o (1) first version, a
|
|
|/ bookmark: a
|
|
| files: F1 F2
|
|
|
|
|
o (0) initial commit
|
|
bookmark:
|
|
files: F1 F2
|
|
|
|
$ hg merge a
|
|
merging F1
|
|
merging F2
|
|
warning: conflicts while merging F1! (edit, then use 'hg resolve --mark')
|
|
warning: conflicts while merging F2! (edit, then use 'hg resolve --mark')
|
|
0 files updated, 0 files merged, 0 files removed, 2 files unresolved
|
|
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
|
|
[1]
|
|
|
|
5) Get the paths:
|
|
$ hg resolve --tool internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "merge",
|
|
"conflicts": [{"base": {"contents": "Unconflicted base, F1\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "Second conflicted version, F1\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "First conflicted version, F1\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "\u003c\u003c\u003c\u003c\u003c\u003c\u003c working copy: 13124abb51b9 b - test: second version, b\nSecond conflicted version, F1\n=======\nFirst conflicted version, F1\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e merge rev: 6dd692b7db4a a - test: first version, a\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/basic/F1"}, "path": "F1"}, {"base": {"contents": "Unconflicted base, F2\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "Second conflicted version, F2\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "First conflicted version, F2\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "\u003c\u003c\u003c\u003c\u003c\u003c\u003c working copy: 13124abb51b9 b - test: second version, b\nSecond conflicted version, F2\n=======\nFirst conflicted version, F2\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e merge rev: 6dd692b7db4a a - test: first version, a\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/basic/F2"}, "path": "F2"}]
|
|
}
|
|
]
|
|
|
|
6) Only requested paths get dumped
|
|
$ hg resolve --tool internal:dumpjson F2
|
|
[
|
|
{
|
|
"command": "merge",
|
|
"conflicts": [{"base": {"contents": "Unconflicted base, F2\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "Second conflicted version, F2\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "First conflicted version, F2\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "\u003c\u003c\u003c\u003c\u003c\u003c\u003c working copy: 13124abb51b9 b - test: second version, b\nSecond conflicted version, F2\n=======\nFirst conflicted version, F2\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e merge rev: 6dd692b7db4a a - test: first version, a\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/basic/F2"}, "path": "F2"}]
|
|
}
|
|
]
|
|
|
|
7) Ensure the paths point to the right contents:
|
|
$ getcontents() { # Usage: getcontents <path> <version>
|
|
> local script="import sys, json; print json.load(sys.stdin)[0][\"conflicts\"][$1][\"$2\"][\"contents\"]"
|
|
> local result=`hg resolve --tool internal:dumpjson --all | python -c "$script"`
|
|
> echo "$result"
|
|
> }
|
|
$ echo `getcontents 0 "base"`
|
|
Unconflicted base, F1
|
|
$ echo `getcontents 0 "other"`
|
|
First conflicted version, F1
|
|
$ echo `getcontents 0 "local"`
|
|
Second conflicted version, F1
|
|
$ echo `getcontents 1 "base"`
|
|
Unconflicted base, F2
|
|
$ echo `getcontents 1 "other"`
|
|
First conflicted version, F2
|
|
$ echo `getcontents 1 "local"`
|
|
Second conflicted version, F2
|
|
|
|
Tests merge conflict corner cases (file-to-directory, binary-to-symlink, etc.)
|
|
"other" == source
|
|
"local" == dest
|
|
|
|
Setup
|
|
$ cd ..
|
|
$ rm -rf basic
|
|
$ mkdir cornercases
|
|
$ cd cornercases
|
|
$ cat >> $HGRCPATH <<EOF
|
|
> [extensions]
|
|
> rebase=
|
|
> conflictinfo=
|
|
> EOF
|
|
|
|
$ reset() {
|
|
> rm -rf foo
|
|
> mkdir foo
|
|
> cd foo
|
|
> hg init
|
|
> echo "base" > file
|
|
> hg commit -Aqm "base"
|
|
> }
|
|
$ logg() {
|
|
> hg log -G -T '({rev}) {desc}\naffected: {files}\ndeleted: {file_dels}\n\n'
|
|
> }
|
|
|
|
Test case 0: A merge of just contents conflicts (not usually a corner case),
|
|
but the user had local changes and ran `merge -f`.
|
|
|
|
tldr: Since we can premerge, the working copy is backed up to an origfile.
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 0
|
|
$ echo "other change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 1
|
|
$ logg
|
|
o (2) source
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| @ (1) dest
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
$ echo "some local changes" > file
|
|
$ hg merge 2 -f
|
|
merging file
|
|
warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
|
|
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
|
|
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
|
|
[1]
|
|
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "merge",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "some local changes\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "other change\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "\u003c\u003c\u003c\u003c\u003c\u003c\u003c working copy: fd7d10c36158 - test: dest\nsome local changes\n=======\nother change\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e merge rev: 9b65ba2922f0 - test: source\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
|
|
Test case 0b: Like #0 but with a corner case: source deleted, local changed
|
|
*and* had local changes using merge -f.
|
|
|
|
tldr: Since we couldn't premerge, the working copy is left alone.
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 0
|
|
$ hg rm file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 1
|
|
$ logg
|
|
o (2) source
|
|
| affected: file
|
|
| deleted: file
|
|
|
|
|
| @ (1) dest
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
$ echo "some local changes" > file
|
|
$ chmod +x file
|
|
$ hg merge 2 -f
|
|
local [working copy] changed file which other [merge rev] deleted
|
|
use (c)hanged version, (d)elete, or leave (u)nresolved? u
|
|
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
|
|
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
|
|
[1]
|
|
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "merge",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "some local changes\n", "exists": true, "isexec": true, "issymlink": false}, "other": {"contents": null, "exists": false, "isexec": null, "issymlink": null}, "output": {"contents": "some local changes\n", "exists": true, "isexec": true, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
|
|
Test case 1: Source deleted, dest changed
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 0
|
|
$ hg rm file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 1
|
|
$ logg
|
|
o (2) source
|
|
| affected: file
|
|
| deleted: file
|
|
|
|
|
| @ (1) dest
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 1 -s 2
|
|
rebasing 2:25c2ef28f4c7 "source" (tip)
|
|
local [dest] changed file which other [source] deleted
|
|
use (c)hanged version, (d)elete, or leave (u)nresolved? u
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": null, "exists": false, "isexec": null, "issymlink": null}, "output": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 1b: Like #1 but with a merge, with local changes
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 0
|
|
$ hg rm file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 1
|
|
$ logg
|
|
o (2) source
|
|
| affected: file
|
|
| deleted: file
|
|
|
|
|
| @ (1) dest
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
$ echo "some local changes" > file
|
|
$ hg merge 2 -f
|
|
local [working copy] changed file which other [merge rev] deleted
|
|
use (c)hanged version, (d)elete, or leave (u)nresolved? u
|
|
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
|
|
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
|
|
[1]
|
|
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "merge",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "some local changes\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": null, "exists": false, "isexec": null, "issymlink": null}, "output": {"contents": "some local changes\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 2: Source changed, dest deleted
|
|
$ cd ..
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ hg rm file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up --q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted: file
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:ec87889f5f90 "source"
|
|
other [source] changed file which local [dest] deleted
|
|
use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": null, "exists": false, "isexec": null, "issymlink": null}, "other": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": null, "exists": false, "isexec": null, "issymlink": null, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 3: Source changed, dest moved
|
|
$ cd ..
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ hg mv file file_newloc
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file file_newloc
|
|
| deleted: file
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:ec87889f5f90 "source"
|
|
merging file_newloc and file to file_newloc
|
|
saved backup bundle to $TESTTMP/cornercases/foo/foo/foo/foo/.hg/strip-backup/ec87889f5f90-e39a76b8-backup.hg (glob)
|
|
$ hg up -q 2 # source
|
|
$ cat file_newloc # Should follow:
|
|
change
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": null,
|
|
"conflicts": []
|
|
}
|
|
]
|
|
Test case 4: Source changed, dest moved (w/o copytracing)
|
|
$ cd ..
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ hg mv file file_newloc
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file file_newloc
|
|
| deleted: file
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1 --config experimental.disablecopytrace=True
|
|
rebasing 1:ec87889f5f90 "source"
|
|
other [source] changed file which local [dest] deleted
|
|
use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": null, "exists": false, "isexec": null, "issymlink": null}, "other": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": null, "exists": false, "isexec": null, "issymlink": null, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 5: Source moved, dest changed
|
|
$ cd ..
|
|
$ reset
|
|
$ hg mv file file_newloc
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file file_newloc
|
|
| deleted: file
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:e6e7483a8950 "source"
|
|
merging file and file_newloc to file_newloc
|
|
saved backup bundle to $TESTTMP/cornercases/foo/foo/foo/foo/.hg/strip-backup/e6e7483a8950-8e128ac2-backup.hg (glob)
|
|
$ hg up 2
|
|
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
$ cat file_newloc
|
|
change
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": null,
|
|
"conflicts": []
|
|
}
|
|
]
|
|
Test case 6: Source moved, dest changed (w/o copytracing)
|
|
$ cd ..
|
|
$ reset
|
|
$ hg mv file file_newloc
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file file_newloc
|
|
| deleted: file
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1 --config experimental.disablecopytrace=True
|
|
rebasing 1:e6e7483a8950 "source"
|
|
local [dest] changed file which other [source] deleted
|
|
use (c)hanged version, (d)elete, or leave (u)nresolved? u
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": null, "exists": false, "isexec": null, "issymlink": null}, "output": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 7: Source is a directory, dest is a file (base is still a file)
|
|
$ cd ..
|
|
$ reset
|
|
$ hg rm file
|
|
$ mkdir file # "file" is a stretch
|
|
$ echo "this will cause problems" >> file/subfile
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file file/subfile
|
|
| deleted: file
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:ed93aeac6b3c "source"
|
|
transaction abort!
|
|
rollback completed
|
|
abort: Not a directory: '$TESTTMP/cornercases/foo/foo/foo/foo/file/subfile'
|
|
[255]
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "update",
|
|
"conflicts": []
|
|
}
|
|
]
|
|
Test case 8: Source is a file, dest is a directory (base is still a file)
|
|
$ cd ..
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ hg rm file
|
|
$ mkdir file # "file"
|
|
$ echo "this will cause problems" >> file/subfile
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file file/subfile
|
|
| deleted: file
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:ec87889f5f90 "source"
|
|
transaction abort!
|
|
rollback completed
|
|
abort: Operation not permitted: '$TESTTMP/cornercases/foo/foo/foo/foo/file'
|
|
[255]
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "update",
|
|
"conflicts": []
|
|
}
|
|
]
|
|
Test case 9: Source is a binary file, dest is a file (base is still a file)
|
|
$ cd ..
|
|
$ reset
|
|
$ python -c 'f = open("file", "w"); f.write("\x00")'
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:b6e55a03a5dc "source"
|
|
merging file
|
|
warning: ([^\s]+) looks like a binary file. (re)
|
|
warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ cat -v file # The local version should be left in the working copy
|
|
change
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "\u0000", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 10: Source is a file, dest is a binary file (base is still a file)
|
|
$ cd ..
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ python -c 'f = open("file", "w"); f.write("\x00")'
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:ec87889f5f90 "source"
|
|
merging file
|
|
warning: ([^\s]+) looks like a binary file. (re)
|
|
warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ cat -v file
|
|
^@ (no-eol)
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "\u0000", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "\u0000", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 11: Source is a symlink, dest is a file (base is still a file)
|
|
$ cd ..
|
|
$ reset
|
|
$ rm file
|
|
$ ln -s somepath file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:06aece48b59f "source"
|
|
merging file
|
|
warning: internal :merge cannot merge symlinks for file
|
|
warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ cat -v file
|
|
change
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "somepath", "exists": true, "isexec": false, "issymlink": true}, "output": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|
|
Test case 12: Source is a file, dest is a symlink (base is still a file)
|
|
$ cd ..
|
|
$ reset
|
|
$ echo "change" > file
|
|
$ hg commit -Aqm "source"
|
|
$ hg up -q 0
|
|
$ rm file
|
|
$ ln -s somepath file
|
|
$ hg commit -Aqm "dest"
|
|
$ hg up -q 2
|
|
$ logg
|
|
@ (2) dest
|
|
| affected: file
|
|
| deleted:
|
|
|
|
|
| o (1) source
|
|
|/ affected: file
|
|
| deleted:
|
|
|
|
|
o (0) base
|
|
affected: file
|
|
deleted:
|
|
|
|
|
|
$ hg rebase -d 2 -s 1
|
|
rebasing 1:ec87889f5f90 "source"
|
|
merging file
|
|
warning: internal :merge cannot merge symlinks for file
|
|
warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
|
|
unresolved conflicts (see hg resolve, then hg rebase --continue)
|
|
[1]
|
|
$ test -f file && echo "Exists" || echo "Does not exist"
|
|
Does not exist
|
|
$ ls file
|
|
file
|
|
$ hg resolve --tool=internal:dumpjson --all
|
|
[
|
|
{
|
|
"command": "rebase",
|
|
"conflicts": [{"base": {"contents": "base\n", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "somepath", "exists": true, "isexec": false, "issymlink": true}, "other": {"contents": "change\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "somepath", "exists": true, "isexec": false, "issymlink": true, "path": "$TESTTMP/cornercases/foo/foo/foo/foo/file"}, "path": "file"}]
|
|
}
|
|
]
|