Deleted Added
full compact
update.c (109660) update.c (128269)
1/*
2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
4 *
5 * You may distribute under the terms of the GNU General Public License as
6 * specified in the README file that comes with the CVS source distribution.
7 *
8 * "update" updates the version in the present directory with respect to the RCS

--- 18 unchanged lines hidden (view full) ---

27 * Files added but not yet committed are reported as A <user_file>. Files
28 * removed but not yet committed are reported as R <user_file>.
29 *
30 * If the current directory contains subdirectories that hold concurrent
31 * versions, these are updated too. If the -d option was specified, new
32 * directories added to the repository are automatically created and updated
33 * as well.
34 *
1/*
2 * Copyright (c) 1992, Brian Berliner and Jeff Polk
3 * Copyright (c) 1989-1992, Brian Berliner
4 *
5 * You may distribute under the terms of the GNU General Public License as
6 * specified in the README file that comes with the CVS source distribution.
7 *
8 * "update" updates the version in the present directory with respect to the RCS

--- 18 unchanged lines hidden (view full) ---

27 * Files added but not yet committed are reported as A <user_file>. Files
28 * removed but not yet committed are reported as R <user_file>.
29 *
30 * If the current directory contains subdirectories that hold concurrent
31 * versions, these are updated too. If the -d option was specified, new
32 * directories added to the repository are automatically created and updated
33 * as well.
34 *
35 * $FreeBSD: head/contrib/cvs/src/update.c 109660 2003-01-21 22:01:38Z peter $
35 * $FreeBSD: head/contrib/cvs/src/update.c 128269 2004-04-15 01:17:28Z peter $
36 */
37
38#include "cvs.h"
39#include "savecwd.h"
40#ifdef SERVER_SUPPORT
41# include "md5.h"
42#endif
43#include "watch.h"
44#include "fileattr.h"
45#include "edit.h"
46#include "getline.h"
47#include "buffer.h"
48#include "hardlink.h"
49
50static int checkout_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts,
51 int adding, int merging, int update_server));
52#ifdef SERVER_SUPPORT
53static void checkout_to_buffer PROTO ((void *, const char *, size_t));
36 */
37
38#include "cvs.h"
39#include "savecwd.h"
40#ifdef SERVER_SUPPORT
41# include "md5.h"
42#endif
43#include "watch.h"
44#include "fileattr.h"
45#include "edit.h"
46#include "getline.h"
47#include "buffer.h"
48#include "hardlink.h"
49
50static int checkout_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts,
51 int adding, int merging, int update_server));
52#ifdef SERVER_SUPPORT
53static void checkout_to_buffer PROTO ((void *, const char *, size_t));
54#endif
55#ifdef SERVER_SUPPORT
56static int patch_file PROTO ((struct file_info *finfo,
57 Vers_TS *vers_ts,
58 int *docheckout, struct stat *file_info,
59 unsigned char *checksum));
60static void patch_file_write PROTO ((void *, const char *, size_t));
54static int patch_file PROTO ((struct file_info *finfo,
55 Vers_TS *vers_ts,
56 int *docheckout, struct stat *file_info,
57 unsigned char *checksum));
58static void patch_file_write PROTO ((void *, const char *, size_t));
61#endif
59#endif /* SERVER_SUPPORT */
62static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers));
63static int scratch_file PROTO((struct file_info *finfo, Vers_TS *vers));
60static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers));
61static int scratch_file PROTO((struct file_info *finfo, Vers_TS *vers));
64static Dtype update_dirent_proc PROTO ((void *callerdat, char *dir,
65 char *repository, char *update_dir,
62static Dtype update_dirent_proc PROTO ((void *callerdat, const char *dir,
63 const char *repository,
64 const char *update_dir,
65 List *entries));
66static int update_dirleave_proc PROTO ((void *callerdat, const char *dir,
67 int err, const char *update_dir,
66 List *entries));
68 List *entries));
67static int update_dirleave_proc PROTO ((void *callerdat, char *dir,
68 int err, char *update_dir,
69 List *entries));
70static int update_fileproc PROTO ((void *callerdat, struct file_info *));
71static int update_filesdone_proc PROTO ((void *callerdat, int err,
69static int update_fileproc PROTO ((void *callerdat, struct file_info *));
70static int update_filesdone_proc PROTO ((void *callerdat, int err,
72 char *repository, char *update_dir,
73 List *entries));
71 const char *repository,
72 const char *update_dir,
73 List *entries));
74#ifdef PRESERVE_PERMISSIONS_SUPPORT
75static int get_linkinfo_proc PROTO ((void *callerdat, struct file_info *));
76#endif
74#ifdef PRESERVE_PERMISSIONS_SUPPORT
75static int get_linkinfo_proc PROTO ((void *callerdat, struct file_info *));
76#endif
77static void write_letter PROTO ((struct file_info *finfo, int letter));
78static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
79
80static char *options = NULL;
81static char *tag = NULL;
82static char *date = NULL;
83/* This is a bit of a kludge. We call WriteTag at the beginning
84 before we know whether nonbranch is set or not. And then at the
85 end, once we have the right value for nonbranch, we call WriteTag

--- 97 unchanged lines hidden (view full) ---

183 case 'q':
184#ifdef SERVER_SUPPORT
185 /* The CVS 1.5 client sends these options (in addition to
186 Global_option requests), so we must ignore them. */
187 if (!server_active)
188#endif
189 error (1, 0,
190 "-q or -Q must be specified before \"%s\"",
77static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
78
79static char *options = NULL;
80static char *tag = NULL;
81static char *date = NULL;
82/* This is a bit of a kludge. We call WriteTag at the beginning
83 before we know whether nonbranch is set or not. And then at the
84 end, once we have the right value for nonbranch, we call WriteTag

--- 97 unchanged lines hidden (view full) ---

182 case 'q':
183#ifdef SERVER_SUPPORT
184 /* The CVS 1.5 client sends these options (in addition to
185 Global_option requests), so we must ignore them. */
186 if (!server_active)
187#endif
188 error (1, 0,
189 "-q or -Q must be specified before \"%s\"",
191 command_name);
190 cvs_cmd_name);
192 break;
193 case 'T':
194 xpull_template = 1;
195 break;
196 case 'd':
197 update_build_dirs = 1;
198 break;
199 case 'f':

--- 217 unchanged lines hidden (view full) ---

