/[cvs]/ccvs/src/base.c
ViewVC logotype

Diff of /ccvs/src/base.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.2.10 by dprice, Fri Dec 2 23:50:48 2005 UTC revision 1.1.2.11 by dprice, Thu Dec 8 15:02:36 2005 UTC
# Line 257  base_checkout (RCSNode *rcs, struct file Line 257  base_checkout (RCSNode *rcs, struct file
257      TRACE (TRACE_FUNCTION, "base_checkout (%s, %s, %s, %s, %s, %s, %s)",      TRACE (TRACE_FUNCTION, "base_checkout (%s, %s, %s, %s, %s, %s, %s)",
258             finfo->fullname, prev, rev, ptag, tag, poptions, options);             finfo->fullname, prev, rev, ptag, tag, poptions, options);
259    
260        if (noexec)
261            return 0;
262    
263      mkdir_if_needed (CVSADM_BASE);      mkdir_if_needed (CVSADM_BASE);
264    
265      assert (!current_parsed_root->isremote);      assert (!current_parsed_root->isremote);
# Line 280  base_checkout (RCSNode *rcs, struct file Line 283  base_checkout (RCSNode *rcs, struct file
283    
284    
285    
286    static char *
287    temp_checkout (RCSNode *rcs, struct file_info *finfo,
288                   const char *prev, const char *rev, const char *ptag,
289                   const char *tag, const char *poptions, const char *options)
290    {
291        char *tempfile;
292        bool save_noexec;
293    
294        TRACE (TRACE_FUNCTION, "temp_checkout (%s, %s, %s, %s, %s, %s, %s)",
295               finfo->fullname, prev, rev, ptag, tag, poptions, options);
296    
297        assert (!current_parsed_root->isremote);
298    
299        tempfile = cvs_temp_name ();
300        save_noexec = noexec;
301        noexec = false;
302        if (RCS_checkout (rcs, tempfile, rev, tag, options, NULL, NULL, NULL))
303        {
304            error (0, 0, "Failed to check out revision %s of `%s'",
305                   rev, finfo->fullname);
306            free (tempfile);
307            noexec = save_noexec;
308            return NULL;
309        }
310        noexec = save_noexec;
311    
312        assert (strcmp (cvs_cmd_name, "export"));
313        if (server_active)
314            server_temp_checkout (rcs, finfo, prev, rev, ptag, tag,
315                                  poptions, options, tempfile);
316    
317        return tempfile;
318    }
319    
320    
321    
322    enum update_existing
323    translate_exists (const char *exists)
324    {
325        if (*exists == 'n') return UPDATE_ENTRIES_NEW;
326        if (*exists == 'y') return UPDATE_ENTRIES_EXISTING;
327        if (*exists == 'm') return UPDATE_ENTRIES_EXISTING_OR_NEW;
328        /* The error below should only happen due to a programming error or when
329         * the server sends a bad response.
330         */
331        error (1, 0, "unknown existence code received from server: `%s'",
332               exists);
333        assert (!"Internal error");  /* Placate GCC.  */
334    }
335    
336    
337    
338    /* Validate the existance of FILENAME against whether we think it should exist
339     * or not.  If it should exist and doesn't, issue a warning and return success.
340     * If it shouldn't exist and does, issue a warning and return false to avoid
341     * accidentally overwriting a user's changes.
342     */
343    bool
344    validate_change (enum update_existing existp, const char *filename,
345                     const char *fullname)
346    {
347        /* Note that checking this separately from writing the file is
348           a race condition: if the existence or lack thereof of the
349           file changes between now and the actual calls which
350           operate on it, we lose.  However (a) there are so many
351           cases, I'm reluctant to try to fix them all, (b) in some
352           cases the system might not even have a system call which
353           does the right thing, and (c) it isn't clear this needs to
354           work.  */
355        if (existp == UPDATE_ENTRIES_EXISTING
356            && !isfile (filename))
357            /* Emit a warning and update the file anyway.  */
358            error (0, 0, "warning: %s unexpectedly disappeared", fullname);
359        else if (existp == UPDATE_ENTRIES_NEW
360            && isfile (filename))
361        {
362            /* This error might be confusing; it isn't really clear to
363               the user what to do about it.  Keep in mind that it has
364               several causes: (1) something/someone creates the file
365               during the time that CVS is running, (2) the repository
366               has two files whose names clash for the client because
367               of case-insensitivity or similar causes, See 3 for
368               additional notes.  (3) a special case of this is that a
369               file gets renamed for example from a.c to A.C.  A
370               "cvs update" on a case-insensitive client will get this
371               error.  In this case and in case 2, the filename
372               (short_pathname) printed in the error message will likely _not_
373               have the same case as seen by the user in a directory listing.
374               (4) the client has a file which the server doesn't know
375               about (e.g. "? foo" file), and that name clashes with a file
376               the server does know about, (5) classify.c will print the same
377               message for other reasons.
378    
379               I hope the above paragraph makes it clear that making this
380               clearer is not a one-line fix.  */
381            error (0, 0, "move away `%s'; it is in the way", fullname);
382    
383            /* The Mode, Mod-time, and Checksum responses should not carry
384             * over to a subsequent Created (or whatever) response, even
385             * in the error case.
386             */
387            if (!really_quiet)
388            {
389                cvs_output ("C ", 0);
390                cvs_output (fullname, 0);
391                cvs_output ("\n", 1);
392            }
393            return false;
394        }
395    
396        return true;
397    }
398    
399    
400    
401  void  void
402  base_copy (struct file_info *finfo, const char *rev, const char *flags)  base_copy (struct file_info *finfo, const char *rev, const char *flags)
403  {  {
# Line 290  base_copy (struct file_info *finfo, cons Line 408  base_copy (struct file_info *finfo, cons
408    
409      assert (flags && flags[0] && flags[1]);      assert (flags && flags[0] && flags[1]);
410    
411        if (!server_active /* The server still doesn't stay perfectly in sync with
412                            * the client workspace.
413                            */
414            && !validate_change (translate_exists (flags), finfo->file,
415                                 finfo->fullname))
416            exit (EXIT_FAILURE);
417    
418        if (noexec)
419            return;
420    
421      basefile = make_base_file_name (finfo->file, rev);      basefile = make_base_file_name (finfo->file, rev);
422      if (isfile (finfo->file))      if (isfile (finfo->file))
423          xchmod (finfo->file, true);          xchmod (finfo->file, true);
424    
425      copy_file (basefile, finfo->file);      copy_file (basefile, finfo->file);
426      if (flags[1] == 'y')      if (flags[1] == 'y')
427          xchmod (finfo->file, true);          xchmod (finfo->file, true);
# Line 324  base_remove (const char *file, const cha Line 453  base_remove (const char *file, const cha
453  int  int
454  base_merge (RCSNode *rcs, struct file_info *finfo, const char *ptag,  base_merge (RCSNode *rcs, struct file_info *finfo, const char *ptag,
455              const char *poptions, const char *options, const char *urev,              const char *poptions, const char *options, const char *urev,
456              const char *rev1, const char *rev2)              const char *rev1, const char *rev2, bool join)
457  {  {
458      char *f1, *f2;      char *f1, *f2;
459      int retval;      int retval;
# Line 336  base_merge (RCSNode *rcs, struct file_in Line 465  base_merge (RCSNode *rcs, struct file_in
465         fails is not very informative -- it is taken verbatim from RCS 5.7,         fails is not very informative -- it is taken verbatim from RCS 5.7,
466         and relies on RCS_checkout saying something intelligent upon failure. */         and relies on RCS_checkout saying something intelligent upon failure. */
467    
468      if (base_checkout (rcs, finfo, urev, rev1, ptag, rev1, poptions, options))      if (!(f1 = temp_checkout (rcs, finfo, urev, rev1, ptag, rev1, poptions,
469                                  options)))
470          error (1, 0, "checkout of revision %s of `%s' failed.\n",          error (1, 0, "checkout of revision %s of `%s' failed.\n",
471                 rev1, finfo->fullname);                 rev1, finfo->fullname);
472        if (join || noexec)
473        {
474            if (!(f2 = temp_checkout (rcs, finfo, urev, rev2, ptag, rev2, poptions,
475                                      options)))
476                error (1, 0, "checkout of revision %s of `%s' failed.\n",
477                       rev2, finfo->fullname);
478        }
479        else
480        {
481            if (base_checkout (rcs, finfo, urev, rev2, ptag, rev2, poptions,
482                               options))
483                error (1, 0, "checkout of revision %s of `%s' failed.\n",
484                       rev2, finfo->fullname);
485            f2 = make_base_file_name (finfo->file, rev2);
486        }
487    
     if (base_checkout (rcs, finfo, urev, rev2, ptag, rev2, poptions, options))  
         error (1, 0, "checkout of revision %s of `%s' failed.\n",  
                rev2, finfo->fullname);  
   
     f1 = make_base_file_name (finfo->file, rev1);  
     f2 = make_base_file_name (finfo->file, rev2);  
488    
489      if (!server_active || !server_use_bases())      if (!server_active || !server_use_bases())
490      {      {
# Line 354  base_merge (RCSNode *rcs, struct file_in Line 493  base_merge (RCSNode *rcs, struct file_in
493           * files on the server as will be generated on the client, but I do not           * files on the server as will be generated on the client, but I do not
494           * believe that they are being used currently and it saves server CPU.           * believe that they are being used currently and it saves server CPU.
495           */           */
496          cvs_output ("Merging differences between revisions ", 0);          if (!really_quiet)
497          cvs_output (rev1, 0);          {
498          cvs_output (" and ", 5);              cvs_output ("Merging differences between ", 0);
499          cvs_output (rev2, 0);              cvs_output (rev1, 0);
500          cvs_output (" into `", 7);              cvs_output (" and ", 5);
501          if (!finfo->update_dir || !strcmp (finfo->update_dir, "."))              cvs_output (rev2, 0);
502              cvs_output (finfo->file, 0);              cvs_output (" into `", 7);
503          else              if (!finfo->update_dir || !strcmp (finfo->update_dir, "."))
504              cvs_output (finfo->fullname, 0);                  cvs_output (finfo->file, 0);
505          cvs_output ("'\n", 2);              else
506                    cvs_output (finfo->fullname, 0);
507                cvs_output ("'\n", 2);
508            }
509    
510          retval = merge (finfo->file, finfo->file, f1, f2, rev1, rev2);          retval = merge (finfo->file, finfo->file, f1, rev1, f2, rev2);
511      }      }
512      else      else
513          retval = 0;          retval = 0;
# Line 373  base_merge (RCSNode *rcs, struct file_in Line 515  base_merge (RCSNode *rcs, struct file_in
515      if (server_active)      if (server_active)
516          server_base_merge (finfo, rev1, rev2);          server_base_merge (finfo, rev1, rev2);
517    
518      if (strcmp (urev, rev1) && unlink_file (f1) < 0)      if (CVS_UNLINK (f1) < 0)
519          error (0, errno, "unable to remove `%s'", f1);          error (0, errno, "unable to remove `%s'", f1);
520      if (strcmp (urev, rev2) && unlink_file (f2) < 0)      /* Using a base file instead of a temp file here and not deleting it is an
521          error (0, errno, "unable to remove `%s'", f2);       * optimization since, for instance, on merge from 1.1 to 1.4 with local
522         * changes, the client is going to want to leave base 1.4 and delete base
523         * 1.1 rather than the other way around.
524         */
525        if (join || noexec)
526        {
527            if (CVS_UNLINK (f2) < 0)
528                error (0, errno, "unable to remove `%s'", f2);
529        }
530      free (f1);      free (f1);
531      free (f2);      free (f2);
532    

Legend:
Removed from v.1.1.2.10  
changed lines
  Added in v.1.1.2.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26