monotone-devel
[Top][All Lists]
Advanced

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

[Monotone-devel] [REVIEW] automate content_diff


From: Thomas Keller
Subject: [Monotone-devel] [REVIEW] automate content_diff
Date: Tue, 14 Nov 2006 18:04:49 +0100
User-agent: Thunderbird 1.5 (X11/20060317)

Hi!

Please have a look at the attached patch. I have to excuse that there
are some unrelated changes in this patch (basically renaming of an
automate test to better fit the automate command and some formatting
fixes in monotone.texi) - this won't happen again.

If everything looks alright, I'd happily merge this into nvm soon.

Thomas.

-- 
- "I know that I don't know." (Sokrates)
Guitone, a frontend for monotone: http://guitone.berlios.de
Music lyrics and more: http://musicmademe.com
# 
# old_revision [2c7f4cc388667aa2d233aa9e0749b317ac42f699]
# 
# rename "tests/automate_automate_version"
#     to "tests/automate_interface_version"
# 
# add_dir "tests/automate_content_diff"
# 
# add_file "tests/automate_content_diff/__driver__.lua"
#  content [49eb0b60c12eefb624af0e586d6bd860ac03cfb4]
# 
# patch "automate.cc"
#  from [092f5069e1ce9988dc6260f868f3a9cd7f14e187]
#    to [a6332c5bb3ceb42b9829830ae0935794086e3f2a]
# 
# patch "cmd_diff_log.cc"
#  from [0eee6f1675c850932e53b7a0214235ae0dc65ad4]
#    to [ad597a711af534bd952b3753d0af247f9e8c1223]
# 
# patch "commands.cc"
#  from [01337415288f19b925c2097f54cb3fe05fce3ced]
#    to [a46a10ed30eab12e318db1db9b48d100f1009ce1]
# 
# patch "monotone.texi"
#  from [18658fe14fa458d5592b1810fc8b353551d14719]
#    to [7212dc67eee89e3f633aaf15f44ef3e265010a92]
# 
# patch "testsuite.lua"
#  from [67b5f8eb1b321452edafe257ac5f61e82c85c856]
#    to [ee3dadaa84390b8be6919ce41c9c5e6c4e3b4881]
# 
============================================================
--- tests/automate_content_diff/__driver__.lua  
49eb0b60c12eefb624af0e586d6bd860ac03cfb4
+++ tests/automate_content_diff/__driver__.lua  
49eb0b60c12eefb624af0e586d6bd860ac03cfb4
@@ -0,0 +1,36 @@
+
+mtn_setup()
+
+-- check output if there are no changes
+check(mtn("automate", "content_diff"), 0, true, true)
+check(fsize("stdout") == 0 and fsize("stderr") == 0)
+
+-- check non-existing path
+check(mtn("automate", "content_diff", "non_existing"), 1, true, true)
+
+
+-- check existing path against current workspace
+addfile("existing", "foo bar")
+-- do not restrict here, since '' (the root) has not yet been committed
+check(mtn("automate", "content_diff"), 0, true, true)
+check(fsize("stdout") ~= 0)
+
+-- add three more revisions and test for correct revid handling
+commit()
+R1=base_revision()
+writefile("existing", "foo foo")
+commit()
+R2=base_revision()
+writefile("existing", "foo foo bar")
+commit()
+R3=base_revision()
+
+-- one and two revisions should work
+check(mtn("automate", "content_diff", "-r", R1), 0, true, true)
+check(fsize("stdout") ~= 0)
+check(mtn("automate", "content_diff", "-r", R1, "-r", R2), 0, true, true)
+check(fsize("stdout") ~= 0)
+
+-- three and more should not
+check(mtn("automate", "content_diff", "-r", R1, "-r", R2, "-r", R3), 1, true, 
true)
+
============================================================
--- automate.cc 092f5069e1ce9988dc6260f868f3a9cd7f14e187
+++ automate.cc a6332c5bb3ceb42b9829830ae0935794086e3f2a
@@ -1499,7 +1499,7 @@ AUTOMATE(get_option, N_("OPTION"), optio
 // Arguments:
 //   1: a revision ID
 //   2: a file name
-// Added in: 3.2
+// Added in: 3.1
 // Purpose: Returns a list of revision IDs in which the content 
 // was most recently changed, relative to the revision ID specified 
 // in argument 1. This equates to a content mark following 
@@ -1556,7 +1556,7 @@ AUTOMATE(get_content_changed, N_("REV FI
 //   1: a source revision ID
 //   2: a file name (in the source revision)
 //   3: a target revision ID
-// Added in: 3.2
+// Added in: 3.1
 // Purpose: Given a the file name in the source revision, a filename 
 // will if possible be returned naming the file in the target revision. 
 // This allows the same file to be matched between revisions, accounting 
============================================================
--- cmd_diff_log.cc     0eee6f1675c850932e53b7a0214235ae0dc65ad4
+++ cmd_diff_log.cc     ad597a711af534bd952b3753d0af247f9e8c1223
@@ -222,6 +222,7 @@ dump_diffs(cset const & cs,
 dump_diffs(cset const & cs,
            app_state & app,
            bool new_is_archived,
+           std::ostream & output,
            set<split_path> const & paths,
            bool limit_paths = false)
 {
@@ -235,7 +236,7 @@ dump_diffs(cset const & cs,
       if (limit_paths && paths.find(i->first) == paths.end())
         continue;
 
-      cout << patch_sep << "\n";
+      output << patch_sep << "\n";
       data unpacked;
       vector<string> lines;
 
@@ -261,7 +262,7 @@ dump_diffs(cset const & cs,
                 i->second,
                 i->second,
                 data(), unpacked,
-                cout, app.opts.diff_format, pattern);
+                output, app.opts.diff_format, pattern);
     }
 
   map<split_path, split_path> reverse_rename_map;
@@ -283,7 +284,7 @@ dump_diffs(cset const & cs,
       file_data f_old;
       data data_old, data_new;
 
-      cout << patch_sep << "\n";
+      output << patch_sep << "\n";
 
       app.db.get_file_version(delta_entry_src(i), f_old);
       data_old = f_old.inner();
@@ -317,38 +318,33 @@ dump_diffs(cset const & cs,
                 delta_entry_src(i),
                 delta_entry_dst(i),
                 data_old, data_new,
-                cout, app.opts.diff_format, pattern);
+                output, app.opts.diff_format, pattern);
     }
 }
 
 static void
 dump_diffs(cset const & cs,
            app_state & app,
-           bool new_is_archived)
+           bool new_is_archived,
+           std::ostream & output)
 {
   set<split_path> dummy;
-  dump_diffs(cs, app, new_is_archived, dummy);
+  dump_diffs(cs, app, new_is_archived, output, dummy);
 }
 
-CMD(diff, N_("informative"), N_("[PATH]..."),
-    N_("show current diffs on stdout.\n"
-    "If one revision is given, the diff between the workspace and\n"
-    "that revision is shown.  If two revisions are given, the diff between\n"
-    "them is given.  If no format is specified, unified is used by default."),
-    options::opts::revision | options::opts::depth | options::opts::exclude
-    | options::opts::diff_options)
+// common functionality for diff and automate content_diff to determine
+// revisions and rosters which should be diffed
+static void 
+prepare_diff(cset & included,
+             app_state & app, 
+             std::vector<utf8> args,
+             bool & new_is_archived,
+             std::string & revheader)
 {
-  bool new_is_archived;
-  ostringstream header;
   temp_node_id_source nis;
+  ostringstream header;
+  cset excluded;
 
-  if (app.opts.external_diff_args_given)
-    N(app.opts.diff_format == external_diff,
-      F("--diff-args requires --external\n"
-        "try adding --external or removing --diff-args?"));
-
-  cset included, excluded;
-
   // initialize before transaction so we have a database to work with.
 
   if (app.opts.revision_selectors.size() == 0)
@@ -356,6 +352,9 @@ CMD(diff, N_("informative"), N_("[PATH].
   else if (app.opts.revision_selectors.size() == 1)
     app.require_workspace();
 
+  N(app.opts.revision_selectors.size() <= 2,
+    F("more than two revisions given"));
+  
   if (app.opts.revision_selectors.size() == 0)
     {
       roster_t new_roster, old_roster;
@@ -457,10 +456,31 @@ CMD(diff, N_("informative"), N_("[PATH].
     }
   else
     {
-      throw usage(name);
+      I(false);
     }
 
+    revheader = header.str();
+}
 
+CMD(diff, N_("informative"), N_("[PATH]..."),
+    N_("show current diffs on stdout.\n"
+    "If one revision is given, the diff between the workspace and\n"
+    "that revision is shown.  If two revisions are given, the diff between\n"
+    "them is given.  If no format is specified, unified is used by default."),
+    options::opts::revision | options::opts::depth | options::opts::exclude
+    | options::opts::diff_options)
+{
+  if (app.opts.external_diff_args_given)
+    N(app.opts.diff_format == external_diff,
+      F("--diff-args requires --external\n"
+        "try adding --external or removing --diff-args?"));
+
+  cset included;
+  std::string revs;
+  bool new_is_archived;
+  
+  prepare_diff(included, app, args, new_is_archived, revs);
+  
   data summary;
   write_cset(included, summary);
 
@@ -469,7 +489,7 @@ CMD(diff, N_("informative"), N_("[PATH].
   cout << "# " << "\n";
   if (summary().size() > 0)
     {
-      cout << header.str() << "# " << "\n";
+      cout << revs << "# " << "\n";
       for (vector<string>::iterator i = lines.begin(); 
            i != lines.end(); ++i)
         cout << "# " << *i << "\n";
@@ -483,9 +503,33 @@ CMD(diff, N_("informative"), N_("[PATH].
   if (app.opts.diff_format == external_diff) {
     do_external_diff(included, app, new_is_archived);
   } else
-    dump_diffs(included, app, new_is_archived);
+    dump_diffs(included, app, new_is_archived, cout);
 }
 
+
+// Name: content_diff
+// Arguments:
+//   (optional) one or more files to include
+// Added in: 4.0
+// Purpose: Availability of mtn diff as automate command.
+//
+// Output format: Like mtn diff, but with the header part omitted (as this is
+// doubles the output of automate get_revision). If no content changes 
happened,
+// the output is empty. All file operations beside mtn add are omitted,
+// as they don't change the content of the file.
+AUTOMATE(content_diff, N_("[FILE [...]]"),
+    options::opts::revision | options::opts::depth | options::opts::exclude)
+{
+  cset included;
+  std::string dummy_header;
+  bool new_is_archived;
+  
+  prepare_diff(included, app, args, new_is_archived, dummy_header);
+  
+  dump_diffs(included, app, new_is_archived, output);
+}
+
+
 static void
 log_certs(app_state & app, revision_id id, cert_name name,
           string label, string separator,
@@ -763,8 +807,8 @@ CMD(log, N_("informative"), N_("[FILE] .
               for (edge_map::const_iterator e = rev.edges.begin();
                    e != rev.edges.end(); ++e)
                 {
-                  dump_diffs(edge_changes(e), app, true, diff_paths,
-                             !mask.empty());
+                    dump_diffs(edge_changes(e), app, true, cout,
+                              diff_paths, !mask.empty());
                 }
             }
 
============================================================
--- commands.cc 01337415288f19b925c2097f54cb3fe05fce3ced
+++ commands.cc a46a10ed30eab12e318db1db9b48d100f1009ce1
@@ -12,7 +12,9 @@
 
 #include "transforms.hh"
 #include "simplestring_xform.hh"
+#include "localized_file_io.hh"
 #include "charset.hh"
+#include "diff_patch.hh"
 #include "inodeprint.hh"
 #include "cert.hh"
 #include "ui.hh"
@@ -24,6 +26,8 @@ using std::cin;
 #endif
 
 using std::cin;
+using std::map;
+using std::ostream;
 using std::pair;
 using std::set;
 using std::string;
============================================================
--- monotone.texi       18658fe14fa458d5592b1810fc8b353551d14719
+++ monotone.texi       7212dc67eee89e3f633aaf15f44ef3e265010a92
@@ -6762,20 +6762,22 @@ @section Automation
 Each attribute stanza also contains another entry which tells the status
 of attribute. This entry can have one of the following four values:
 
address@hidden
address@hidden
 'added': the attribute has just been added to the file
-
address@hidden
 'dropped': the attribute has just been dropped from the file
-
address@hidden
 'unchanged': the attribute has not been changed since the last revision
-
address@hidden
 'changed': the attribute has been changed since the last revision
address@hidden itemize
 
 The status 'changed' can come up if an attribute foo has been dropped and
 added afterwards with another value, like
 
 @verbatim
-# foo has the value "bar"
-$ mtn attr drop foo ; mtn attr set foo baz
+$ mtn attr drop file.txt foo ; mtn attr set file.txt foo baz
 @end verbatim
 
 If an attribute has been dropped, the output will still return the previously
@@ -6802,6 +6804,69 @@ @section Automation
 
 @end table
 
address@hidden mtn automate content_diff address@hidden address@hidden 
address@hidden ...]
+
address@hidden @strong
address@hidden Arguments:
+
+One or more @var{file} arguments restrict the diff output to these files,
+otherwise all changed files in the given revision(s) and/or current workspace
+are considered.
+
+If zero or more revisions are given, the command behaves as follows:
+
address@hidden
address@hidden
+no revision: the diff is done between the workspace revision and the 
+parent (base) revision of this workspace
address@hidden
+one revision: the diff is done between the workspace revision and the
+given revision @option{id1},
address@hidden
+two revisions: the diff is done between @option{id1} and @option{id2}; no
+workspace is needed in this case.
address@hidden itemize
+
address@hidden Added in:
+
+4.0
+
address@hidden Purpose:
+
+Prints the content changes between two revisions or a revision and the current
+workspace. This command differs from @command{mtn diff} in that way that it 
only
+outputs content changes and keeps quite on renames or drops, as the header of
address@hidden diff} is omitted (this is what @command{mtn automate 
get_revision} 
+already provides).
+
address@hidden Sample output:
+
address@hidden
+============================================================
+--- guitone/res/i18n/guitone_de.ts      
9857927823e1d6a0339b531c120dcaadd22d25e9
++++ guitone/res/i18n/guitone_de.ts      
0b4715dc296b1955b0707923d45d79ca7769dd3f
+@@ -1,6 +1,14 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <!DOCTYPE TS><TS version="1.1">
+ <context>
++    <name>AncestryGraph</name>
++    <message>
+[...]
address@hidden verbatim
+
address@hidden Output format:
+
+The GNU unified diff format. If there have been no content changes, the output
+is empty.
+
address@hidden Error conditions:
+
+If more than two revisions are given or a workspace is required, but
+not found, prints to stderr and exits with status 1. If one or more file 
+restrictions can't be applied, the command prints to stderr and exits as well.
+
address@hidden table
+
 @item mtn automate get_file @var{id}
 
 @table @strong
============================================================
--- testsuite.lua       67b5f8eb1b321452edafe257ac5f61e82c85c856
+++ testsuite.lua       ee3dadaa84390b8be6919ce41c9c5e6c4e3b4881
@@ -425,7 +425,7 @@ table.insert(tests, "db_load_must_create
 table.insert(tests, "update_no-ops_when_no_parent_revision")
 table.insert(tests, "branch-based_checkout")
 table.insert(tests, "db_load_must_create_a_new_db")
-table.insert(tests, "automate_automate_version")
+table.insert(tests, "automate_interface_version")
 table.insert(tests, "automate_heads")
 table.insert(tests, "merge_normalization_edge_case")
 table.insert(tests, "(todo)_undo_update_command")
@@ -687,3 +687,4 @@ table.insert(tests, "add_ignored")
 table.insert(tests, "db_check_(heights)")
 table.insert(tests, "disapproving_with_message")
 table.insert(tests, "add_ignored")
+table.insert(tests, "automate_content_diff")

reply via email to

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