417 /* look in the attic too if a tag or date is specified */
418 if (tag != NULL || date != NULL || joining())
419 which |= W_ATTIC;
420
421 /* call the command line interface */
422 err = do_update (argc, argv, options, tag, date, force_tag_match,
423 local, update_build_dirs, aflag, update_prune_dirs,
424 pipeout, which, join_rev1, join_rev2, (char *) NULL,
191 break;
192 case 'T':
193 xpull_template = 1;
194 break;
195 case 'd':
196 update_build_dirs = 1;
197 break;
198 case 'f':

--- 217 unchanged lines hidden (view full) ---

416 /* look in the attic too if a tag or date is specified */
417 if (tag != NULL || date != NULL || joining())
418 which |= W_ATTIC;
419
420 /* call the command line interface */
421 err = do_update (argc, argv, options, tag, date, force_tag_match,
422 local, update_build_dirs, aflag, update_prune_dirs,
423 pipeout, which, join_rev1, join_rev2, (char *) NULL,
425 xpull_template);
424 xpull_template, (char *) NULL);
426
427 /* free the space Make_Date allocated if necessary */
428 if (date != NULL)
429 free (date);
430
431 return (err);
432}
433
434/*
435 * Command line interface to update (used by checkout)
436 */
437int
438do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
439 xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir,
425
426 /* free the space Make_Date allocated if necessary */
427 if (date != NULL)
428 free (date);
429
430 return (err);
431}
432
433/*
434 * Command line interface to update (used by checkout)
435 */
436int
437do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
438 xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir,
440 xpull_template)
439 xpull_template, repository)
441 int argc;
442 char **argv;
443 char *xoptions;
444 char *xtag;
445 char *xdate;
446 int xforce;
447 int local;
448 int xbuild;
449 int xaflag;
450 int xprune;
451 int xpipeout;
452 int which;
453 char *xjoin_rev1;
454 char *xjoin_rev2;
455 char *preload_update_dir;
456 int xpull_template;
440 int argc;
441 char **argv;
442 char *xoptions;
443 char *xtag;
444 char *xdate;
445 int xforce;
446 int local;
447 int xbuild;
448 int xaflag;
449 int xprune;
450 int xpipeout;
451 int which;
452 char *xjoin_rev1;
453 char *xjoin_rev2;
454 char *preload_update_dir;
455 int xpull_template;
456 char *repository;
457{
458 int err = 0;
459 char *cp;
460
461 /* fill in the statics */
462 options = xoptions;
463 tag = xtag;
464 date = xdate;

--- 31 unchanged lines hidden (view full) ---

496 working_dir = xgetwd(); /* save top-level working dir */
497
498 /* FIXME-twp: the arguments to start_recursion make me dizzy. This
499 function call was copied from the update_fileproc call that
500 follows it; someone should make sure that I did it right. */
501 err = start_recursion (get_linkinfo_proc, (FILESDONEPROC) NULL,
502 (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
503 argc, argv, local, which, aflag, CVS_LOCK_READ,
457{
458 int err = 0;
459 char *cp;
460
461 /* fill in the statics */
462 options = xoptions;
463 tag = xtag;
464 date = xdate;

--- 31 unchanged lines hidden (view full) ---

496 working_dir = xgetwd(); /* save top-level working dir */
497
498 /* FIXME-twp: the arguments to start_recursion make me dizzy. This
499 function call was copied from the update_fileproc call that
500 follows it; someone should make sure that I did it right. */
501 err = start_recursion (get_linkinfo_proc, (FILESDONEPROC) NULL,
502 (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
503 argc, argv, local, which, aflag, CVS_LOCK_READ,
504 preload_update_dir, 1);
504 preload_update_dir, 1, (char *) NULL);
505 if (err)
506 return (err);
507
508 /* FIXME-twp: at this point we should walk the hardlist
509 and update the `links' field of each hardlink_info struct
510 to list the files that are linked on dist. That would make
511 it easier & more efficient to compare the disk linkage with
512 the repository linkage (a simple strcmp). */
513 }
514#endif
515
516 /* call the recursion processor */
517 err = start_recursion (update_fileproc, update_filesdone_proc,
518 update_dirent_proc, update_dirleave_proc, NULL,
519 argc, argv, local, which, aflag, CVS_LOCK_READ,
505 if (err)
506 return (err);
507
508 /* FIXME-twp: at this point we should walk the hardlist
509 and update the `links' field of each hardlink_info struct
510 to list the files that are linked on dist. That would make
511 it easier & more efficient to compare the disk linkage with
512 the repository linkage (a simple strcmp). */
513 }
514#endif
515
516 /* call the recursion processor */
517 err = start_recursion (update_fileproc, update_filesdone_proc,
518 update_dirent_proc, update_dirleave_proc, NULL,
519 argc, argv, local, which, aflag, CVS_LOCK_READ,
520 preload_update_dir, 1);
520 preload_update_dir, 1, repository);
521
522#ifdef SERVER_SUPPORT
523 if (server_active)
524 return err;
525#endif
526
527 /* see if we need to sleep before returning to avoid time-stamp races */
528 if (last_register_time)

--- 36 unchanged lines hidden (view full) ---

565
566 /* Create a new, empty hardlink_info node. */
567 hlinfo = (struct hardlink_info *)
568 xmalloc (sizeof (struct hardlink_info));
569
570 hlinfo->status = (Ctype) 0; /* is this dumb? */
571 hlinfo->checked_out = 0;
572
521
522#ifdef SERVER_SUPPORT
523 if (server_active)
524 return err;
525#endif
526
527 /* see if we need to sleep before returning to avoid time-stamp races */
528 if (last_register_time)

--- 36 unchanged lines hidden (view full) ---

565
566 /* Create a new, empty hardlink_info node. */
567 hlinfo = (struct hardlink_info *)
568 xmalloc (sizeof (struct hardlink_info));
569
570 hlinfo->status = (Ctype) 0; /* is this dumb? */
571 hlinfo->checked_out = 0;
572
573 linkp->data = (char *) hlinfo;
573 linkp->data = hlinfo;
574
575 return 0;
576}
577#endif
578
574
575 return 0;
576}
577#endif
578
579
580
579/*
580 * This is the callback proc for update. It is called for each file in each
581 * directory by the recursion code. The current directory is the local
582 * instantiation. file is the file name we are to operate on. update_dir is
583 * set to the path relative to where we started (for pretty printing).
584 * repository is the repository. entries and srcfiles are the pre-parsed
585 * entries and source control files.
586 *

--- 106 unchanged lines hidden (view full) ---

693 after this. */
694 status = T_CHECKOUT;
695 retval = checkout_file (finfo, vers, 0, 0, 1);
696 }
697 else
698 {
699 if (vers->ts_conflict)
700 {
581/*
582 * This is the callback proc for update. It is called for each file in each
583 * directory by the recursion code. The current directory is the local
584 * instantiation. file is the file name we are to operate on. update_dir is
585 * set to the path relative to where we started (for pretty printing).
586 * repository is the repository. entries and srcfiles are the pre-parsed
587 * entries and source control files.
588 *

--- 106 unchanged lines hidden (view full) ---

695 after this. */
696 status = T_CHECKOUT;
697 retval = checkout_file (finfo, vers, 0, 0, 1);
698 }
699 else
700 {
701 if (vers->ts_conflict)
702 {
701 char *filestamp;
702 int retcode;
703
704 /*
705 * If the timestamp has changed and no
706 * conflict indicators are found, it isn't a
707 * 'C' any more.
708 */
709
710#ifdef SERVER_SUPPORT
711 if (server_active)
712 retcode = vers->ts_conflict[0] != '=';
713 else
703 if (file_has_conflict (finfo, vers->ts_conflict)
704 || file_has_markers (finfo))
714 {
705 {
715 filestamp = time_stamp (finfo->file);
716 retcode = strcmp (vers->ts_conflict, filestamp);
717 free (filestamp);
718 }
719#else
720 filestamp = time_stamp (finfo->file);
721 retcode = strcmp (vers->ts_conflict, filestamp);
722 free (filestamp);
723#endif
724
725 if (retcode)
726 {
727 /* The timestamps differ. But if there
728 are conflict markers print 'C' anyway. */
729 retcode = !file_has_markers (finfo);
730 }
731
732 if (!retcode)
733 {
734 write_letter (finfo, 'C');
735 retval = 1;
736 }
737 else
738 {
739 /* Reregister to clear conflict flag. */
740 Register (finfo->entries, finfo->file,
741 vers->vn_rcs, vers->ts_rcs,
742 vers->options, vers->tag,
743 vers->date, (char *)0);
744 }
745 }
746 if (!retval)
706 write_letter (finfo, 'C');
707 retval = 1;
708 }
709 else
710 {
711 /* Reregister to clear conflict flag. */
712 Register (finfo->entries, finfo->file,
713 vers->vn_rcs, vers->ts_rcs,
714 vers->options, vers->tag,
715 vers->date, (char *)0);
716 }
717 }
718 if (!retval)
747 {
748 write_letter (finfo, 'M');
719 write_letter (finfo, 'M');
749 retval = 0;
750 }
751 }
752 break;
753 case T_PATCH: /* needs patch */
754#ifdef SERVER_SUPPORT
755 if (patches)
756 {
757 int docheckout;
758 struct stat file_info;

--- 53 unchanged lines hidden (view full) ---

812 p = getnode ();
813 p->type = FILES;
814 p->key = xstrdup (finfo->file);
815 if (addnode (ignlist, p) != 0)
816 freenode (p);
817 }
818
819 freevers_ts (&vers);
720 }
721 break;
722 case T_PATCH: /* needs patch */
723#ifdef SERVER_SUPPORT
724 if (patches)
725 {
726 int docheckout;
727 struct stat file_info;

--- 53 unchanged lines hidden (view full) ---

781 p = getnode ();
782 p->type = FILES;
783 p->key = xstrdup (finfo->file);
784 if (addnode (ignlist, p) != 0)
785 freenode (p);
786 }
787
788 freevers_ts (&vers);
820 return (retval);
789 return retval;
821}
822
790}
791
823static void update_ignproc PROTO ((char *, char *));
824
792
793
794static void update_ignproc PROTO ((const char *, const char *));
795
825static void
826update_ignproc (file, dir)
796static void
797update_ignproc (file, dir)
827 char *file;
828 char *dir;
798 const char *file;
799 const char *dir;
829{
830 struct file_info finfo;
800{
801 struct file_info finfo;
802 char *tmp;
831
832 memset (&finfo, 0, sizeof (finfo));
833 finfo.file = file;
834 finfo.update_dir = dir;
835 if (dir[0] == '\0')
803
804 memset (&finfo, 0, sizeof (finfo));
805 finfo.file = file;
806 finfo.update_dir = dir;
807 if (dir[0] == '\0')
836 finfo.fullname = xstrdup (file);
808 tmp = xstrdup (file);
837 else
838 {
809 else
810 {
839 finfo.fullname = xmalloc (strlen (file) + strlen (dir) + 10);
840 strcpy (finfo.fullname, dir);
841 strcat (finfo.fullname, "/");
842 strcat (finfo.fullname, file);
811 tmp = xmalloc (strlen (file) + strlen (dir) + 10);
812 strcpy (tmp, dir);
813 strcat (tmp, "/");
814 strcat (tmp, file);
843 }
844
815 }
816
817 finfo.fullname = tmp;
845 write_letter (&finfo, '?');
818 write_letter (&finfo, '?');
846 free (finfo.fullname);
819 free (tmp);
847}
848
820}
821
822
823
849/* ARGSUSED */
850static int
851update_filesdone_proc (callerdat, err, repository, update_dir, entries)
852 void *callerdat;
853 int err;
824/* ARGSUSED */
825static int
826update_filesdone_proc (callerdat, err, repository, update_dir, entries)
827 void *callerdat;
828 int err;
854 char *repository;
855 char *update_dir;
829 const char *repository;
830 const char *update_dir;
856 List *entries;
857{
858 if (rewrite_tag)
859 {
860 WriteTag (NULL, tag, date, nonbranch, update_dir, repository);
861 rewrite_tag = 0;
862 }
863
864 /* if this directory has an ignore list, process it then free it */
865 if (ignlist)
866 {
867 ignore_files (ignlist, entries, update_dir, update_ignproc);
868 dellist (&ignlist);
869 }
870
871 /* Clean up CVS admin dirs if we are export */
831 List *entries;
832{
833 if (rewrite_tag)
834 {
835 WriteTag (NULL, tag, date, nonbranch, update_dir, repository);
836 rewrite_tag = 0;
837 }
838
839 /* if this directory has an ignore list, process it then free it */
840 if (ignlist)
841 {
842 ignore_files (ignlist, entries, update_dir, update_ignproc);
843 dellist (&ignlist);
844 }
845
846 /* Clean up CVS admin dirs if we are export */
872 if (strcmp (command_name, "export") == 0)
847 if (strcmp (cvs_cmd_name, "export") == 0)
873 {
874 /* I'm not sure the existence_error is actually possible (except
875 in cases where we really should print a message), but since
876 this code used to ignore all errors, I'll play it safe. */
877 if (unlink_file_dir (CVSADM) < 0 && !existence_error (errno))
878 error (0, errno, "cannot remove %s directory", CVSADM);
879 }
880#ifdef SERVER_SUPPORT

--- 5 unchanged lines hidden (view full) ---

886 /* If there is no CVS/Root file, add one */
887 if (!isfile (CVSADM_ROOT))
888 Create_Root ((char *) NULL, current_parsed_root->original);
889 }
890
891 return (err);
892}
893
848 {
849 /* I'm not sure the existence_error is actually possible (except
850 in cases where we really should print a message), but since
851 this code used to ignore all errors, I'll play it safe. */
852 if (unlink_file_dir (CVSADM) < 0 && !existence_error (errno))
853 error (0, errno, "cannot remove %s directory", CVSADM);
854 }
855#ifdef SERVER_SUPPORT

