Issue1175

Title KeyError for copy in commit
Priority bug Status resolved
Superseder Nosy List RonnyPfannschmidt, abuehl, cgudrian, dbaron, djc, jsgf, marijn, mpm, phil, pmezard, sylvain, unlink
Assigned To Topics

Created on 2008-06-12.12:06:41 by djc, last changed 2008-08-11.06:26:54 by djc.

Messages
msg6742 (view) Author: djc Date: 2008-08-11.06:26:54
This should be fixed by mpm, in stable as of 0d714a48ab53. (See test-issue1175.)
msg6579 (view) Author: mpm Date: 2008-07-24.23:48:49
Making title more specific to the bug
msg6574 (view) Author: mpm Date: 2008-07-24.19:11:58
Here's a truly minimal test case:

hg init
touch a
hg ci -Am0
hg mv a b
hg ci -Am1 a # record remove
hg ci -Am2 b # a is now not in parent manifest
msg6563 (view) Author: djc Date: 2008-07-23.17:42:52
So what would be a good error message for this? Since it comes up fairly often
and people get scared by the traceback, maybe we can include a fix in 1.0.2. It
should probably give a short indication of the problem, but mostly consist of a
suggestion as to the workaround.
msg6562 (view) Author: mpm Date: 2008-07-23.17:02:24
Adding nosy from related bugs: issue1151, issue1152, issue1227, issue1237
msg6276 (view) Author: mpm Date: 2008-06-13.19:45:21
And an even simpler test that shows the problem with a remove on one side and a
rename on the other:

#!/bin/sh                                                                       
rm -rf a
hg init a
cd a
echo a > a
hg ci -Am0
hg rm a
hg ci -m1
hg co 0
hg mv a a2
hg up
hg st -c
hg ci -m2
msg6266 (view) Author: djc Date: 2008-06-12.20:20:07
We should at least give a nicer error message with a hint on what to do
instead/next.
msg6265 (view) Author: mpm Date: 2008-06-12.20:09:59
Here's a much simpler test:

#!/bin/sh

rm -rf a b

hg init a
cd a
echo A > A
hg ci -Am0
hg mv A A1 
hg commit -m1
cd ..

hg clone a b
cd b
hg co 0
hg mv A A2
hg up
hg st -c
hg ci -m2

And here's the problem:

Mercurial stores copy information for the working directory in the dirstate with
a simple (source, destination) pair. When we commit, we record that "destination
is a copy of source in changeset X", where X is the parent of the working directory.

When we do a linear update, we merge things into the working directory and
record a new parent for the working directory.

In this test, we move A to A2 in the working directory, do a linear update to a
revision where A doesn't exist anymore, and then when we try to record the
origin of A2, we're now confused because there's no mention of A in the parent.

The simple workaround is to commit and then merge rather than update and commit.
That ensures the rename gets recorded while we still know what the source file
was. Since we have an easy workaround, I'm degrading this to bug.

I'm afraid no good fixes come to mind. Ideally, we'd store the copy version in
the dirstate, but that would probably require file format changes. Because an
update can take us arbitrarily far from our original version without recording
where we were, there's no good way to find what version of the now-missing file
we copied.
msg6258 (view) Author: djc Date: 2008-06-12.12:07:14
Copied from the users list:

http://news.gmane.org/find-root.php?group=gmane.comp.version-control.mercurial.general&article=7702
msg6257 (view) Author: djc Date: 2008-06-12.12:06:38
I have just found a way to make Mercurial 1.0.1 crash upon commit.

* rename a file in repository1
* rename it to a different path in repository2 (a clone of repository1)
* pull from repository1 into repository2
* update
* commit

This is with on a FreeBSD-7.0-p1/i386 system, with mercurial-1.0.1
installed from ports. Python is python25-2.5.2_2, also installed from
ports (the _2 is the patch revision of the FreeBSD port).

I don't know if this also exists in the latest development tree.
I have no time to test with the latest code right now. Sorry if
this is a duplicate. I had a quick look over what the bugtracker
returned when I searched for "rename", but I could not see a bug
report title that resembled this (I hope I haven't overlooked anything
though...)

Below is the output of the reproduction script, which is attached,
run with sh -x.

Thanks,
Stefan

