sapling/eden/scm/tests/test-fb-hgext-merge-conflictinfo.t
Durham Goode 850c78d8c9 errors: drop quotes around OSError paths
Summary:
Python 3 has changed which errors are OSError vs IOError. We have
slightly different formatting which makes the test awkward to be py2 and 3
compatible. Let's make the formats the same.

Reviewed By: quark-zju

Differential Revision: D19663964

fbshipit-source-id: 892461049b61d648431f300bea0da2f6f1c70066
2020-01-31 10:56:30 -08:00

749 lines
25 KiB
Perl

#require py2
#chg-compatible
TODO: configure mutation
$ configure noevolution
$ enable conflictinfo rebase
1) Make the repo
$ mkdir basic
$ cd basic
$ hg init
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"
$ 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: 1 conflicts while merging F1! (edit, then use 'hg resolve --mark')
warning: 1 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",
"command_details": {"cmd": "merge", "to_abort": "update --clean", "to_continue": "merge --continue"},
"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": "<<<<<<< working copy: 13124abb51b9 b - test: second version, b\nSecond conflicted version, F1\n=======\nFirst conflicted version, F1\n>>>>>>> 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": "<<<<<<< working copy: 13124abb51b9 b - test: second version, b\nSecond conflicted version, F2\n=======\nFirst conflicted version, F2\n>>>>>>> merge rev: 6dd692b7db4a a - test: first version, a\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/basic/F2"}, "path": "F2"}],
"pathconflicts": []
}
]
6) Only requested paths get dumped
$ hg resolve --tool internal:dumpjson F2
[
{
"command": "merge",
"command_details": {"cmd": "merge", "to_abort": "update --clean", "to_continue": "merge --continue"},
"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": "<<<<<<< working copy: 13124abb51b9 b - test: second version, b\nSecond conflicted version, F2\n=======\nFirst conflicted version, F2\n>>>>>>> merge rev: 6dd692b7db4a a - test: first version, a\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/basic/F2"}, "path": "F2"}],
"pathconflicts": []
}
]
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
$ 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: 1 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",
"command_details": {"cmd": "merge", "to_abort": "update --clean", "to_continue": "merge --continue"},
"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": "<<<<<<< working copy: fd7d10c36158 - test: dest\nsome local changes\n=======\nother change\n>>>>>>> merge rev: 9b65ba2922f0 - test: source\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/file"}, "path": "file"}],
"pathconflicts": []
}
]
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",
"command_details": {"cmd": "merge", "to_abort": "update --clean", "to_continue": "merge --continue"},
"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"}],
"pathconflicts": []
}
]
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 25c2ef28f4c7 "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",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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",
"command_details": {"cmd": "merge", "to_abort": "update --clean", "to_continue": "merge --continue"},
"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"}],
"pathconflicts": []
}
]
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 ec87889f5f90 "source"
other [source] changed file which local [dest] deleted
use (c)hanged version, leave (d)eleted, leave (u)nresolved, or input (r)enamed path? u
unresolved conflicts (see hg resolve, then hg rebase --continue)
[1]
$ hg resolve --tool=internal:dumpjson --all
[
{
"command": "rebase",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 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-rebase.hg (glob)
$ hg up -q 2 # source
$ cat file_newloc # Should follow:
change
$ hg resolve --tool=internal:dumpjson --all
[
{
"command": null,
"conflicts": [],
"pathconflicts": []
}
]
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.copytrace=off
rebasing ec87889f5f90 "source"
other [source] changed file which local [dest] deleted
use (c)hanged version, leave (d)eleted, leave (u)nresolved, or input (r)enamed path? u
unresolved conflicts (see hg resolve, then hg rebase --continue)
[1]
$ hg resolve --tool=internal:dumpjson --all
[
{
"command": "rebase",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 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-rebase.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": [],
"pathconflicts": []
}
]
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.copytrace=off
rebasing 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",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 ed93aeac6b3c "source"
abort:*: $TESTTMP/cornercases/foo/foo/foo/foo/file (glob)
[255]
$ hg resolve --tool=internal:dumpjson --all
[abort:*: $TESTTMP/cornercases/foo/foo/foo/foo/file (glob)
[255]
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 ec87889f5f90 "source"
abort:*: $TESTTMP/cornercases/foo/foo/foo/foo/file (glob)
[255]
$ hg resolve --tool=internal:dumpjson --all
[
{
"command": "rebase",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 b6e55a03a5dc "source"
merging file
warning: ([^\s]+) looks like a binary file. (re)
warning: 1 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",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 ec87889f5f90 "source"
merging file
warning: ([^\s]+) looks like a binary file. (re)
warning: 1 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",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 06aece48b59f "source"
merging file
warning: internal :merge cannot merge symlinks for file
warning: 1 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",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
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 ec87889f5f90 "source"
merging file
warning: internal :merge cannot merge symlinks for file
warning: 1 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",
"command_details": {"cmd": "rebase", "to_abort": "rebase --abort", "to_continue": "rebase --continue"},
"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"}],
"pathconflicts": []
}
]
$ cd ..
command_details works correctly with commands that drop both a statefile and a
mergestate (like shelve):
$ hg init command_details
$ cd command_details
$ cat >> .hg/hgrc <<EOF
> [extensions]
> shelve=
> [experimental]
> evolution = createmarkers
> EOF
$ hg debugdrawdag <<'EOS'
> b c
> |/
> a
> EOS
$ hg up -q c
$ echo 'state' > b
$ hg add -q
$ hg shelve
shelved as c
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg up -q b
$ hg unshelve
unshelving change 'c'
rebasing shelved changes
rebasing b0582bede31d "shelve changes to: c"
merging b
warning: 1 conflicts while merging b! (edit, then use 'hg resolve --mark')
unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
[1]
$ hg resolve --tool=internal:dumpjson --all
[
{
"command": "unshelve",
"command_details": {"cmd": "unshelve", "to_abort": "unshelve --abort", "to_continue": "unshelve --continue"},
"conflicts": [{"base": {"contents": "", "exists": true, "isexec": false, "issymlink": false}, "local": {"contents": "b", "exists": true, "isexec": false, "issymlink": false}, "other": {"contents": "state\n", "exists": true, "isexec": false, "issymlink": false}, "output": {"contents": "<<<<<<< dest: 488e1b7e7341 b - test: b\nb=======\nstate\n>>>>>>> source: b0582bede31d - test: shelve changes to: c\n", "exists": true, "isexec": false, "issymlink": false, "path": "$TESTTMP/cornercases/foo/foo/foo/command_details/b"}, "path": "b"}],
"pathconflicts": []
}
]