--- 5 unchanged lines hidden (view full) ---

861 /* If there is no CVS/Root file, add one */
862 if (!isfile (CVSADM_ROOT))
863 Create_Root ((char *) NULL, current_parsed_root->original);
864 }
865
866 return (err);
867}
868
869
870
894/*
895 * update_dirent_proc () is called back by the recursion processor before a
896 * sub-directory is processed for update. In this case, update_dirent proc
897 * will probably create the directory unless -d isn't specified and this is a
898 * new directory. A return code of 0 indicates the directory should be
899 * processed by the recursion code. A return of non-zero indicates the
900 * recursion code should skip this directory.
901 */
902static Dtype
903update_dirent_proc (callerdat, dir, repository, update_dir, entries)
904 void *callerdat;
871/*
872 * update_dirent_proc () is called back by the recursion processor before a
873 * sub-directory is processed for update. In this case, update_dirent proc
874 * will probably create the directory unless -d isn't specified and this is a
875 * new directory. A return code of 0 indicates the directory should be
876 * processed by the recursion code. A return of non-zero indicates the
877 * recursion code should skip this directory.
878 */
879static Dtype
880update_dirent_proc (callerdat, dir, repository, update_dir, entries)
881 void *callerdat;
905 char *dir;
906 char *repository;
907 char *update_dir;
882 const char *dir;
883 const char *repository;
884 const char *update_dir;
908 List *entries;
909{
910 if (ignore_directory (update_dir))
911 {
912 /* print the warm fuzzy message */
913 if (!quiet)
914 error (0, 0, "Ignoring %s", update_dir);
915 return R_SKIP_ALL;

--- 133 unchanged lines hidden (view full) ---

1049
1050 /* print the warm fuzzy message */
1051 if (!quiet)
1052 error (0, 0, "Updating %s", update_dir);
1053
1054 return (R_PROCESS);
1055}
1056
885 List *entries;
886{
887 if (ignore_directory (update_dir))
888 {
889 /* print the warm fuzzy message */
890 if (!quiet)
891 error (0, 0, "Ignoring %s", update_dir);
892 return R_SKIP_ALL;

--- 133 unchanged lines hidden (view full) ---

1026
1027 /* print the warm fuzzy message */
1028 if (!quiet)
1029 error (0, 0, "Updating %s", update_dir);
1030
1031 return (R_PROCESS);
1032}
1033
1034
1035
1057/*
1058 * update_dirleave_proc () is called back by the recursion code upon leaving
1059 * a directory. It will prune empty directories if needed and will execute
1060 * any appropriate update programs.
1061 */
1062/* ARGSUSED */
1063static int
1064update_dirleave_proc (callerdat, dir, err, update_dir, entries)
1065 void *callerdat;
1036/*
1037 * update_dirleave_proc () is called back by the recursion code upon leaving
1038 * a directory. It will prune empty directories if needed and will execute
1039 * any appropriate update programs.
1040 */
1041/* ARGSUSED */
1042static int
1043update_dirleave_proc (callerdat, dir, err, update_dir, entries)
1044 void *callerdat;
1066 char *dir;
1045 const char *dir;
1067 int err;
1046 int err;
1068 char *update_dir;
1047 const char *update_dir;
1069 List *entries;
1070{
1048 List *entries;
1049{
1071 FILE *fp;
1072
1073 /* Delete the ignore list if it hasn't already been done. */
1074 if (ignlist)
1075 dellist (&ignlist);
1076
1077 /* If we set the tag or date for a new subdirectory in
1078 update_dirent_proc, and we're now done with that subdirectory,
1079 undo the tag/date setting. Note that we know that the tag and
1080 date were both originally NULL in this case. */

--- 9 unchanged lines hidden (view full) ---

1090 free (date);
1091 date = NULL;
1092 }
1093 nonbranch = 0;
1094 free (tag_update_dir);
1095 tag_update_dir = NULL;
1096 }
1097
1050 /* Delete the ignore list if it hasn't already been done. */
1051 if (ignlist)
1052 dellist (&ignlist);
1053
1054 /* If we set the tag or date for a new subdirectory in
1055 update_dirent_proc, and we're now done with that subdirectory,
1056 undo the tag/date setting. Note that we know that the tag and
1057 date were both originally NULL in this case. */

--- 9 unchanged lines hidden (view full) ---

1067 free (date);
1068 date = NULL;
1069 }
1070 nonbranch = 0;
1071 free (tag_update_dir);
1072 tag_update_dir = NULL;
1073 }
1074
1098 /* run the update_prog if there is one */
1099 /* FIXME: should be checking for errors from CVS_FOPEN and printing
1100 them if not existence_error. */
1101 if (err == 0 && !pipeout && !noexec &&
1102 (fp = CVS_FOPEN (CVSADM_UPROG, "r")) != NULL)
1103 {
1104 char *cp;
1105 char *repository;
1106 char *line = NULL;
1107 size_t line_allocated = 0;
1108
1109 repository = Name_Repository ((char *) NULL, update_dir);
1110 if (getline (&line, &line_allocated, fp) >= 0)
1111 {
1112 if ((cp = strrchr (line, '\n')) != NULL)
1113 *cp = '\0';
1114 run_setup (line);
1115 run_arg (repository);
1116 cvs_output (program_name, 0);
1117 cvs_output (" ", 1);
1118 cvs_output (command_name, 0);
1119 cvs_output (": Executing '", 0);
1120 run_print (stdout);
1121 cvs_output ("'\n", 0);
1122 cvs_flushout ();
1123 (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
1124 }
1125 else if (ferror (fp))
1126 error (0, errno, "cannot read %s", CVSADM_UPROG);
1127 else
1128 error (0, 0, "unexpected end of file on %s", CVSADM_UPROG);
1129
1130 if (fclose (fp) < 0)
1131 error (0, errno, "cannot close %s", CVSADM_UPROG);
1132 if (line != NULL)
1133 free (line);
1134 free (repository);
1135 }
1136
1137 if (strchr (dir, '/') == NULL)
1138 {
1139 /* FIXME: chdir ("..") loses with symlinks. */
1140 /* Prune empty dirs on the way out - if necessary */
1141 (void) CVS_CHDIR ("..");
1142 if (update_prune_dirs && isemptydir (dir, 0))
1143 {
1144 /* I'm not sure the existence_error is actually possible (except

--- 11 unchanged lines hidden (view full) ---

1156static int isremoved PROTO ((Node *, void *));
1157
1158/* Returns 1 if the file indicated by node has been removed. */
1159static int
1160isremoved (node, closure)
1161 Node *node;
1162 void *closure;
1163{
1075 if (strchr (dir, '/') == NULL)
1076 {
1077 /* FIXME: chdir ("..") loses with symlinks. */
1078 /* Prune empty dirs on the way out - if necessary */
1079 (void) CVS_CHDIR ("..");
1080 if (update_prune_dirs && isemptydir (dir, 0))
1081 {
1082 /* I'm not sure the existence_error is actually possible (except

--- 11 unchanged lines hidden (view full) ---

1094static int isremoved PROTO ((Node *, void *));
1095
1096/* Returns 1 if the file indicated by node has been removed. */
1097static int
1098isremoved (node, closure)
1099 Node *node;
1100 void *closure;
1101{
1164 Entnode *entdata = (Entnode*) node->data;
1102 Entnode *entdata = node->data;
1165
1166 /* If the first character of the version is a '-', the file has been
1167 removed. */
1168 return (entdata->version && entdata->version[0] == '-') ? 1 : 0;
1169}
1170
1171/* Returns 1 if the argument directory is completely empty, other than the
1172 existence of the CVS directory entry. Zero otherwise. If MIGHT_NOT_EXIST
1173 and the directory doesn't exist, then just return 0. */
1174int
1175isemptydir (dir, might_not_exist)
1103
1104 /* If the first character of the version is a '-', the file has been
1105 removed. */
1106 return (entdata->version && entdata->version[0] == '-') ? 1 : 0;
1107}
1108
1109/* Returns 1 if the argument directory is completely empty, other than the
1110 existence of the CVS directory entry. Zero otherwise. If MIGHT_NOT_EXIST
1111 and the directory doesn't exist, then just return 0. */
1112int
1113isemptydir (dir, might_not_exist)
1176 char *dir;
1114 const char *dir;
1177 int might_not_exist;
1178{
1179 DIR *dirp;
1180 struct dirent *dp;
1181
1182 if ((dirp = CVS_OPENDIR (dir)) == NULL)
1183 {
1184 if (might_not_exist && existence_error (errno))

--- 187 unchanged lines hidden (view full) ---

1372 && server_active
1373 && ! pipeout
1374 && ! file_gzip_level
1375 && ! joining ()
1376 && ! wrap_name_has (finfo->file, WRAP_FROMCVS))
1377 {
1378 revbuf = buf_nonio_initialize ((BUFMEMERRPROC) NULL);
1379 status = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1115 int might_not_exist;
1116{
1117 DIR *dirp;
1118 struct dirent *dp;
1119
1120 if ((dirp = CVS_OPENDIR (dir)) == NULL)
1121 {
1122 if (might_not_exist && existence_error (errno))

--- 187 unchanged lines hidden (view full) ---

1310 && server_active
1311 && ! pipeout
1312 && ! file_gzip_level
1313 && ! joining ()
1314 && ! wrap_name_has (finfo->file, WRAP_FROMCVS))
1315 {
1316 revbuf = buf_nonio_initialize ((BUFMEMERRPROC) NULL);
1317 status = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1380 vers_ts->vn_rcs, vers_ts->vn_tag,
1318 vers_ts->vn_rcs, vers_ts->tag,
1381 vers_ts->options, RUN_TTY,
1382 checkout_to_buffer, revbuf);
1383 }
1384 else
1385#endif
1386 status = RCS_checkout (vers_ts->srcfile,
1387 pipeout ? NULL : finfo->file,
1319 vers_ts->options, RUN_TTY,
1320 checkout_to_buffer, revbuf);
1321 }
1322 else
1323#endif
1324 status = RCS_checkout (vers_ts->srcfile,
1325 pipeout ? NULL : finfo->file,
1388 vers_ts->vn_rcs, vers_ts->vn_tag,
1326 vers_ts->vn_rcs, vers_ts->tag,
1389 vers_ts->options, RUN_TTY,
1390 (RCSCHECKOUTPROC) NULL, (void *) NULL);
1391 }
1392 if (file_is_dead || status == 0)
1393 {
1394 mode_t mode;
1395
1396 mode = (mode_t) -1;

--- 6 unchanged lines hidden (view full) ---

1403 {
1404 struct stat sb;
1405
1406 /* FIXME: We should have RCS_checkout return the mode.
1407 That would also fix the kludge with noexec, above, which
1408 is here only because noexec doesn't write srcfile->path
1409 for us to stat. */
1410 if (stat (vers_ts->srcfile->path, &sb) < 0)
1327 vers_ts->options, RUN_TTY,
1328 (RCSCHECKOUTPROC) NULL, (void *) NULL);
1329 }
1330 if (file_is_dead || status == 0)
1331 {
1332 mode_t mode;
1333
1334 mode = (mode_t) -1;

--- 6 unchanged lines hidden (view full) ---

1341 {
1342 struct stat sb;
1343
1344 /* FIXME: We should have RCS_checkout return the mode.
1345 That would also fix the kludge with noexec, above, which
1346 is here only because noexec doesn't write srcfile->path
1347 for us to stat. */
1348 if (stat (vers_ts->srcfile->path, &sb) < 0)
1349 {
1350 buf_free (revbuf);
1411 error (1, errno, "cannot stat %s",
1412 vers_ts->srcfile->path);
1351 error (1, errno, "cannot stat %s",
1352 vers_ts->srcfile->path);
1353 }
1413 mode = sb.st_mode &~ (S_IWRITE | S_IWGRP | S_IWOTH);
1414 }
1415
1416 if (cvswrite
1417 && !file_is_dead
1418 && !fileattr_get (finfo->file, "_watched"))
1419 {
1420 if (revbuf == NULL)

--- 89 unchanged lines hidden (view full) ---

1510 adding ? "0" : xvers_ts->vn_rcs,
1511 xvers_ts->ts_user, xvers_ts->options,
1512 xvers_ts->tag, xvers_ts->date,
1513 (char *)0); /* Clear conflict flag on fresh checkout */
1514
1515 /* fix up the vers structure, in case it is used by join */
1516 if (join_rev1)
1517 {
1354 mode = sb.st_mode &~ (S_IWRITE | S_IWGRP | S_IWOTH);
1355 }
1356
1357 if (cvswrite
1358 && !file_is_dead
1359 && !fileattr_get (finfo->file, "_watched"))
1360 {
1361 if (revbuf == NULL)

--- 89 unchanged lines hidden (view full) ---

1451 adding ? "0" : xvers_ts->vn_rcs,
1452 xvers_ts->ts_user, xvers_ts->options,
1453 xvers_ts->tag, xvers_ts->date,
1454 (char *)0); /* Clear conflict flag on fresh checkout */
1455
1456 /* fix up the vers structure, in case it is used by join */
1457 if (join_rev1)
1458 {
1459 /* FIXME: Throwing away the original revision info is almost
1460 certainly wrong -- what if join_rev1 is "BASE"? */
1518 if (vers_ts->vn_user != NULL)
1519 free (vers_ts->vn_user);
1520 if (vers_ts->vn_rcs != NULL)
1521 free (vers_ts->vn_rcs);
1522 vers_ts->vn_user = xstrdup (xvers_ts->vn_rcs);
1523 vers_ts->vn_rcs = xstrdup (xvers_ts->vn_rcs);
1524 }
1525
1526 /* If this is really Update and not Checkout, recode history */
1461 if (vers_ts->vn_user != NULL)
1462 free (vers_ts->vn_user);
1463 if (vers_ts->vn_rcs != NULL)
1464 free (vers_ts->vn_rcs);
1465 vers_ts->vn_user = xstrdup (xvers_ts->vn_rcs);
1466 vers_ts->vn_rcs = xstrdup (xvers_ts->vn_rcs);
1467 }
1468
1469 /* If this is really Update and not Checkout, recode history */
1527 if (strcmp (command_name, "update") == 0)
1470 if (strcmp (cvs_cmd_name, "update") == 0)
1528 history_write ('U', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
1529 finfo->repository);
1530
1531 freevers_ts (&xvers_ts);
1532
1533 if (!really_quiet && !file_is_dead)
1534 {
1535 write_letter (finfo, 'U');

--- 30 unchanged lines hidden (view full) ---

1566 /* Not sure if the existence_error check is needed here. */
1567 if (!existence_error (errno))
1568 /* FIXME: should include update_dir in message. */
1569 error (0, errno, "error removing %s", backup);
1570 }
1571 free (backup);
1572 }
1573
1471 history_write ('U', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
1472 finfo->repository);
1473
1474 freevers_ts (&xvers_ts);
1475
1476 if (!really_quiet && !file_is_dead)
1477 {
1478 write_letter (finfo, 'U');

--- 30 unchanged lines hidden (view full) ---

1509 /* Not sure if the existence_error check is needed here. */
1510 if (!existence_error (errno))
1511 /* FIXME: should include update_dir in message. */
1512 error (0, errno, "error removing %s", backup);
1513 }
1514 free (backup);
1515 }
1516
1517 if (revbuf != NULL)
1518 buf_free (revbuf);
1574 return (retval);
1575}
1576
1577#ifdef SERVER_SUPPORT
1578
1579/* This function is used to write data from a file being checked out
1580 into a buffer. */
1581

--- 130 unchanged lines hidden (view full) ---

1712 if (e == NULL)
1713 error (1, errno, "cannot open %s", file1);
1714
1715 data.filename = file1;
1716 data.fp = e;
1717 data.final_nl = 0;
1718 data.compute_checksum = 0;
1719
1519 return (retval);
1520}
1521
1522#ifdef SERVER_SUPPORT
1523
1524/* This function is used to write data from a file being checked out
1525 into a buffer. */
1526

--- 130 unchanged lines hidden (view full) ---

1657 if (e == NULL)
1658 error (1, errno, "cannot open %s", file1);
1659
1660 data.filename = file1;
1661 data.fp = e;
1662 data.final_nl = 0;
1663 data.compute_checksum = 0;
1664
1665 /* FIXME - Passing vers_ts->tag here is wrong in the least number
1666 * of cases. Since we don't know whether vn_user was checked out
1667 * using a tag, we pass vers_ts->tag, which, assuming the user did
1668 * not specify a new TAG to -r, will be the branch we are on.
1669 *
1670 * The only thing it is used for is to substitute in for the Name
1671 * RCS keyword, so in the error case, the patch fails to apply on
1672 * the client end and we end up resending the whole file.
1673 *
1674 * At least, if we are keeping track of the tag vn_user came from,
1675 * I don't know where yet. -DRP
1676 */
1720 retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1677 retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1721 vers_ts->vn_user, (char *) NULL,
1678 vers_ts->vn_user, vers_ts->tag,
1722 vers_ts->options, RUN_TTY,
1723 patch_file_write, (void *) &data);
1724
1725 if (fclose (e) < 0)
1726 error (1, errno, "cannot close %s", file1);
1727
1728 if (retcode != 0 || ! data.final_nl)
1729 fail = 1;

