monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] BUG: "mtn diff" vs. "diff" with respect to not exis


From: Ralf S. Engelschall
Subject: Re: [Monotone-devel] BUG: "mtn diff" vs. "diff" with respect to not existing trailing newline on last line
Date: Tue, 4 Mar 2008 09:33:07 +0100
User-agent: Mutt/1.5.17 OpenPKG/CURRENT (2007-11-01)

On Mon, Mar 03, 2008, Nathaniel Smith wrote:

> On Mon, Mar 03, 2008 at 10:53:25PM +0100, Ralf S. Engelschall wrote:
> > The appended patch successfully resolves the bug for me.
>
> Looks fine in principle, but *really* needs some tests added...?

Ok, here it comes. I've first polished the code changes a little bit
further (variable name, reduced the use of constants::default_encoding,
etc), added a test suite which checks for all four combinations
(existing file with or without old trailing newline multiplied with
new file with our without new trailing newline), and I've adjusted the
existing test suite where two diff outputs still had added lines before
deleted lines.

So, what does the patch do:

1. It fixes the "mtn diff" output to be compatible with diff(1) for the
   special cases of a missing trailing newline (both in the old or new
   content).

2. It ensures that in the "mtn diff" output hunks always deleted lines
   come first and then added lines. This special case just occurred
   twice in the whole test suite, but especially is triggered for the
   missing trailing newline case and hence had to be fixed in parallel.

3. It corrects two existing diff outputs in the test suite and adds
   a new test for the four cases of trailing newlines.

A "make check" is passed (again) successfully, although I'm still at
15db9bc261c01c4ca5cdb052aec69d29f3bec58a because latest HEAD is broken
because of the recent "keydir" change...

Any opinions, objections, whatever?

                                       Ralf S. Engelschall
                                       address@hidden
                                       www.engelschall.com

