monotone-commits-diffs
[Top][All Lists]
Advanced

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

[Monotone-commits-diffs] net.venge.monotone: e32ffd851f457a4a7bc651877a6


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone: e32ffd851f457a4a7bc651877a6cc9d18066b08b
Date: Sun, 13 May 2012 02:53:21 +0200 (CEST)

revision:            e32ffd851f457a4a7bc651877a6cc9d18066b08b
date:                2012-05-12T23:37:19
author:              address@hidden
branch:              net.venge.monotone
changelog:
explicit merge of '3ea3e8ee8014b9cf0cbe92c98dd3e4b7bc76378a'
              and 'f79c782efe47978eba15b1fe43faa48f63f8cf06'



manifest:
format_version "1"

new_manifest [2f2390b32b1d92a153b8ba973891a2db5f951fe4]

old_revision [3ea3e8ee8014b9cf0cbe92c98dd3e4b7bc76378a]

patch "doc/monotone.texi"
 from [7b7f4e950e7fc284363246761f612d85d65b9744]
   to [d1293584f8a36c591fec36bc00427f77512c9876]

old_revision [f79c782efe47978eba15b1fe43faa48f63f8cf06]

add_dir "test/func/automate_erase_descendants"

add_file "test/func/automate_erase_descendants/__driver__.lua"
 content [45830e0a1e9f33e9031ca9953689b3648a9eb04e]

patch ".mtn-ignore"
 from [bd2b1b11006b28d0b1fb079e6b9c77521c704508]
   to [be27b64d4938d68bb89fab2933c1c35d0cebf885]

patch "NEWS"
 from [e2f75fe4e775336683ea15030378d9c771ead705]
   to [17c819736b0893e4d4667526656138ed23cb4b48]

patch "doc/monotone.texi"
 from [5ea8185d257fcccce9d656396e1167358301bcb4]
   to [d1293584f8a36c591fec36bc00427f77512c9876]

patch "src/automate.cc"
 from [efa4ecceab7f1e31f71778f325da312bf6aefba5]
   to [919e3df52514d0877aeafc67791aae6a3faa33b4]

patch "src/unix/fs.cc"
 from [d34f7ed4b5cf3655d7920568e4e1a146fa670e13]
   to [cd0a6fb223a4351035c3d2c32a5d4dafc609ba91]
============================================================
--- doc/monotone.texi	7b7f4e950e7fc284363246761f612d85d65b9744
+++ doc/monotone.texi	d1293584f8a36c591fec36bc00427f77512c9876
@@ -4233,7 +4233,7 @@ @section Exporting to GIT
 $ mkdir test.git
 $ cd test.git
 $ git init
-$ mtn --db test.mtn git_export | git fast import
+$ mtn --db test.mtn git_export | git fast-import
 @end group
 @end smallexample
 
============================================================
--- .mtn-ignore	bd2b1b11006b28d0b1fb079e6b9c77521c704508
+++ .mtn-ignore	be27b64d4938d68bb89fab2933c1c35d0cebf885
@@ -2,6 +2,7 @@
 ^ABOUT-NLS$
 ^Makefile(\.in)?$
 ^aclocal\.m4$
+^autom4te\.cache$
 ^build-arch-stamp$
 ^build-indep-stamp$
 ^compile$
============================================================
--- NEWS	e2f75fe4e775336683ea15030378d9c771ead705
+++ NEWS	17c819736b0893e4d4667526656138ed23cb4b48
@@ -10,6 +10,10 @@ XXX XXX XX XX:XX:XX UTC 201X
           and returns the attributes for a specific file from the
           revision's manifest
 
+        - New 'erase_descendants' automate command which returns all
+          input revisions, except those that are a descendant of
+          another revision in the input.
+
         - New 'min(A)' selector is now available which returns all
           revisions selected by A which are not descendants of other
           revisions selected by A.
============================================================
--- doc/monotone.texi	5ea8185d257fcccce9d656396e1167358301bcb4
+++ doc/monotone.texi	d1293584f8a36c591fec36bc00427f77512c9876
@@ -7523,7 +7523,48 @@ @section Automation
 
 @end table
 