--- 6 unchanged lines hidden (view full) ---

1736
1737 data.filename = file2;
1738 data.fp = e;
1739 data.final_nl = 0;
1740 data.compute_checksum = 1;
1741 cvs_MD5Init (&data.context);
1742
1743 retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1679 vers_ts->options, RUN_TTY,
1680 patch_file_write, (void *) &data);
1681
1682 if (fclose (e) < 0)
1683 error (1, errno, "cannot close %s", file1);
1684
1685 if (retcode != 0 || ! data.final_nl)
1686 fail = 1;

--- 6 unchanged lines hidden (view full) ---

1693
1694 data.filename = file2;
1695 data.fp = e;
1696 data.final_nl = 0;
1697 data.compute_checksum = 1;
1698 cvs_MD5Init (&data.context);
1699
1700 retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
1744 vers_ts->vn_rcs, vers_ts->vn_tag,
1701 vers_ts->vn_rcs, vers_ts->tag,
1745 vers_ts->options, RUN_TTY,
1746 patch_file_write, (void *) &data);
1747
1748 if (fclose (e) < 0)
1749 error (1, errno, "cannot close %s", file2);
1750
1751 if (retcode != 0 || ! data.final_nl)
1752 fail = 1;

--- 105 unchanged lines hidden (view full) ---

