Bug 1802 - 'hg merge' forgets a file's x-attribute on windows
Summary: 'hg merge' forgets a file's x-attribute on windows
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: normal bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-08-19 11:18 UTC by Johann Duscher
Modified: 2012-05-13 04:57 UTC (History)
16 users (show)

See Also:
Python Version: ---


Attachments
(34 bytes, text/plain)
2010-05-18 14:43 UTC, kirkoman
Details
(34 bytes, text/troff)
2011-10-17 10:03 UTC, Martin Geisler
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Johann Duscher 2009-08-19 11:18 UTC
Suppose we have three repositories R, RA, RB. RA and RB are fresh clones of
A. RA lies on a Windows computer, RB on a Linux computer. Now suppose
further that in RB a file's attribute is is changed from '-x' to '+x' using
'chmod +x file'. This change now is committed to RB and pushed to R.
Meanwhile, some changes were committed to RA on Windows. For RA now a 'hg
pull -u' and a 'hg merge' (without conflicts) followed by a 'hg commit' is
done (or, alternatively, a 'hg fetch'). After merging, these changes are
pushed to R. Everything works well, except that now the file's '+x' has
vanished. If the changes from R now are pulled into RB using 'hg pull -u'
the file 'file' has no '+x' attribute anymore. This is a bug, I think,
because the '+x' bit should be merged into the RA's manifest.
Comment 1 Johann Duscher 2009-08-19 12:06 UTC
Sorry, forget to tell you that this behavior is shown using Mercurial V1.3.1.

Additionally, I would like to tell you why, at least for us, this bug is
urgent. We develop on Windows but a Linux Server running Hudson checks out
our sources from a Mercurial repository and builds our sources. There are a
lot of Bash-Scripts which are also checked out from our repository. Now ig
we check in a script on Windows we cannot set the 'x' bit (I don't know a
way how to do it, at least). So we 'chmod +x' the Bash scripts and check
them in again. These changes often need to be merged by the developers
working on Windows. However, everytime a merge occurs on Windows all the
x-bits are lost and with their next commit/push to our central repository
the Hudson Server checks out the changes and starts building. However, the
build scripts are not executable anymore and our build fails...

So even if the x-bit issue seems not urgent to most of you it is definitely
a show stopper for us. We can workaround this issue only by making sure all
developers can pull the 'chmod +x' Bash script changes without needing a 'hg
merge'. In other words, everytime a bash script is added and/or chmod'ed we
need to synchronize all developers to a point where they can safely pull.
The advantages of working with a DVCS vanish then...
Comment 2 Mark Determann 2010-03-31 04:55 UTC
This occurs because windows doesnt support the usual (at least for every
other OS I have seen) file permission flags and has no seperation between
read and execute permissions.

Assuming this hasnt been fixed in recent versions of mercurial, the easiest
solution to this problem is to set up an extension that chmods files based
upon pattern matching against their name (e.g. *.sh for shell scripts).

I will put a copy of the extension I have written to do this here:
www.bitbucket.org/qwerty360/setperm

This extension is a work in progress, while as far as I can tell for simple
examples it works there are a number of bugs/issues that need fixing
Comment 3 Benoit Boissinot 2010-04-26 08:25 UTC
Fixed by:
changeset:   10921:fb89cd21a7a0
branch:      stable
parent:      10917:bce47e253b61
user:        Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date:        Thu Apr 15 18:08:48 2010 +0200
summary:     workingctx: correctly compute the flag for noexec filesystems+merge

(sorry, I missed this entry)
Comment 4 kirkoman 2010-05-18 12:36 UTC
Do you expect this to work with 1.5.3, Benoit?  It think I see fb89cd21a7a0 
present in 1.5.3, however I am still able to reproduce the problem - a Windows 
merge still nullifies an exec-bit change.
Comment 5 Benoit Boissinot 2010-05-18 12:45 UTC
@kirkoman:

can you provide a small recipe to reproduce?
Comment 6 kirkoman 2010-05-18 14:43 UTC
I'm attaching a manifest of my actual repro, but here is the recipe proper:

 on a unix box:
  1. init a new repo
  2. add a file (w/out the exec bit set)
  3. serve the repo

 on a windows box:
  a) clone the unix repo

 unix:
  4. set the exec bit and commit
  5. serve the repo again

 windows:
  b) make any change to the repo
  c) pull - merge - commit
  d) serve the repo

 unix:
  6. pull and update
  7. the exec bit has been lost.
Comment 7 Benoit Boissinot 2010-05-18 15:47 UTC
Ok, got it. My fix only solved the case where the file appears, not the case 
where it changes.

I think we can only fix that with some dirstateNG tricks.
Comment 8 Matt Mackall 2010-07-23 16:58 UTC
I think we should be able to fix this. It's ugly, but we do have all the
necessary information available. We just have to redo the exec bit merge at
commit time if we've got no exec bits in the working directory.
Comment 9 Graeme Harkness 2010-09-30 05:43 UTC
Did this issue get fixed by any chance?  If so, in which version?
Comment 10 Graeme Harkness 2010-10-28 06:56 UTC
Bump
Comment 11 kiilerix 2010-10-28 07:14 UTC
Not handling x attributes on platforms that doesn't support it is hardly a
bug. It would definitely be nice to handle it, but it is not urgent.
Comment 12 Graeme Harkness 2010-10-28 07:38 UTC
> Not handling x attributes on platforms that doesn't support
> it is hardly a bug. It would definitely be nice to handle it,
> but it is not urgent.

I'm not sure this problem is that benign.

As kirkoman pointed out in his "steps to reproduce", it will affect any repo 
shared between windows and Unix: probably anyone doing cross-platform 
development!

If any repo created on a Unix box is ever pull-merge-committed on a Windows 
box, any files with the x attribute set will be trashed!  That even if those 
files were not touched on the Windows box.

It's true that the Windows platform doesn't support these flags, but that 
doesn't mean it should trash them.
Comment 13 Matt Mackall 2010-10-28 12:21 UTC
We have criteria for bug priorities here and 'bug' is the appropriate priority:

http://mercurial.selenic.com/wiki/BugTracker

Note that this bug only occurs when the x-bit on the 'local' side of the
merge is the same as the ancestor's x bit. Here's a table:

LOA UW
000 00
001 00
010 10 <- merge, fail
011 00 <- merge, correct
100 11 <- merge, correct
101 01 <- merge, fail
110 11
111 11

key: (L)ocal (O)ther (A)ncestor (U)nix (W)indows

In other words, it only affects 50% of merges that happen to involve x bits
(not terribly common). So its occurrence is pretty rare, even when doing
cross-platform development. 

It is indeed annoying to occasionally lose an x bit off a file, but calling
the file 'trashed' is a bit of a stretch, don't you think?

There's some discussion about fixing the issue here:

http://mercurial.selenic.com/wiki/DirState#Proposed_extensions
Comment 14 Graeme Harkness 2010-10-28 15:01 UTC
> We have criteria for bug priorities here and 'bug' is the
> appropriate priority:
> http://mercurial.selenic.com/wiki/BugTracker

Yes, thanks for the link, that sounds about right :-)

> Note that this bug only occurs when the x-bit on the 'local' side of
> the merge is the same as the ancestor's x bit. Here's a table:
>
> LOA UW
> 000 00
> 001 00
> 010 10 <- merge, fail
> 011 00 <- merge, correct
> 100 11 <- merge, correct
> 101 01 <- merge, fail
> 110 11
> 111 11
>
> key: (L)ocal (O)ther (A)ncestor (U)nix (W)indows
>
> In other words, it only affects 50% of merges that happen to involve
> x bits (not terribly common). So its occurrence is pretty rare, even
> when doing cross-platform development. 

