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.
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...
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
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)
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.
@kirkoman: can you provide a small recipe to reproduce?
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.
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.
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.
Did this issue get fixed by any chance? If so, in which version?
Bump
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.
> 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.
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
> 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.
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.
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.
Nothing's changed here recently.
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? :)
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.
I'm looking into this bug, I'm trying to get a handle on how complex it is to solve.
Good luck.
I'm no longer working on this bug.
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)
--- 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)