1858
1859 Register (finfo->entries, finfo->file, xvers_ts->vn_rcs,
1860 xvers_ts->ts_user, xvers_ts->options,
1861 xvers_ts->tag, xvers_ts->date, NULL);
1862
1863 if (CVS_STAT (finfo->file, file_info) < 0)
1864 error (1, errno, "could not stat %s", finfo->file);
1865
1702 vers_ts->options, RUN_TTY,
1703 patch_file_write, (void *) &data);
1704
1705 if (fclose (e) < 0)
1706 error (1, errno, "cannot close %s", file2);
1707
1708 if (retcode != 0 || ! data.final_nl)
1709 fail = 1;

--- 105 unchanged lines hidden (view full) ---

1815
1816 Register (finfo->entries, finfo->file, xvers_ts->vn_rcs,
1817 xvers_ts->ts_user, xvers_ts->options,
1818 xvers_ts->tag, xvers_ts->date, NULL);
1819
1820 if (CVS_STAT (finfo->file, file_info) < 0)
1821 error (1, errno, "could not stat %s", finfo->file);
1822
1866 /* If this is really Update and not Checkout, recode history */
1867 if (strcmp (command_name, "update") == 0)
1868 history_write ('P', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
1869 finfo->repository);
1823 /* If this is really Update and not Checkout, record history. */
1824 if (strcmp (cvs_cmd_name, "update") == 0)
1825 history_write ('P', finfo->update_dir, xvers_ts->vn_rcs,
1826 finfo->file, finfo->repository);
1870
1871 freevers_ts (&xvers_ts);
1872
1873 if (!really_quiet)
1874 {
1875 write_letter (finfo, 'P');
1876 }
1877 }

--- 50 unchanged lines hidden (view full) ---

1928}
1929
1930#endif /* SERVER_SUPPORT */
1931
1932/*
1933 * Several of the types we process only print a bit of information consisting
1934 * of a single letter and the name.
1935 */
1827
1828 freevers_ts (&xvers_ts);
1829
1830 if (!really_quiet)
1831 {
1832 write_letter (finfo, 'P');
1833 }
1834 }

--- 50 unchanged lines hidden (view full) ---

1885}
1886
1887#endif /* SERVER_SUPPORT */
1888
1889/*
1890 * Several of the types we process only print a bit of information consisting
1891 * of a single letter and the name.
1892 */
1936static void
1893void
1937write_letter (finfo, letter)
1938 struct file_info *finfo;
1939 int letter;
1940{
1941 if (!really_quiet)
1942 {
1943 char *tag = NULL;
1944 /* Big enough for "+updated" or any of its ilk. */

--- 24 unchanged lines hidden (view full) ---

1969 {
1970 sprintf (buf, "-%s", tag);
1971 cvs_output_tagged (buf, NULL);
1972 }
1973 }
1974 return;
1975}
1976
1894write_letter (finfo, letter)
1895 struct file_info *finfo;
1896 int letter;
1897{
1898 if (!really_quiet)
1899 {
1900 char *tag = NULL;
1901 /* Big enough for "+updated" or any of its ilk. */

--- 24 unchanged lines hidden (view full) ---

1926 {
1927 sprintf (buf, "-%s", tag);
1928 cvs_output_tagged (buf, NULL);
1929 }
1930 }
1931 return;
1932}
1933
1934
1935
1977/*
1978 * Do all the magic associated with a file which needs to be merged
1979 */
1980static int
1981merge_file (finfo, vers)
1982 struct file_info *finfo;
1983 Vers_TS *vers;
1984{

--- 58 unchanged lines hidden (view full) ---

2043 write_letter (finfo, 'C');
2044
2045 history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file,
2046 finfo->repository);
2047 retval = 0;
2048 goto out;
2049 }
2050
1936/*
1937 * Do all the magic associated with a file which needs to be merged
1938 */
1939static int
1940merge_file (finfo, vers)
1941 struct file_info *finfo;
1942 Vers_TS *vers;
1943{

--- 58 unchanged lines hidden (view full) ---

2002 write_letter (finfo, 'C');
2003
2004 history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file,
2005 finfo->repository);
2006 retval = 0;
2007 goto out;
2008 }
2009
2051 status = RCS_merge(finfo->rcs, vers->srcfile->path, finfo->file,
2052 vers->options, vers->vn_user, vers->vn_rcs);
2010 status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
2011 vers->options, vers->vn_user, vers->vn_rcs);
2053 if (status != 0 && status != 1)
2054 {
2055 error (0, status == -1 ? errno : 0,
2056 "could not merge revision %s of %s", vers->vn_user, finfo->fullname);
2057 error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
2058 finfo->fullname, backup);
2059 rename_file (backup, finfo->file);
2060 retval = 1;