+ basename ./hg-1.0.1-update-move-moved-to-bug.sh
+ basename=hg-1.0.1-update-move-moved-to-bug.sh
+ echo hg-1.0.1-update-move-moved-to-bug.sh
+ sed -e s/.sh$//
+ scratch_area=hg-1.0.1-update-move-moved-to-bug
+ repos=hg-1.0.1-update-move-moved-to-bug/repos
+ repos2=hg-1.0.1-update-move-moved-to-bug/repos2
+ set -e
+ rm -rf hg-1.0.1-update-move-moved-to-bug
+ mkdir -p hg-1.0.1-update-move-moved-to-bug/repos
+ echo A
+ hg init hg-1.0.1-update-move-moved-to-bug/repos
+ cd hg-1.0.1-update-move-moved-to-bug/repos
+ hg commit -A -m init
adding A
+ hg clone hg-1.0.1-update-move-moved-to-bug/repos
hg-1.0.1-update-move-moved-to-bug/repos2
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ cd hg-1.0.1-update-move-moved-to-bug/repos2
+ hg update
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ hg rename hg-1.0.1-update-move-moved-to-bug/repos/A
hg-1.0.1-update-move-moved-to-bug/repos/A.moved
+ hg commit -m moved A to A.moved hg-1.0.1-update-move-moved-to-bug/repos
+ hg rename hg-1.0.1-update-move-moved-to-bug/repos2/A
hg-1.0.1-update-move-moved-to-bug/repos2/A.moved2
+ cd hg-1.0.1-update-move-moved-to-bug/repos2
+ hg pull
pulling from /home/stsp/hg-1.0.1-update-move-moved-to-bug/repos
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)
+ hg update
warning: detected divergent renames of A to:
 A.moved2
 A.moved
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ cd hg-1.0.1-update-move-moved-to-bug/repos2
+ hg commit -m this will crash
** unknown exception encountered, details follow
** report bug details to http://www.selenic.com/mercurial/bts
** or mercurial <at> selenic.com
** Mercurial Distributed SCM (version 1.0.1)
Traceback (most recent call last):
  File "/usr/local/bin/hg", line 20, in <module>
    mercurial.dispatch.run()
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 20,
in run
    sys.exit(dispatch(sys.argv[1:]))
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 29,
in dispatch
    return _runcatch(u, args)
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 45,
in _runcatch
    return _dispatch(ui, args)
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 364,
in _dispatch
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 417,
in _runcommand
    return checkargs()
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 373,
in checkargs
    return cmdfunc()
  File "/usr/local/lib/python2.5/site-packages/mercurial/dispatch.py", line 356,
in <lambda>
    d = lambda: func(ui, repo, *args, **cmdoptions)
  File "/usr/local/lib/python2.5/site-packages/mercurial/commands.py", line 557,
in commit
    node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
  File "/usr/local/lib/python2.5/site-packages/mercurial/cmdutil.py", line 1179,
in commit
    return commitfunc(ui, repo, files, message, match, opts)
  File "/usr/local/lib/python2.5/site-packages/mercurial/commands.py", line 555,
in commitfunc
    force_editor=opts.get('force_editor'))
  File "/usr/local/lib/python2.5/site-packages/hgext/mq.py", line 2189, in commit
    return super(mqrepo, self).commit(*args, **opts)
  File "/usr/local/lib/python2.5/site-packages/mercurial/localrepo.py", line
832, in commit
    new[f] = self.filecommit(f, m1, m2, linkrev, trp, changed)
  File "/usr/local/lib/python2.5/site-packages/mercurial/localrepo.py", line
712, in filecommit
    meta["copyrev"] = hex(manifest1[cp])
KeyError: 'A'
History
Date User Action Args
2008-08-11 06:26:54djcsetstatus: chatting -> resolved
nosy: mpm, jsgf, pmezard, phil, djc, abuehl, dbaron, cgudrian, sylvain, unlink, RonnyPfannschmidt, marijn
messages: + msg6742
2008-07-26 18:34:13marijnsetnosy: mpm, jsgf, pmezard, phil, djc, abuehl, dbaron, cgudrian, sylvain, unlink, RonnyPfannschmidt, marijn
2008-07-26 18:01:00mpmsetnosy: + marijn
2008-07-26 18:00:43mpmlinkissue1244 superseder
2008-07-25 20:00:47unlinksetnosy: + unlink
2008-07-24 23:48:51mpmsetnosy: mpm, jsgf, pmezard, phil, djc, abuehl, dbaron, cgudrian, sylvain, RonnyPfannschmidt
messages: + msg6579
title: linear update confused by diverging renames -> KeyError for copy in commit
2008-07-24 23:42:16mpmsetnosy: + dbaron
2008-07-24 23:41:55mpmlinkissue1240 superseder
2008-07-24 19:11:58mpmsetnosy: mpm, jsgf, pmezard, phil, djc, abuehl, cgudrian, sylvain, RonnyPfannschmidt
messages: + msg6574
2008-07-24 13:33:35abuehlsetnosy: + abuehl
2008-07-23 17:42:52djcsetnosy: mpm, jsgf, pmezard, phil, djc, cgudrian, sylvain, RonnyPfannschmidt
messages: + msg6563
2008-07-23 17:02:24mpmsetnosy: + cgudrian, sylvain, jsgf, pmezard, RonnyPfannschmidt, phil
messages: + msg6562
2008-07-23 17:01:10mpmlinkissue1227 superseder
2008-07-23 17:00:35mpmlinkissue1151 superseder
2008-07-23 16:59:43mpmlinkissue1152 superseder
2008-07-23 16:58:21mpmlinkissue1237 superseder
2008-06-13 19:45:21mpmsetmessages: + msg6276
2008-06-12 20:20:08djcsetmessages: + msg6266
2008-06-12 20:10:12mpmsetpriority: urgent -> bug
messages: + msg6265
title: exception on commit after merging divergent renames -> linear update confused by diverging renames
2008-06-12 12:07:14djcsetstatus: unread -> chatting
messages: + msg6258
2008-06-12 12:06:41djccreate