Patchwork merge: show helpful message on file with directory name conflicts (issue29)

login
register
mail settings
Submitter Prasoon Shukla
Date Dec. 9, 2013, 12:52 p.m.
Message ID <f81553a5e76a62ba265c.1386593577@jimmypage>
Download mbox | patch
Permalink /patch/3208/
State Rejected
Headers show

Comments

Prasoon Shukla - Dec. 9, 2013, 12:52 p.m.
# HG changeset patch
# User Prasoon Shukla <prasoon92.iitr@gmail.com>
# Date 1386593059 -19800
#      Mon Dec 09 18:14:19 2013 +0530
# Node ID f81553a5e76a62ba265cc4d92ada0f265c3b708d
# Parent  1c92524c37cdd251c1a36b2da0fb4148b0e6ba09
merge: show helpful message on file with directory name conflicts (issue29)

Merging from a branch containing a file (directory) with same name as a
directory (file) in the working directory causes an exception with an
unhelpful message. This fix rasies an exception with a better error message.
The fix incorporates detecting the errno of the exception raised, then
comparing the errno with standard errnos defined in built-in errno module.
Exception is raised for the proper errnos.
Augie Fackler - Dec. 10, 2013, 9:30 p.m.
On Mon, Dec 09, 2013 at 06:22:57PM +0530, Prasoon Shukla wrote:
> # HG changeset patch
> # User Prasoon Shukla <prasoon92.iitr@gmail.com>
> # Date 1386593059 -19800
> #      Mon Dec 09 18:14:19 2013 +0530
> # Node ID f81553a5e76a62ba265cc4d92ada0f265c3b708d
> # Parent  1c92524c37cdd251c1a36b2da0fb4148b0e6ba09
> merge: show helpful message on file with directory name conflicts (issue29)
>
> Merging from a branch containing a file (directory) with same name as a
> directory (file) in the working directory causes an exception with an
> unhelpful message. This fix rasies an exception with a better error message.
> The fix incorporates detecting the errno of the exception raised, then
> comparing the errno with standard errnos defined in built-in errno module.
> Exception is raised for the proper errnos.
>
> diff -r 1c92524c37cd -r f81553a5e76a mercurial/scmutil.py
> --- a/mercurial/scmutil.py	Sun Dec 01 21:24:48 2013 -0600
> +++ b/mercurial/scmutil.py	Mon Dec 09 18:14:19 2013 +0530
> @@ -281,6 +281,15 @@
>                              nlink = 2 # force mktempcopy (issue1922)
>                          fd.close()
>                  except (OSError, IOError), e:
> +                    # issue29 fixed with next 2 if statements
> +                    # we display filename relative to the directory of repo
> +                    if e.errno == errno.EISDIR:
> +                        raise util.Abort(_("incoming file %s collides "
> +                        "with local directory %s/, please fix" %(path, path)))

Hm. How should the user fix this? Does this only happen in untracked
local directories, or does this happen if I make a file named "b/wat"
and you make a file named "b" and then we try to merge?

I feel like this could use a hint for /how/ the user should resolve
the problem.