address@hidden mtn automate erase_descendants address@hidden
 
address@hidden @strong
address@hidden Arguments:
+
+One or more revision IDs.
+
address@hidden Added in:
+
+13.1
+
address@hidden Purpose:
+
+Prints all arguments, except those that are a descendant of some other
+argument.
+
+One way to think about this is that it prints the minimal elements of
+the given set, under the ordering imposed by the ``parent of''
+relation.  Another way to think of it is if the arguments formed a
+branch, then we would print the roots of that branch.  If there are no
+arguments, prints nothing.
+
address@hidden Sample output:
+
address@hidden
+28ce076c69eadb9b1ca7bdf9d40ce95fe2f29b61
+75156724e0e2e3245838f356ec373c50fa469f1f
address@hidden verbatim
+
address@hidden Output format:
+
+Zero or more lines, each giving the ID of one of the given revisions.
+Each line consists of a revision ID, in hexadecimal, followed by a
+newline.  The lines are printed in alphabetically sorted order.
+
address@hidden Error conditions:
+
+If any of the revisions do not exist, prints nothing to stdout, prints
+an error message to stderr, and exits with status 1.
+
address@hidden table
+
 @item mtn automate file_merge @var{left-rid} @var{left-path} @var{right-rid} @var{right-path}
 
 @table @strong
============================================================
--- src/automate.cc	efa4ecceab7f1e31f71778f325da312bf6aefba5
+++ src/automate.cc	919e3df52514d0877aeafc67791aae6a3faa33b4
@@ -240,6 +240,39 @@ CMD_AUTOMATE(erase_ancestors, N_("[REV1 
     output << *i << '\n';
 }
 
+// Name: erase_descendants
+// Arguments:
+//   0 or more: revision ids
+// Added in: 13.1
+// Purpose: Prints all arguments, except those that are a descendant of some
+//   other argument.  One way to think about this is that it prints the
+//   minimal elements of the given set, under the ordering imposed by the
+//   "parent of" relation.  Another way to think of it is if the arguments were
+//   a branch, then we print the roots of that branch.
+// Output format: A list of revision ids, in hexadecimal, each followed by a
+//   newline.  Revision ids are printed in alphabetically sorted order.
+// Error conditions: If any of the revisions do not exist, prints nothing to
+//   stdout, prints an error message to stderr, and exits with status 1.
+CMD_AUTOMATE(erase_descendants, N_("[REV1 [REV2 [REV3 [...]]]]"),
+             N_("Erases the descendants in a list of revisions"),
+             "",
+             options::opts::none)
+{
+  database db(app);
+
+  set<revision_id> revs;
+  for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i)
+    {
+      revision_id rid(decode_hexenc_as<revision_id>((*i)(), origin::user));
+      E(db.revision_exists(rid), origin::user,
+        F("no revision %s found in database") % rid);
+      revs.insert(rid);
+    }
+  erase_descendants(db, revs);
+  for (set<revision_id>::const_iterator i = revs.begin(); i != revs.end(); ++i)
+    output << *i << '\n';
+}
+
 // Name: toposort
 // Arguments:
 //   0 or more: revision ids
============================================================
--- src/unix/fs.cc	d34f7ed4b5cf3655d7920568e4e1a146fa670e13
+++ src/unix/fs.cc	cd0a6fb223a4351035c3d2c32a5d4dafc609ba91
@@ -1,3 +1,4 @@
+// Copyright (C) 2012 Stephe Leake <address@hidden>
 // Copyright (C) 2005 nathaniel smith <address@hidden>
 //
 // This program is made available under the GNU GPL version 2.0 or
@@ -28,6 +29,7 @@
 #include "../platform.hh"
 #include "../vector.hh"
 
+using std::malloc;
 using std::string;
 using std::vector;
 
