Bug 4113 - shelve: unshelve rewrites unknown files unless they are listed in .hgignore
Summary: shelve: unshelve rewrites unknown files unless they are listed in .hgignore
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: shelve (show other bugs)
Version: 2.8
Hardware: PC Linux
: normal bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-26 10:01 UTC by Thomas Arendsen Hein
Modified: 2013-12-11 09:37 UTC (History)
3 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Arendsen Hein 2013-11-26 10:01 UTC
Tested with Mercurial 2.8 and 2.8+44-2ca325ea57fa (current crew stable).
Debian squeeze, Python 2.6.6

To reproduce:

cd /some/where/on/nfs
hg init dir
cd dir
echo foo > foo
hg add foo
hg ci -m foo
echo bar > bar
echo more >> foo

Look at timestamp of "bar" and wait a bit and/or chmod it to e.g. 400, then

hg --config extensions.shelve= shelve
hg --config extensions.shelve= unshelve

Now "bar" has an updated timestamp and the file mode is back at 644 (or whatever your umask allows for new files).

Two problems:

1. For large/many files this takes a long time (and will complain about adding files >10MB if they are this large)
2. "make" might not recompile files, because the targets are too new or the file is now world-readable when it wasn't before.

Workaround is to add the files to .hgignore, but why are the files rewritten at all?
Without this behaviour the critical bug #4112 might not occur.
Comment 1 Matt Mackall 2013-11-26 14:56 UTC
Confirmed. Something is seriously wrong here.

With unknown file foo, tracked file bar:

$ hg unshelve --debug
unshelving change 'default'
foo                                 <- ???
...
rebase completed
resolving manifests
 branchmerge: False, force: False, partial: False
 ancestor: 1498e7679f59, local: 1498e7679f59+, remote: 000000000000
 foo: other deleted -> r
removing foo                           <- ???
updating: foo 1/1 files (100.00%)

Notably a foo.i gets created!?
Comment 2 Durham Goode 2013-11-26 19:43 UTC
Sent a patch to mercurial-devel@ with a proposed fix.
Comment 3 Thomas Arendsen Hein 2013-11-27 03:37 UTC
Thank you.
The patch on the list works for my test case and bug #4112 is at least hidden now, too.
Comment 4 HG Bot 2013-12-01 15:00 UTC
Fixed by http://selenic.com/repo/hg/rev/578b888c820e
Durham Goode <durham@fb.com>
unshelve: don't commit unknown files during unshelve (issue4113)

Previously, unshelve would temporarily commit unknown files (via addremove) in
an attempt to allow unshelving into unknown files.  This produced unexpected
results, like the file time stamp changing and a .i file being created.

This change makes it no longer use addremove.  It ignores unknown files
completely.  If an unshelve would overwrite an unknown file, the unknown file is
moved to *.orig

The shelve continue/abort format is changed, but it just removes stuff from the
end of the file, so it can still read the old format.

(please test the fix)
Comment 5 Thomas Arendsen Hein 2013-12-11 09:37 UTC
I have created bug #4130 for the problem with your patch that I reported on mercurial-devel, so this issue can be resolved.