#
# old_revision [15db9bc261c01c4ca5cdb052aec69d29f3bec58a]
#
# add_dir "tests/diff_on_missing_trailing_newline_at_end_of_file"
#
# add_file 
"tests/diff_on_missing_trailing_newline_at_end_of_file/__driver__.lua"
#  content [692118ef6cc7d9765b13d563b90614c1c791e3da]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file1"
#  content [a43dc27b1c92cccc533ceb3a27035128e26e5b07]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file13.diff"
#  content [d6e7ac58324be3537427f865e5925f187331f5de]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file14.diff"
#  content [dcdd2294fa92ad013ddc177c12f3a3bed0c2dd38]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file2"
#  content [4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file23.diff"
#  content [86af946a84931611d6625fe4b555ab42b4e8fc0d]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file24.diff"
#  content [e6c588f9eac350fac803802708a65f2807b68673]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file3"
#  content [8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11]
#
# add_file "tests/diff_on_missing_trailing_newline_at_end_of_file/file4"
#  content [400b49625ecf4bb7d2d7096ba86801bddb05bb9f]
#
# patch "diff_patch.cc"
#  from [e359a4c03c6ce548d6414dce11160fbcb6fcb831]
#    to [daeb9be7d8c10d33781b54debd541027618dbfce]
#
# patch "simplestring_xform.cc"
#  from [5f2e4fcd288a2ec1fd59feb97ebc777b56597608]
#    to [dcaa75eb0ed67ddc119ef62f06c21bd7d13bf5cb]
#
# patch "simplestring_xform.hh"
#  from [0280d49b889bc0b7b2900d5d123cc8ec95a115eb]
#    to [564a305c99ca931c93956ac3ef903683dcb15db7]
#
# patch "tests/merge_update_part_of_file/after.diff"
#  from [48e13022c089817683c14884566546af358f7ce9]
#    to [a86dd00b0ad3a0822139372cc83d8ddd746572dd]
#
# patch "tests/merge_update_part_of_file/before.diff"
#  from [6dffe627ffe07df8df1f15670b065f16264cba6a]
#    to [1f6b25391440c416b57b517d8ce552d7b7a52f80]
#
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/__driver__.lua        
692118ef6cc7d9765b13d563b90614c1c791e3da
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/__driver__.lua        
692118ef6cc7d9765b13d563b90614c1c791e3da
@@ -0,0 +1,58 @@
+--
+-- Checks that "mtn diff" output produces the correct results
+-- in case of a missing trailing newline at end of file.
+--
+-- This test goes like this:
+-- 1. Commits two files:
+--    "file1": containing "foo\nbar\nquux\n"
+--    "file2": containing "foo\nbar\nquux"
+-- 2. Override both "file1" and "file2" with:
+--    "file3": containing "foo\nbar\quux\nbaz\n"
+--    "file4": containing "foo\nbar\quux\nbaz"
+-- 3. Produce a diff output and compare against:
+--    "file13.diff"
+--    "file14.diff"
+--    "file23.diff"
+--    "file24.diff"
+--
+
+mtn_setup()
+
+check(get("file1"))
+check(get("file2"))
+check(get("file3"))
+check(get("file4"))
+check(get("file13.diff"))
+check(get("file14.diff"))
+check(get("file23.diff"))
+check(get("file24.diff"))
+
+addfile("file1")
+addfile("file2")
+commit()
+anc = base_revision()
+
+copy("file3", "file1")
+check(mtn("diff", "file1"), 0, true)
+canonicalize("stdout")
+rename("stdout", "file13.mtn-diff")
+check(samefile("file13.mtn-diff", "file13.diff"))
+
+copy("file4", "file1")
+check(mtn("diff", "file1"), 0, true)
+canonicalize("stdout")
+rename("stdout", "file14.mtn-diff")
+check(samefile("file14.mtn-diff", "file14.diff"))
+
+copy("file3", "file2")
+check(mtn("diff", "file2"), 0, true)
+canonicalize("stdout")
+rename("stdout", "file23.mtn-diff")
+check(samefile("file23.mtn-diff", "file23.diff"))
+
+copy("file4", "file2")
+check(mtn("diff", "file2"), 0, true)
+canonicalize("stdout")
+rename("stdout", "file24.mtn-diff")
+check(samefile("file24.mtn-diff", "file24.diff"))
+
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file1 
a43dc27b1c92cccc533ceb3a27035128e26e5b07
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file1 
a43dc27b1c92cccc533ceb3a27035128e26e5b07
@@ -0,0 +1,3 @@
+foo
+bar
+quux
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file13.diff   
d6e7ac58324be3537427f865e5925f187331f5de
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file13.diff   
d6e7ac58324be3537427f865e5925f187331f5de
@@ -0,0 +1,15 @@
+#
+# old_revision [40ea110392539e19c2d251569a3610c0051e0c64]
+#
+# patch "file1"
+#  from [a43dc27b1c92cccc533ceb3a27035128e26e5b07]
+#    to [8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11]
+#
+============================================================
+--- file1      a43dc27b1c92cccc533ceb3a27035128e26e5b07
++++ file1      8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11
+@@ -1,3 +1,4 @@ quux
+ foo
+ bar
+ quux
++baz
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file14.diff   
dcdd2294fa92ad013ddc177c12f3a3bed0c2dd38
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file14.diff   
dcdd2294fa92ad013ddc177c12f3a3bed0c2dd38
@@ -0,0 +1,16 @@
+#
+# old_revision [40ea110392539e19c2d251569a3610c0051e0c64]
+#
+# patch "file1"
+#  from [a43dc27b1c92cccc533ceb3a27035128e26e5b07]
+#    to [400b49625ecf4bb7d2d7096ba86801bddb05bb9f]
+#
+============================================================
+--- file1      a43dc27b1c92cccc533ceb3a27035128e26e5b07
++++ file1      400b49625ecf4bb7d2d7096ba86801bddb05bb9f
+@@ -1,3 +1,4 @@ quux
+ foo
+ bar
+ quux
++baz
+\ No newline at end of file
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file2 
4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file2 
4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1
@@ -0,0 +1,3 @@
+foo
+bar
+quux
\ No newline at end of file
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file23.diff   
86af946a84931611d6625fe4b555ab42b4e8fc0d
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file23.diff   
86af946a84931611d6625fe4b555ab42b4e8fc0d
@@ -0,0 +1,17 @@
+#
+# old_revision [40ea110392539e19c2d251569a3610c0051e0c64]
+#
+# patch "file2"
+#  from [4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1]
+#    to [8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11]
+#
+============================================================
+--- file2      4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1
++++ file2      8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11
+@@ -1,3 +1,4 @@ bar
+ foo
+ bar
+-quux
+\ No newline at end of file
++quux
++baz
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file24.diff   
e6c588f9eac350fac803802708a65f2807b68673
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file24.diff   
e6c588f9eac350fac803802708a65f2807b68673
@@ -0,0 +1,18 @@
+#
+# old_revision [40ea110392539e19c2d251569a3610c0051e0c64]
+#
+# patch "file2"
+#  from [4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1]
+#    to [400b49625ecf4bb7d2d7096ba86801bddb05bb9f]
+#
+============================================================
+--- file2      4f8091d2fa31b0598dd0ff6dc936f8d0b47b59d1
++++ file2      400b49625ecf4bb7d2d7096ba86801bddb05bb9f
+@@ -1,3 +1,4 @@ bar
+ foo
+ bar
+-quux
+\ No newline at end of file
++quux
++baz
+\ No newline at end of file
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file3 
8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file3 
8aa9b19b304a24ebcd71cfc4a27efc95f8ad8e11
@@ -0,0 +1,4 @@
+foo
+bar
+quux
+baz
============================================================
--- tests/diff_on_missing_trailing_newline_at_end_of_file/file4 
400b49625ecf4bb7d2d7096ba86801bddb05bb9f
+++ tests/diff_on_missing_trailing_newline_at_end_of_file/file4 
400b49625ecf4bb7d2d7096ba86801bddb05bb9f
@@ -0,0 +1,4 @@
+foo
+bar
+quux
+baz
\ No newline at end of file
============================================================
--- diff_patch.cc       e359a4c03c6ce548d6414dce11160fbcb6fcb831
+++ diff_patch.cc       daeb9be7d8c10d33781b54debd541027618dbfce
@@ -1010,17 +1010,17 @@ void walk_hunk_consumer(vector<long, QA(
           while (idx(lines2,b) != *i)
             cons.insert_at(b++);
         }
-      if (b < lines2.size())
+      if (a < lines1.size())
         {
           cons.advance_to(a);
-          while(b < lines2.size())
-            cons.insert_at(b++);
+          while(a < lines1.size())
+            cons.delete_at(a++);
         }
-      if (a < lines1.size())
+      if (b < lines2.size())
         {
           cons.advance_to(a);
-          while(a < lines1.size())
-            cons.delete_at(a++);
+          while(b < lines2.size())
+            cons.insert_at(b++);
         }
       cons.flush_hunk(a);
     }