--- 19 unchanged lines hidden (view full) ---

2080 vers->date, cp);
2081 if (cp)
2082 free (cp);
2083 }
2084
2085 /* fix up the vers structure, in case it is used by join */
2086 if (join_rev1)
2087 {
2012 if (status != 0 && status != 1)
2013 {
2014 error (0, status == -1 ? errno : 0,
2015 "could not merge revision %s of %s", vers->vn_user, finfo->fullname);
2016 error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
2017 finfo->fullname, backup);
2018 rename_file (backup, finfo->file);
2019 retval = 1;

--- 19 unchanged lines hidden (view full) ---

2039 vers->date, cp);
2040 if (cp)
2041 free (cp);
2042 }
2043
2044 /* fix up the vers structure, in case it is used by join */
2045 if (join_rev1)
2046 {
2047 /* FIXME: Throwing away the original revision info is almost
2048 certainly wrong -- what if join_rev1 is "BASE"? */
2088 if (vers->vn_user != NULL)
2089 free (vers->vn_user);
2090 vers->vn_user = xstrdup (vers->vn_rcs);
2091 }
2092
2093#ifdef SERVER_SUPPORT
2094 /* Send the new contents of the file before the message. If we
2095 wanted to be totally correct, we would have the client write

--- 26 unchanged lines hidden (view full) ---

2122 }
2123
2124 if (status == 1)
2125 {
2126 error (0, 0, "conflicts found in %s", finfo->fullname);
2127
2128 write_letter (finfo, 'C');
2129
2049 if (vers->vn_user != NULL)
2050 free (vers->vn_user);
2051 vers->vn_user = xstrdup (vers->vn_rcs);
2052 }
2053
2054#ifdef SERVER_SUPPORT
2055 /* Send the new contents of the file before the message. If we
2056 wanted to be totally correct, we would have the client write

--- 26 unchanged lines hidden (view full) ---

2083 }
2084
2085 if (status == 1)
2086 {
2087 error (0, 0, "conflicts found in %s", finfo->fullname);
2088
2089 write_letter (finfo, 'C');
2090
2130 history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
2091 history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file,
2092 finfo->repository);
2131
2132 }
2133 else if (retcode == -1)
2134 {
2135 error (1, errno, "fork failed while examining update of %s",
2136 finfo->fullname);
2137 }
2138 else
2139 {
2140 write_letter (finfo, 'M');
2141 history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file,
2142 finfo->repository);
2143 }
2144 retval = 0;
2145 out:
2146 free (backup);
2147 return retval;
2148}
2149
2093
2094 }
2095 else if (retcode == -1)
2096 {
2097 error (1, errno, "fork failed while examining update of %s",
2098 finfo->fullname);
2099 }
2100 else
2101 {
2102 write_letter (finfo, 'M');
2103 history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file,
2104 finfo->repository);
2105 }
2106 retval = 0;
2107 out:
2108 free (backup);
2109 return retval;
2110}
2111
2112
2113
2150/*
2151 * Do all the magic associated with a file which needs to be joined
2114/*
2115 * Do all the magic associated with a file which needs to be joined
2152 * (-j option)
2116 * (reached via the -j option to checkout or update).
2117 *
2118 * INPUTS
2119 * finfo File information about the destination file.
2120 * vers The Vers_TS structure for finfo.
2121 *
2122 * GLOBALS
2123 * join_rev1 From the command line.
2124 * join_rev2 From the command line.
2125 * server_active Natch.
2126 *
2127 * ASSUMPTIONS
2128 * 1. Is not called in client mode.
2153 */
2154static void
2155join_file (finfo, vers)
2156 struct file_info *finfo;
2157 Vers_TS *vers;
2158{
2159 char *backup;
2160 char *t_options;

--- 34 unchanged lines hidden (view full) ---

2195 if (jrev2 == NULL)
2196 {
2197 jrev2 = jrev1;
2198 jrev1 = NULL;
2199 jdate2 = jdate1;
2200 jdate1 = NULL;
2201 }
2202
2129 */
2130static void
2131join_file (finfo, vers)
2132 struct file_info *finfo;
2133 Vers_TS *vers;
2134{
2135 char *backup;
2136 char *t_options;

--- 34 unchanged lines hidden (view full) ---

2171 if (jrev2 == NULL)
2172 {
2173 jrev2 = jrev1;
2174 jrev1 = NULL;
2175 jdate2 = jdate1;
2176 jdate1 = NULL;
2177 }
2178
2179 /* FIXME: Need to handle "BASE" for jrev1 and/or jrev2. Note caveat
2180 below about vn_user. */
2181
2203 /* Convert the second revision, walking branches and dates. */
2204 rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, (int *) NULL);
2205
2206 /* If this is a merge of two revisions, get the first revision.
2207 If only one join tag was specified, then the first revision is
2208 the greatest common ancestor of the second revision and the
2209 working file. */
2210 if (jrev1 != NULL)

--- 165 unchanged lines hidden (view full) ---

2376 finfo->repository);
2377#endif
2378 if (! really_quiet)
2379 error (0, 0, "scheduling %s for removal", finfo->fullname);
2380
2381 return;
2382 }
2383
2182 /* Convert the second revision, walking branches and dates. */
2183 rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, (int *) NULL);
2184
2185 /* If this is a merge of two revisions, get the first revision.
2186 If only one join tag was specified, then the first revision is
2187 the greatest common ancestor of the second revision and the
2188 working file. */
2189 if (jrev1 != NULL)

--- 165 unchanged lines hidden (view full) ---