> +                    if e.errno == errno.ENOTDIR:
> +                        raise util.Abort(_("a directory name in incoming "
> +                              "file %s collids with local file of the same "
> +                              "name, please fix" % path))
>                      if e.errno != errno.ENOENT:
>                          raise
>                      nlink = 0
> diff -r 1c92524c37cd -r f81553a5e76a tests/test-merge1.t
> --- a/tests/test-merge1.t	Sun Dec 01 21:24:48 2013 -0600
> +++ b/tests/test-merge1.t	Mon Dec 09 18:14:19 2013 +0530
> @@ -28,7 +28,7 @@
>
>    $ mkdir b
>    $ hg up
> -  abort: *: '$TESTTMP/t/b' (glob)
> +  abort: incoming file b collides with local directory b/, please fix
>    [255]
>    $ hg ci
>    abort: last update was interrupted
> diff -r 1c92524c37cd -r f81553a5e76a tests/test-merge4.t
> --- a/tests/test-merge4.t	Sun Dec 01 21:24:48 2013 -0600
> +++ b/tests/test-merge4.t	Mon Dec 09 18:14:19 2013 +0530
> @@ -7,9 +7,28 @@
>    $ hg commit -m "commit #1"
>    $ hg update 0
>    0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +  $ mkdir b
> +  $ echo file in dir > b/file.txt
> +  $ hg ci -A -m "commit #2"
> +  adding b/file.txt
> +  created new head
> +
> +Now, folder name 'b' matches the file b in commit#1. Merge should fail
> +with proper warning.
> +
> +  $ hg merge 1
> +  abort: incoming file b collides with local directory b/, please fix
> +  [255]
> +  $ hg update 1
> +  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
> +  $ hg merge 2
> +  abort: a directory name in incoming file b/file.txt collids with local file of the same name, please fix
> +  [255]
> +  $ hg update 0
> +  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
>    $ echo This is file c1 > c
>    $ hg add c
> -  $ hg commit -m "commit #2"
> +  $ hg commit -m "commit #3"
>    created new head
>    $ hg merge 1
>    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
Adrian Buehlmann - Dec. 10, 2013, 10:02 p.m.
On 2013-12-09 13:52, Prasoon Shukla wrote:
> # HG changeset patch
> # User Prasoon Shukla <prasoon92.iitr@gmail.com>
> # Date 1386593059 -19800
> #      Mon Dec 09 18:14:19 2013 +0530
> # Node ID f81553a5e76a62ba265cc4d92ada0f265c3b708d
> # Parent  1c92524c37cdd251c1a36b2da0fb4148b0e6ba09
> merge: show helpful message on file with directory name conflicts (issue29)
> 
> Merging from a branch containing a file (directory) with same name as a
> directory (file) in the working directory causes an exception with an
> unhelpful message. This fix rasies an exception with a better error message.
> The fix incorporates detecting the errno of the exception raised, then
> comparing the errno with standard errnos defined in built-in errno module.
> Exception is raised for the proper errnos.
> 
> diff -r 1c92524c37cd -r f81553a5e76a mercurial/scmutil.py
> --- a/mercurial/scmutil.py	Sun Dec 01 21:24:48 2013 -0600
> +++ b/mercurial/scmutil.py	Mon Dec 09 18:14:19 2013 +0530
> @@ -281,6 +281,15 @@
>                              nlink = 2 # force mktempcopy (issue1922)
>                          fd.close()
>                  except (OSError, IOError), e:
> +                    # issue29 fixed with next 2 if statements
> +                    # we display filename relative to the directory of repo
> +                    if e.errno == errno.EISDIR:
> +                        raise util.Abort(_("incoming file %s collides "
> +                        "with local directory %s/, please fix" %(path, path)))
> +                    if e.errno == errno.ENOTDIR:
> +                        raise util.Abort(_("a directory name in incoming "
> +                              "file %s collids with local file of the same "
> +                              "name, please fix" % path))
>                      if e.errno != errno.ENOENT:
>                          raise
>                      nlink = 0

If something like this must be done, I think it should likely be done at
a higher level.

I believe vfs objects are too low-level to handle these kind of exceptions.

I think a vfs object should have no notion of what an "incoming file" is.

If I remember correctly, vfs objects are used for writing the files
inside the store too (.hg/store).
Prasoon Shukla - Dec. 14, 2013, 6:13 a.m.
I apologize for the late reply. Been busy.