@@ -1349,8 +1349,8 @@ make_diff(string const & filename1,
     }

   vector<string> lines1, lines2;
-  split_into_lines(data1(), lines1);
-  split_into_lines(data2(), lines2);
+  split_into_lines(data1(), lines1, true);
+  split_into_lines(data2(), lines2, true);

   vector<long, QA(long)> left_interned;
   vector<long, QA(long)> right_interned;
============================================================
--- simplestring_xform.cc       5f2e4fcd288a2ec1fd59feb97ebc777b56597608
+++ simplestring_xform.cc       dcaa75eb0ed67ddc119ef62f06c21bd7d13bf5cb
@@ -50,9 +50,24 @@ void split_into_lines(string const & in,
 }

 void split_into_lines(string const & in,
+                      vector<string> & out,
+                      bool diff_compat)
+{
+  return split_into_lines(in, constants::default_encoding, out, diff_compat);
+}
+
+void split_into_lines(string const & in,
                       string const & encoding,
                       vector<string> & out)
 {
+  return split_into_lines(in, encoding, out, false);
+}
+
+void split_into_lines(string const & in,
+                      string const & encoding,
+                      vector<string> & out,
+                      bool diff_compat)
+{
   string lc_encoding = lowercase(encoding);
   out.clear();

@@ -92,8 +107,16 @@ void split_into_lines(string const & in,
             break;
           end = in.find_first_of("\r\n", begin);
         }
-      if (begin < in.size())
-        out.push_back(in.substr(begin, in.size() - begin));
+      if (begin < in.size()) {
+        // special case: last line without trailing newline
+        string s = in.substr(begin, in.size() - begin);
+        if (diff_compat) {
+          // special handling: produce diff(1) compatible output
+          s += (in.find_first_of("\r") != string::npos ? "\r\n" : "\n");
+          s += "\\ No newline at end of file";
+        }
+        out.push_back(s);
+      }
     }
   else
     {
============================================================
--- simplestring_xform.hh       0280d49b889bc0b7b2900d5d123cc8ec95a115eb
+++ simplestring_xform.hh       564a305c99ca931c93956ac3ef903683dcb15db7
@@ -13,6 +13,15 @@ void split_into_lines(std::string const
                       std::string const & encoding,
                       std::vector<std::string> & out);

+void split_into_lines(std::string const & in,
+                      std::vector<std::string> & out,
+                      bool diff_compat);
+
+void split_into_lines(std::string const & in,
+                      std::string const & encoding,
+                      std::vector<std::string> & out,
+                      bool diff_compat);
+
 void join_lines(std::vector<std::string> const & in,
                 std::string & out,
                 std::string const & linesep);
============================================================
--- tests/merge_update_part_of_file/after.diff  
48e13022c089817683c14884566546af358f7ce9
+++ tests/merge_update_part_of_file/after.diff  
a86dd00b0ad3a0822139372cc83d8ddd746572dd
@@ -12,5 +12,5 @@
  two
  chunks

+-line to be changed
 +line changed
--line to be changed
============================================================
--- tests/merge_update_part_of_file/before.diff 
6dffe627ffe07df8df1f15670b065f16264cba6a
+++ tests/merge_update_part_of_file/before.diff 
1f6b25391440c416b57b517d8ce552d7b7a52f80
@@ -23,5 +23,5 @@
  two
  chunks

+-line to be changed
 +line changed
--line to be changed





reply via email to

[Prev in Thread] Current Thread [Next in Thread]