2355 finfo->repository);
2356#endif
2357 if (! really_quiet)
2358 error (0, 0, "scheduling %s for removal", finfo->fullname);
2359
2360 return;
2361 }
2362
2384 /* If the target of the merge is the same as the working file
2385 revision, then there is nothing to do. */
2386 if (vers->vn_user != NULL && strcmp (rev2, vers->vn_user) == 0)
2363 /* If the two merge revisions are the same, then there is nothing
2364 * to do. This needs to be checked before the rev2 == up-to-date base
2365 * revision check tha comes next. Otherwise, rev1 can == rev2 and get an
2366 * "already contains the changes between <rev1> and <rev1>" message.
2367 */
2368 if (rev1 && strcmp (rev1, rev2) == 0)
2387 {
2369 {
2370 free (rev1);
2371 free (rev2);
2372 return;
2373 }
2374
2375 /* If we know that the user file is up-to-date, then it becomes an
2376 * optimization to skip the merge when rev2 is the same as the base
2377 * revision. i.e. we know that diff3(file2,file1,file2) will produce
2378 * file2.
2379 */
2380 if (vers->vn_user != NULL && vers->ts_user != NULL
2381 && strcmp (vers->ts_user, vers->ts_rcs) == 0
2382 && strcmp (rev2, vers->vn_user) == 0)
2383 {
2384 if (!really_quiet)
2385 {
2386 cvs_output (finfo->fullname, 0);
2387 cvs_output (" already contains the differences between ", 0);
2388 cvs_output (rev1 ? rev1 : "creation", 0);
2389 cvs_output (" and ", 0);
2390 cvs_output (rev2, 0);
2391 cvs_output ("\n", 1);
2392 }
2393
2388 if (rev1 != NULL)
2389 free (rev1);
2390 free (rev2);
2394 if (rev1 != NULL)
2395 free (rev1);
2396 free (rev2);
2397
2391 return;
2392 }
2393
2394 /* If rev1 is dead or does not exist, then the file was added
2395 between rev1 and rev2. */
2396 if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1))
2397 {
2398 if (rev1 != NULL)

--- 38 unchanged lines hidden (view full) ---

2437 else
2438 error (0, 0,
2439 "file %s exists, but has been added in revision %s",
2440 finfo->fullname, jrev2);
2441
2442 return;
2443 }
2444
2398 return;
2399 }
2400
2401 /* If rev1 is dead or does not exist, then the file was added
2402 between rev1 and rev2. */
2403 if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1))
2404 {
2405 if (rev1 != NULL)

--- 38 unchanged lines hidden (view full) ---

2444 else
2445 error (0, 0,
2446 "file %s exists, but has been added in revision %s",
2447 finfo->fullname, jrev2);
2448
2449 return;
2450 }
2451
2445 /* If the two merge revisions are the same, then there is nothing
2446 to do. */
2447 if (strcmp (rev1, rev2) == 0)
2448 {
2449 free (rev1);
2450 free (rev2);
2451 return;
2452 }
2453
2454 /* If there is no working file, then we can't do the merge. */
2452 /* If there is no working file, then we can't do the merge. */
2455 if (vers->vn_user == NULL)
2453 if (vers->vn_user == NULL || vers->vn_user[0] == '-')
2456 {
2457 free (rev1);
2458 free (rev2);
2459
2460 if (jdate2 != NULL)
2461 error (0, 0,
2462 "file %s does not exist, but is present in revision %s as of %s",
2463 finfo->fullname, jrev2, jdate2);

--- 7 unchanged lines hidden (view full) ---

2471 return;
2472 }
2473
2474#ifdef SERVER_SUPPORT
2475 if (server_active && !isreadable (finfo->file))
2476 {
2477 int retcode;
2478 /* The file is up to date. Need to check out the current contents. */
2454 {
2455 free (rev1);
2456 free (rev2);
2457
2458 if (jdate2 != NULL)
2459 error (0, 0,
2460 "file %s does not exist, but is present in revision %s as of %s",
2461 finfo->fullname, jrev2, jdate2);

--- 7 unchanged lines hidden (view full) ---

2469 return;
2470 }
2471
2472#ifdef SERVER_SUPPORT
2473 if (server_active && !isreadable (finfo->file))
2474 {
2475 int retcode;
2476 /* The file is up to date. Need to check out the current contents. */
2477 /* FIXME - see the FIXME comment above the call to RCS_checkout in the
2478 * patch_file function.
2479 */
2479 retcode = RCS_checkout (vers->srcfile, finfo->file,
2480 retcode = RCS_checkout (vers->srcfile, finfo->file,
2480 vers->vn_user, (char *) NULL,
2481 vers->vn_user, vers->tag,
2481 (char *) NULL, RUN_TTY,
2482 (RCSCHECKOUTPROC) NULL, (void *) NULL);
2483 if (retcode != 0)
2484 error (1, 0,
2485 "failed to check out %s file", finfo->fullname);
2486 }
2487#endif
2488

--- 29 unchanged lines hidden (view full) ---

2518 RCS_merge gives all kinds of trouble. */
2519 if (vers->vn_user != NULL
2520 && strcmp (rev1, vers->vn_user) == 0
2521 /* See comments above about how No_Difference has already been
2522 called. */
2523 && vers->ts_user != NULL
2524 && strcmp (vers->ts_user, vers->ts_rcs) == 0
2525
2482 (char *) NULL, RUN_TTY,
2483 (RCSCHECKOUTPROC) NULL, (void *) NULL);
2484 if (retcode != 0)
2485 error (1, 0,
2486 "failed to check out %s file", finfo->fullname);
2487 }
2488#endif
2489

--- 29 unchanged lines hidden (view full) ---

2519 RCS_merge gives all kinds of trouble. */
2520 if (vers->vn_user != NULL
2521 && strcmp (rev1, vers->vn_user) == 0
2522 /* See comments above about how No_Difference has already been
2523 called. */
2524 && vers->ts_user != NULL
2525 && strcmp (vers->ts_user, vers->ts_rcs) == 0
2526
2526 /* This is because of the worry below about $Name. If that
2527 isn't a problem, I suspect this code probably works for
2528 text files too. */
2527 /* Avoid this in the text file case. See below for why.
2528 */
2529 && (strcmp (t_options, "-kb") == 0
2530 || wrap_merge_is_copy (finfo->file)))
2531 {
2529 && (strcmp (t_options, "-kb") == 0
2530 || wrap_merge_is_copy (finfo->file)))
2531 {
2532 /* FIXME: what about nametag? What does RCS_merge do with
2533 $Name? */
2534 if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
2535 RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
2532 /* FIXME: Verify my comment below:
2533 *
2534 * RCS_merge does nothing with keywords. It merges the changes between
2535 * two revisions without expanding the keywords (it might expand in
2536 * -kk mode before computing the diff between rev1 and rev2 - I'm not
2537 * sure). In other words, the keyword lines in the current work file
2538 * get left alone.
2539 *
2540 * Therfore, checking out the destination revision (rev2) is probably
2541 * incorrect in the text case since we should see the keywords that were
2542 * substituted into the original file at the time it was checked out
2543 * and not the keywords from rev2.
2544 *
2545 * Also, it is safe to pass in NULL for nametag since we know no
2546 * substitution is happening during the binary mode checkout.
2547 */
2548 if (RCS_checkout ( finfo->rcs, finfo->file, rev2, (char *)NULL, t_options,
2549 RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0 )
2536 status = 2;
2537 else
2538 status = 0;
2539
2540 /* OK, this is really stupid. RCS_checkout carefully removes
2541 write permissions, and we carefully put them back. But
2542 until someone gets around to fixing it, that seems like the
2543 easiest way to get what would seem to be the right mode.

--- 11 unchanged lines hidden (view full) ---

2555 print. */
2556 write_letter (finfo, 'U');
2557 }
2558 else if (strcmp (t_options, "-kb") == 0
2559 || wrap_merge_is_copy (finfo->file)
2560 || special_file_mismatch (finfo, rev1, rev2))
2561 {
2562 /* We are dealing with binary files, or files with a
2550 status = 2;
2551 else
2552 status = 0;
2553
2554 /* OK, this is really stupid. RCS_checkout carefully removes
2555 write permissions, and we carefully put them back. But
2556 until someone gets around to fixing it, that seems like the
2557 easiest way to get what would seem to be the right mode.

--- 11 unchanged lines hidden (view full) ---

2569 print. */
2570 write_letter (finfo, 'U');
2571 }
2572 else if (strcmp (t_options, "-kb") == 0
2573 || wrap_merge_is_copy (finfo->file)
2574 || special_file_mismatch (finfo, rev1, rev2))
2575 {
2576 /* We are dealing with binary files, or files with a
2563 permission/linkage mismatch, and real merging would
2577 permission/linkage mismatch (this second case only occurs when
2578 PRESERVE_PERMISSIONS_SUPPORT is enabled), and real merging would
2564 need to take place. This is a conflict. We give the user
2565 the two files, and let them resolve it. It is possible
2566 that we should require a "touch foo" or similar step before
2567 we allow a checkin. */
2579 need to take place. This is a conflict. We give the user
2580 the two files, and let them resolve it. It is possible
2581 that we should require a "touch foo" or similar step before
2582 we allow a checkin. */
2568 if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
2569 RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
2583 if (RCS_checkout ( finfo->rcs, finfo->file, rev2, (char *)NULL,
2584 t_options, RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
2570 status = 2;
2571 else
2572 status = 0;
2573
2574 /* OK, this is really stupid. RCS_checkout carefully removes
2575 write permissions, and we carefully put them back. But
2576 until someone gets around to fixing it, that seems like the
2577 easiest way to get what would seem to be the right mode.

--- 15 unchanged lines hidden (view full) ---

2593 rev2, finfo->fullname);
2594 error (0, 0, "file from working directory is now in %s", backup);
2595 write_letter (finfo, 'C');
2596 }
2597 else
2598 status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
2599 t_options, rev1, rev2);
2600
2585 status = 2;
2586 else
2587 status = 0;
2588
2589 /* OK, this is really stupid. RCS_checkout carefully removes
2590 write permissions, and we carefully put them back. But
2591 until someone gets around to fixing it, that seems like the
2592 easiest way to get what would seem to be the right mode.

--- 15 unchanged lines hidden (view full) ---

2608 rev2, finfo->fullname);
2609 error (0, 0, "file from working directory is now in %s", backup);
2610 write_letter (finfo, 'C');
2611 }
2612 else
2613 status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
2614 t_options, rev1, rev2);
2615
2601 if (status != 0 && status != 1)
2616 if (status != 0)
2602 {
2617 {
2603 error (0, status == -1 ? errno : 0,
2604 "could not merge revision %s of %s", rev2, finfo->fullname);
2605 error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
2606 finfo->fullname, backup);
2607 rename_file (backup, finfo->file);
2618 if (status != 1)
2619 {
2620 error (0, status == -1 ? errno : 0,
2621 "could not merge revision %s of %s", rev2, finfo->fullname);
2622 error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
2623 finfo->fullname, backup);
2624 rename_file (backup, finfo->file);
2625 }
2608 }
2626 }
2609 free (rev1);
2610 free (rev2);
2627 else /* status == 0 */
2628 {
2629 /* FIXME: the noexec case is broken. RCS_merge could be doing the
2630 xcmp on the temporary files without much hassle, I think. */
2631 if (!noexec && !xcmp (backup, finfo->file))
2632 {
2633 if (!really_quiet)
2634 {
2635 cvs_output (finfo->fullname, 0);
2636 cvs_output (" already contains the differences between ", 0);
2637 cvs_output (rev1, 0);
2638 cvs_output (" and ", 0);
2639 cvs_output (rev2, 0);
2640 cvs_output ("\n", 1);
2641 }
2611
2642
2643 /* and skip the registering and sending the new file since it
2644 * hasn't been updated.
2645 */
2646 goto out;
2647 }
2648 }
2649
2612 /* The file has changed, but if we just checked it out it may
2613 still have the same timestamp it did when it was first
2614 registered above in checkout_file. We register it again with a
2615 dummy timestamp to make sure that later runs of CVS will
2616 recognize that it has changed.
2617
2618 We don't actually need to register again if we called
2619 RCS_checkout above, and we aren't running as the server.

--- 19 unchanged lines hidden (view full) ---

2639 {
2640 server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
2641 backup);
2642 server_updated (finfo, vers, SERVER_MERGED,
2643 (mode_t) -1, (unsigned char *) NULL,
2644 (struct buffer *) NULL);
2645 }
2646#endif
2650 /* The file has changed, but if we just checked it out it may
2651 still have the same timestamp it did when it was first
2652 registered above in checkout_file. We register it again with a
2653 dummy timestamp to make sure that later runs of CVS will
2654 recognize that it has changed.
2655
2656 We don't actually need to register again if we called
2657 RCS_checkout above, and we aren't running as the server.

--- 19 unchanged lines hidden (view full) ---

2677 {
2678 server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
2679 backup);
2680 server_updated (finfo, vers, SERVER_MERGED,
2681 (mode_t) -1, (unsigned char *) NULL,
2682 (struct buffer *) NULL);
2683 }
2684#endif
2685
2686out:
2687 free (rev1);
2688 free (rev2);
2647 free (backup);
2648}
2649
2689 free (backup);
2690}
2691
2692
2693
2650/*
2651 * Report whether revisions REV1 and REV2 of FINFO agree on:
2652 * . file ownership
2653 * . permissions
2654 * . major and minor device numbers
2655 * . symbolic links
2656 * . hard links
2657 *

--- 63 unchanged lines hidden (view full) ---

2721 finfo->file);
2722# endif
2723 }
2724 rev1_hardlinks = list_linked_files_on_disk (finfo->file);
2725 }
2726 else
2727 {
2728 n = findnode (finfo->rcs->versions, rev1);
2694/*
2695 * Report whether revisions REV1 and REV2 of FINFO agree on:
2696 * . file ownership
2697 * . permissions
2698 * . major and minor device numbers
2699 * . symbolic links
2700 * . hard links
2701 *

--- 63 unchanged lines hidden (view full) ---

2765 finfo->file);
2766# endif
2767 }
2768 rev1_hardlinks = list_linked_files_on_disk (finfo->file);
2769 }
2770 else
2771 {
2772 n = findnode (finfo->rcs->versions, rev1);
2729 vp = (RCSVers *) n->data;
2773 vp = n->data;
2730
2731 n = findnode (vp->other_delta, "symlink");
2732 if (n != NULL)
2733 rev1_symlink = xstrdup (n->data);
2734 else
2735 {
2736 n = findnode (vp->other_delta, "owner");
2737 if (n == NULL)

--- 18 unchanged lines hidden (view full) ---

2756 rev1_mode |= S_IFREG;
2757 else
2758 {
2759 /* If the size of `ftype' changes, fix the sscanf call also */
2760 char ftype[16];
2761 if (sscanf (n->data, "%15s %lu", ftype,
2762 &dev_long) < 2)
2763 error (1, 0, "%s:%s has bad `special' newphrase %s",
2774
2775 n = findnode (vp->other_delta, "symlink");
2776 if (n != NULL)
2777 rev1_symlink = xstrdup (n->data);
2778 else
2779 {
2780 n = findnode (vp->other_delta, "owner");
2781 if (n == NULL)

--- 18 unchanged lines hidden (view full) ---

2800 rev1_mode |= S_IFREG;
2801 else
2802 {
2803 /* If the size of `ftype' changes, fix the sscanf call also */
2804 char ftype[16];
2805 if (sscanf (n->data, "%15s %lu", ftype,
2806 &dev_long) < 2)
2807 error (1, 0, "%s:%s has bad `special' newphrase %s",
2764 finfo->file, rev1, n->data);
2808 finfo->file, rev1, (char *)n->data);
2765 rev1_dev = dev_long;
2766 if (strcmp (ftype, "character") == 0)
2767 rev1_mode |= S_IFCHR;
2768 else if (strcmp (ftype, "block") == 0)
2769 rev1_mode |= S_IFBLK;
2770 else
2771 error (0, 0, "%s:%s unknown file type `%s'",
2772 finfo->file, rev1, ftype);

--- 26 unchanged lines hidden (view full) ---

2799 finfo->file);
2800# endif
2801 }
2802 rev2_hardlinks = list_linked_files_on_disk (finfo->file);
2803 }
2804 else
2805 {
2806 n = findnode (finfo->rcs->versions, rev2);
2809 rev1_dev = dev_long;
2810 if (strcmp (ftype, "character") == 0)
2811 rev1_mode |= S_IFCHR;
2812 else if (strcmp (ftype, "block") == 0)
2813 rev1_mode |= S_IFBLK;
2814 else
2815 error (0, 0, "%s:%s unknown file type `%s'",
2816 finfo->file, rev1, ftype);

--- 26 unchanged lines hidden (view full) ---

2843 finfo->file);
2844# endif
2845 }
2846 rev2_hardlinks = list_linked_files_on_disk (finfo->file);
2847 }
2848 else
2849 {
2850 n = findnode (finfo->rcs->versions, rev2);
2807 vp = (RCSVers *) n->data;
2851 vp = n->data;
2808
2809 n = findnode (vp->other_delta, "symlink");
2810 if (n != NULL)
2811 rev2_symlink = xstrdup (n->data);
2812 else
2813 {
2814 n = findnode (vp->other_delta, "owner");
2815 if (n == NULL)

--- 18 unchanged lines hidden (view full) ---

2834 rev2_mode |= S_IFREG;
2835 else
2836 {
2837 /* If the size of `ftype' changes, fix the sscanf call also */
2838 char ftype[16];
2839 if (sscanf (n->data, "%15s %lu", ftype,
2840 &dev_long) < 2)
2841 error (1, 0, "%s:%s has bad `special' newphrase %s",
2852
2853 n = findnode (vp->other_delta, "symlink");
2854 if (n != NULL)
2855 rev2_symlink = xstrdup (n->data);
2856 else
2857 {
2858 n = findnode (vp->other_delta, "owner");
2859 if (n == NULL)

--- 18 unchanged lines hidden (view full) ---

2878 rev2_mode |= S_IFREG;
2879 else
2880 {
2881 /* If the size of `ftype' changes, fix the sscanf call also */
2882 char ftype[16];
2883 if (sscanf (n->data, "%15s %lu", ftype,
2884 &dev_long) < 2)
2885 error (1, 0, "%s:%s has bad `special' newphrase %s",
2842 finfo->file, rev2, n->data);
2886 finfo->file, rev2, (char *)n->data);
2843 rev2_dev = dev_long;
2844 if (strcmp (ftype, "character") == 0)
2845 rev2_mode |= S_IFCHR;
2846 else if (strcmp (ftype, "block") == 0)
2847 rev2_mode |= S_IFBLK;
2848 else
2849 error (0, 0, "%s:%s unknown file type `%s'",
2850 finfo->file, rev2, ftype);

--- 115 unchanged lines hidden ---
2887 rev2_dev = dev_long;
2888 if (strcmp (ftype, "character") == 0)
2889 rev2_mode |= S_IFCHR;
2890 else if (strcmp (ftype, "block") == 0)
2891 rev2_mode |= S_IFBLK;
2892 else
2893 error (0, 0, "%s:%s unknown file type `%s'",
2894 finfo->file, rev2, ftype);

--- 115 unchanged lines hidden ---