cvs-cvs
[Top][All Lists]
Advanced

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

[Cvs-cvs] Changes to ccvs/src/remove.c [signed-commits]


From: Derek Robert Price
Subject: [Cvs-cvs] Changes to ccvs/src/remove.c [signed-commits]
Date: Tue, 11 Oct 2005 22:46:50 -0400

Index: ccvs/src/remove.c
diff -u /dev/null ccvs/src/remove.c:1.63.2.1
--- /dev/null   Wed Oct 12 02:46:50 2005
+++ ccvs/src/remove.c   Wed Oct 12 02:46:37 2005
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ *                                  and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
+ * 
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS source distribution.
+ * 
+ * Remove a File
+ * 
+ * Removes entries from the present version. The entries will be removed from
+ * the RCS repository upon the next "commit".
+ * 
+ * "remove" accepts no options, only file names that are to be removed.  The
+ * file must not exist in the current directory for "remove" to work
+ * correctly.
+ */
+
+#include "cvs.h"
+
+#ifdef CLIENT_SUPPORT
+static int remove_force_fileproc (void *callerdat,
+                                        struct file_info *finfo);
+#endif
+static int remove_fileproc (void *callerdat, struct file_info *finfo);
+static Dtype remove_dirproc (void *callerdat, const char *dir,
+                             const char *repos, const char *update_dir,
+                             List *entries);
+
+static int force;
+static int local;
+static int removed_files;
+static int existing_files;
+
+static const char *const remove_usage[] =
+{
+    "Usage: %s %s [-flR] [files...]\n",
+    "\t-f\tDelete the file before removing it.\n",
+    "\t-l\tProcess this directory only (not recursive).\n",
+    "\t-R\tProcess directories recursively.\n",
+    "(Specify the --help global option for a list of other help options)\n",
+    NULL
+};
+
+int
+cvsremove (int argc, char **argv)
+{
+    int c, err;
+
+    if (argc == -1)
+       usage (remove_usage);
+
+    optind = 0;
+    while ((c = getopt (argc, argv, "+flR")) != -1)
+    {
+       switch (c)
+       {
+           case 'f':
+               force = 1;
+               break;
+           case 'l':
+               local = 1;
+               break;
+           case 'R':
+               local = 0;
+               break;
+           case '?':
+           default:
+               usage (remove_usage);
+               break;
+       }
+    }
+    argc -= optind;
+    argv += optind;
+
+    wrap_setup ();
+
+#ifdef CLIENT_SUPPORT
+    if (current_parsed_root->isremote) {
+       /* Call expand_wild so that the local removal of files will
+           work.  It's ok to do it always because we have to send the
+           file names expanded anyway.  */
+       expand_wild (argc, argv, &argc, &argv);
+       
+       if (force)
+       {
+           if (!noexec)
+           {
+               start_recursion (remove_force_fileproc, NULL, NULL, NULL,
+                                NULL, argc, argv, local, W_LOCAL,
+                                0, CVS_LOCK_NONE, NULL, 0, NULL);
+           }
+           /* else FIXME should probably act as if the file doesn't exist
+              in doing the following checks.  */
+       }
+
+       start_server ();
+       ign_setup ();
+       if (local)
+           send_arg("-l");
+       send_arg ("--");
+       /* FIXME: Can't we set SEND_NO_CONTENTS here?  Needs investigation.  */
+       send_files (argc, argv, local, 0, 0, SIGN_NEVER, NULL, NULL);
+       send_file_names (argc, argv, 0);
+       free_names (&argc, argv);
+       send_to_server ("remove\012", 0);
+        return get_responses_and_close ();
+    }
+#endif
+
+    /* start the recursion processor */
+    err = start_recursion (remove_fileproc, NULL, remove_dirproc, NULL,
+                          NULL, argc, argv, local, W_LOCAL, 0,
+                          CVS_LOCK_READ, NULL, 1, NULL);
+
+    if (removed_files && !really_quiet)
+       error (0, 0, "use `%s commit' to remove %s permanently", program_name,
+              (removed_files == 1) ? "this file" : "these files");
+
+    if (existing_files)
+       error (0, 0,
+              ((existing_files == 1) ?
+               "%d file exists; remove it first" :
+               "%d files exist; remove them first"),
+              existing_files);
+
+    return (err);
+}
+
+#ifdef CLIENT_SUPPORT
+
+/*
+ * This is called via start_recursion if we are running as the client
+ * and the -f option was used.  We just physically remove the file.
+ */
+
+/*ARGSUSED*/
+static int
+remove_force_fileproc (void *callerdat, struct file_info *finfo)
+{
+    if (CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
+       error (0, errno, "unable to remove %s", finfo->fullname);
+    return 0;
+}
+
+#endif
+
+/*
+ * remove the file, only if it has already been physically removed
+ */
+/* ARGSUSED */
+static int
+remove_fileproc (void *callerdat, struct file_info *finfo)
+{
+    Vers_TS *vers;
+
+    if (force)
+    {
+       if (!noexec)
+       {
+           if ( CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
+           {
+               error (0, errno, "unable to remove %s", finfo->fullname);
+           }
+       }
+       /* else FIXME should probably act as if the file doesn't exist
+          in doing the following checks.  */
+    }
+
+    vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
+
+    if (vers->ts_user != NULL)
+    {
+       existing_files++;
+       if (!quiet)
+           error (0, 0, "file `%s' still in working directory",
+                  finfo->fullname);
+    }
+    else if (vers->vn_user == NULL)
+    {
+       if (!quiet)
+           error (0, 0, "nothing known about `%s'", finfo->fullname);
+    }
+    else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
+    {
+       char *fname;
+
+       /*
+        * It's a file that has been added, but not commited yet. So,
+        * remove the ,t file for it and scratch it from the
+        * entries file.  */
+       Scratch_Entry (finfo->entries, finfo->file);
+       fname = Xasprintf ("%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
+       if (unlink_file (fname) < 0
+           && !existence_error (errno))
+           error (0, errno, "cannot remove %s", CVSEXT_LOG);
+       if (!quiet)
+           error (0, 0, "removed `%s'", finfo->fullname);
+
+#ifdef SERVER_SUPPORT
+       if (server_active)
+           server_checked_in (finfo->file, finfo->update_dir, 
finfo->repository);
+#endif
+       free (fname);
+    }
+    else if (vers->vn_user[0] == '-')
+    {
+       if (!quiet)
+           error (0, 0, "file `%s' already scheduled for removal",
+                  finfo->fullname);
+    }
+    else if (vers->tag != NULL && isdigit ((unsigned char) *vers->tag))
+    {
+       /* Commit will just give an error, and so there seems to be
+          little reason to allow the remove.  I mean, conflicts that
+          arise out of parallel development are one thing, but conflicts
+          that arise from sticky tags are quite another.
+
+          I would have thought that non-branch sticky tags should be the
+          same but at least now, removing a file with a non-branch sticky
+          tag means to delete the tag from the file.  I'm not sure that
+          is a good behavior, but until it is changed, we need to allow
+          it.  */
+       error (0, 0, "\
+cannot remove file `%s' which has a numeric sticky tag of `%s'",
+              finfo->fullname, vers->tag);
+    }
+    else if (vers->date != NULL)
+    {
+       /* Commit will just give an error, and so there seems to be
+          little reason to allow the remove.  */
+       error (0, 0, "\
+cannot remove file `%s' which has a sticky date of `%s'",
+              finfo->fullname, vers->date);
+    }
+    else
+    {
+       char *fname;
+
+       /* Re-register it with a negative version number.  */
+       fname = Xasprintf ("-%s", vers->vn_user);
+       Register (finfo->entries, finfo->file, fname, vers->ts_rcs,
+                 vers->options, vers->tag, vers->date, vers->ts_conflict);
+       if (!quiet)
+           error (0, 0, "scheduling `%s' for removal", finfo->fullname);
+       removed_files++;
+
+#ifdef SERVER_SUPPORT
+       if (server_active)
+           server_checked_in (finfo->file, finfo->update_dir, 
finfo->repository);
+#endif
+       free (fname);
+    }
+
+    freevers_ts (&vers);
+    return (0);
+}
+
+
+
+/*
+ * Print a warm fuzzy message
+ */
+/* ARGSUSED */
+static Dtype
+remove_dirproc (void *callerdat, const char *dir, const char *repos,
+                const char *update_dir, List *entries)
+{
+    if (!quiet)
+       error (0, 0, "Removing %s", update_dir);
+    return (R_PROCESS);
+}




reply via email to

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