@Augie
1. To fix, user needs to rename the file/directory at either end. Or,
the conflicting file/directory can be deleted at either end.
2. In a nutshell, this error occurs whenever a file (directory)
collides with directory (file) of same name - tracked or not. This is
a filesystem error that occurs while trying to write the new
file/directory that is fetched. So, this will occur regardless of
whether the file is tracked or even if it is hgignored.
3. Well, mpm suggested this kind of message on the bugtracker, so I
went ahead with it. (http://bz.selenic.com/show_bug.cgi?id=29#c8)
I am open to suggestion as to how the message should look like.

@Adrian

Oh, okay. I am just getting started with hg so I don't really much of
an idea about this kind of thing. I suppose then, I can catch these
exceptions before the control goes to the vfs object?
Katsunori FUJIWARA - Jan. 1, 2014, 9:47 a.m.
At Sat, 14 Dec 2013 11:43:46 +0530,
Prasoon Shukla wrote:
> 
> I apologize for the late reply. Been busy.
> 
> @Augie
> 1. To fix, user needs to rename the file/directory at either end. Or,
> the conflicting file/directory can be deleted at either end.
> 2. In a nutshell, this error occurs whenever a file (directory)
> collides with directory (file) of same name - tracked or not. This is
> a filesystem error that occurs while trying to write the new
> file/directory that is fetched. So, this will occur regardless of
> whether the file is tracked or even if it is hgignored.
> 3. Well, mpm suggested this kind of message on the bugtracker, so I
> went ahead with it. (http://bz.selenic.com/show_bug.cgi?id=29#c8)
> I am open to suggestion as to how the message should look like.
> 
> @Adrian
> 
> Oh, okay. I am just getting started with hg so I don't really much of
> an idea about this kind of thing. I suppose then, I can catch these
> exceptions before the control goes to the vfs object?

I'm also working to fix issue29 by making "hg merge" collision
sensitive.

  http://selenic.com/pipermail/mercurial-devel/2013-May/051080.html

This series is now being rewritten for efficiency on large scale
repositories with Matt's suggestion.

  http://selenic.com/pipermail/mercurial-devel/2013-May/051132.html

I apologize for the late response, and also for slow rewriting patches :-)

----------------------------------------------------------------------
[FUJIWARA Katsunori]                             foozy@lares.dti.ne.jp

Patch

diff -r 1c92524c37cd -r f81553a5e76a mercurial/scmutil.py
--- a/mercurial/scmutil.py	Sun Dec 01 21:24:48 2013 -0600
+++ b/mercurial/scmutil.py	Mon Dec 09 18:14:19 2013 +0530
@@ -281,6 +281,15 @@ 
                             nlink = 2 # force mktempcopy (issue1922)
                         fd.close()
                 except (OSError, IOError), e:
+                    # issue29 fixed with next 2 if statements
+                    # we display filename relative to the directory of repo
+                    if e.errno == errno.EISDIR:
+                        raise util.Abort(_("incoming file %s collides "
+                        "with local directory %s/, please fix" %(path, path)))
+                    if e.errno == errno.ENOTDIR:
+                        raise util.Abort(_("a directory name in incoming "
+                              "file %s collids with local file of the same "
+                              "name, please fix" % path))
                     if e.errno != errno.ENOENT:
                         raise
                     nlink = 0
diff -r 1c92524c37cd -r f81553a5e76a tests/test-merge1.t
--- a/tests/test-merge1.t	Sun Dec 01 21:24:48 2013 -0600
+++ b/tests/test-merge1.t	Mon Dec 09 18:14:19 2013 +0530
@@ -28,7 +28,7 @@ 
 
   $ mkdir b
   $ hg up
-  abort: *: '$TESTTMP/t/b' (glob)
+  abort: incoming file b collides with local directory b/, please fix
   [255]
   $ hg ci
   abort: last update was interrupted
diff -r 1c92524c37cd -r f81553a5e76a tests/test-merge4.t
--- a/tests/test-merge4.t	Sun Dec 01 21:24:48 2013 -0600
+++ b/tests/test-merge4.t	Mon Dec 09 18:14:19 2013 +0530
@@ -7,9 +7,28 @@ 
   $ hg commit -m "commit #1"
   $ hg update 0
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkdir b
+  $ echo file in dir > b/file.txt
+  $ hg ci -A -m "commit #2"
+  adding b/file.txt
+  created new head
+
+Now, folder name 'b' matches the file b in commit#1. Merge should fail
+with proper warning.
+
+  $ hg merge 1
+  abort: incoming file b collides with local directory b/, please fix
+  [255]
+  $ hg update 1
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge 2
+  abort: a directory name in incoming file b/file.txt collids with local file of the same name, please fix
+  [255]
+  $ hg update 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo This is file c1 > c
   $ hg add c
-  $ hg commit -m "commit #2"
+  $ hg commit -m "commit #3"
   created new head
   $ hg merge 1
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved