;;; Copyright (C) 2006 Magnus Henoch ;;; ;;; This program is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 2 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (in-package :darcs) (defun pull (ourrepo &optional theirrepo) "Pull new patches from THEIRREPO into OURREPO. If THEIRREPO is not specified, use default repositiory specified in preferences." (setf ourrepo (fad:pathname-as-directory ourrepo)) (unless theirrepo (setf theirrepo (car (get-preflist ourrepo "defaultrepo"))) (unless theirrepo (error "No remote repositiory specified, and no default available."))) (let ((our-patchinfo (read-repo-patch-list ourrepo)) (their-patchinfo (read-repo-patch-list theirrepo))) (multiple-value-bind (common only-ours only-theirs) (get-common-and-uncommon our-patchinfo their-patchinfo) (declare (ignore common)) (format t "~&Found these new patches:") (dolist (p only-theirs) (format t "~& - ~A" p)) ;; XXX: This is where we pick which of their patches we want to ;; pull. (let* ((their-patches (mapcar (lambda (pi) (read-patch-from-repo theirrepo pi)) only-theirs)) (our-patches (mapcar (lambda (pi) (read-patch-from-repo ourrepo pi)) only-ours)) (merged-patches (patches (merge-patches (make-instance 'composite-patch :patches their-patches) (make-instance 'composite-patch :patches our-patches))))) (format t "~&Applying patches") (let ((applying-to-source t) (source-and-pristine-differ nil)) (dolist (p merged-patches) ;; First, copy the modified patch to the repository. (write-patch-to-repo p ourrepo) ;; Then, apply it to the pristine copy. This couldn't ;; possibly fail. (apply-patch-to-pristine p ourrepo) ;; Note the patch in the inventory. (append-inventory ourrepo (named-patch-patchinfo p)) ;; And finally apply the patch to the real source. This ;; could fail if the source has been modified. Deal with ;; that in a crude way. XXX: it is wasteful to apply ;; patches twice. (when applying-to-source (restart-case (apply-patch p ourrepo) (skip-this () :report "Don't apply this patch to the source tree (it was applied to the pristine tree)" (setf source-and-pristine-differ t)) (skip-all () :report "Stop trying to apply patches to the source tree (they will be applied to the pristine tree)" (setf source-and-pristine-differ t) (setf applying-to-source nil)))) (format t ".")) (when source-and-pristine-differ (format t "~&~"))))) (format t "~&All done")))