Our Unix developers are seeing this problem very frequently, almost after 
every windows developers' pull-merge-commit-push.  I will use your table to 
look into what might be exacerbating the problem.  Perhaps we are getting a 
"flip-flop" type situation where windows developers inadvertently strip off 
the x-bit, then unix developers fix it and re-check-in, then it breaks again 
on Windows........(repeat).

> It is indeed annoying to occasionally lose an x bit off a
> file

It is!  For clarity, we are seeing the x bit being stripped off lots of 
files and, because they are spread throughout the directory structure, 
fixing them all is a pain.  We've resorted to writing a script which 
iterates over all the executable files, fixing them :-)

> but calling the file 'trashed' is a bit of a stretch, don't you think?

I agree, apologies for the exaggeration :-)

> There's some discussion about fixing the issue here:
> http://mercurial.selenic.com/wiki/DirState#Proposed_extensions

This seems to be a good approach.  It sounds sensible that this extra state 
needs to be kept outwith the underlying filesystem, so that it can persist 
on filesystems that do not support the x-bit, i.e. Windows.

Many thanks for your interest.
Comment 15 kirkoman 2010-11-01 13:58 UTC
This continues to be an issue for us.

@mpm: I am not sure I grok your table, but aren't your success cases only 
hypothetical?  How could local ever differ from ancestor on a windows box 
since there is no way to change (or even record) the x-bit on windows?  In 
practice, I believe this bug affects 100% of windows merges involving an x-
bit.

I will admit this situation does not come up terribly often.  But every 
couple of months, some nube always spends a few hours trying to figure out 
what is going on, we debate the merits and risks of making everyone synch 
their repositories just to push the x-bit changeset, and then end up 
deciding to just script a chmod +x as part of the build.  Less than ideal.

Would really love to see this fixed.  We are building up workarounds and 
developer lore instead of relying on our source control software.  Seems to 
be the case for other cross-platform shops as well.
Comment 16 Chris Walton 2011-03-15 10:46 UTC
Has there been any progress on addressing this problem?

It is a daily annoyance, as we develop in a mixed Windows/Linux environment.
  The execute permissions are removed on every commit from Windows, and then
the files are marked as changed when the permissions are reset in Linux.   

Many thanks.
Comment 17 Matt Mackall 2011-03-15 13:30 UTC
Nothing's changed here recently.
Comment 18 Josh Faust 2011-06-06 18:57 UTC
This is something we're hitting quite often -- tens of files will get their 
executable bits stripped any time a windows developer does a merge. It's at 
the point where we're changing things so that we don't need files in the repo 
to have executable bits in order to get around it, but that's obviously not 
idea.

Who can we bribe to get this fixed? :)
Comment 19 Matt Mackall 2011-06-07 12:17 UTC
If you're willing to throw money at the problem, you can try contacting
someone here:

http://mercurial.selenic.com/wiki/Support

A plan exists (track the x-bit in the extra mode bits in dirstate), it just
needs someone with time to implement it.
Comment 20 Martin Geisler 2011-06-15 07:12 UTC
I'm looking into this bug, I'm trying to get a handle on how complex it is
to solve.
Comment 21 Adrian Buehlmann 2011-06-15 07:24 UTC
Good luck.
Comment 22 Martin Geisler 2011-07-07 01:57 UTC
I'm no longer working on this bug.
Comment 23 HG Bot 2011-10-22 16:00 UTC
Fixed by http://selenic.com/repo/hg/rev/cf5f9df6406b
Matt Mackall <mpm@selenic.com>
windows: recompute flags when committing a merge (issue1802)

(please test the fix)
Comment 24 Bugzilla 2012-05-12 09:02 UTC
--- Bug imported by bugzilla@serpentine.com 2012-05-12 09:02 EDT  ---

This bug was previously known as _bug_ 1802 at http://mercurial.selenic.com/bts/issue1802
Imported an attachment (id=1255)
Imported an attachment (id=1256)