@@ -288,11 +290,74 @@ rename_clobberingly(string const & from,
 void
 rename_clobberingly(string const & from, string const & to)
 {
+  // rename doesn't work across devices, which can happen if part of the
+  // workspace is NFS mounted.
+  //
+  // We only check for that if rename fails, to avoid slowing down normal
+  // workspaces.
+
   if (rename(from.c_str(), to.c_str()))
     {
-      const int err = errno;
-      E(false, origin::system,
-        F("renaming '%s' to '%s' failed: %s") % from % to % os_strerror(err));
+      // rename failed
+      int err = errno;
+
+      int from_fd = open(from.c_str(), O_RDONLY);
+      int to_fd = open(to.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+      struct stat from_stat;
+      struct stat to_stat;
+      fstat(from_fd, &from_stat);
+      fstat(to_fd, &to_stat);
+
+      if (from_stat.st_dev != to_stat.st_dev)
+        {
+          // different devices; use cp, rm
+          //
+          // except there isn't a C function that does 'cp', so we read in
+          // the file and write it out again.
+
+          char * buffer    = (char * )malloc(from_stat.st_size);
+          char * ptr       = buffer;
+          size_t remaining = from_stat.st_size;
+
+          do
+            {
+              ssize_t read_count = read(from_fd, ptr, remaining);
+
+              err = errno;
+
+              E(read_count >= 0, origin::system,
+                F ("error reading file '%s': %s") % from % os_strerror(err));
+
+              remaining -= read_count;
+              ptr       += read_count;
+            }
+          while (remaining > 0);
+          close(from_fd);
+
+          ptr       = buffer;
+          remaining = from_stat.st_size;
+          do
+            {
+              ssize_t write_count = write(to_fd, ptr, remaining);
+              err = errno;
+              E(write_count >= 0, origin::system,
+                F("error writing file '%s': %s") % to % os_strerror(err));
+
+              remaining -= write_count;
+              ptr       += write_count;
+            }
+          while (remaining > 0);
+          close(to_fd);
+
+          free(buffer);
+
+          remove(from.c_str());
+        }
+      else
+        {
+          E(false, origin::system,
+            F("renaming '%s' to '%s' failed: %s") % from % to % os_strerror(err));
+        }
     }
 }
 
============================================================
--- /dev/null	
+++ test/func/automate_erase_descendants/__driver__.lua	45830e0a1e9f33e9031ca9953689b3648a9eb04e
@@ -0,0 +1,46 @@
+
+mtn_setup()
+
+-- Make sure we fail when given a non-existent revision
+check(mtn("automate", "erase_descendants", "c7539264e83c5d6af4c792f079b5d46e9c128665"), 1, false, false)
+
+--   A
+--  / \
+-- B   C
+--     |\
+--     D E
+--     \/
+--      F
+includecommon("automate_ancestry.lua")
+
+revs = make_graph()
+
+-- Now do some checks
+
+-- Empty input gives empty output
+revmap("erase_descendants", {}, {})
+
+-- Single revision input gives the same single revision output
+for _,x in pairs(revs) do
+  revmap("erase_descendants", {x}, {x})
+end
+
+-- Whole revision graph should give roots - A in this case
+revmap("erase_descendants", {revs.a, revs.b, revs.c, revs.d, revs.e, revs.f}, {revs.a})
+
+-- Sibling only inputs should give the same output
+revmap("erase_descendants", {revs.b, revs.c}, {revs.b, revs.c})
+revmap("erase_descendants", {revs.d, revs.e}, {revs.d, revs.e})
+
+-- Siblings with descendants should give just the siblings
+revmap("erase_descendants", {revs.b, revs.c, revs.d, revs.e, revs.f}, {revs.b, revs.c})
+revmap("erase_descendants", {revs.d, revs.e, revs.f}, {revs.d, revs.e})
+
+-- Leaves only input should give the same output
+revmap("erase_descendants", {revs.b, revs.f}, {revs.b, revs.f})
+
+-- Revision with its descendants should give just the revision
+revmap("erase_descendants", {revs.c, revs.d, revs.e, revs.f}, {revs.c})
+revmap("erase_descendants", {revs.e, revs.f}, {revs.e})
+
+

reply via email to

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