1 jim.wunderlich 1.1 #//%2006////////////////////////////////////////////////////////////////////////
2 #//
3 #// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 #// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 #// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 #// IBM Corp.; EMC Corporation, The Open Group.
7 #// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 #// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 #// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 #// EMC Corporation; VERITAS Software Corporation; The Open Group.
11 #// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 #// EMC Corporation; Symantec Corporation; The Open Group.
13 #//
14 #// Permission is hereby granted, free of charge, to any person obtaining a copy
15 #// of this software and associated documentation files (the "Software"), to
16 #// deal in the Software without restriction, including without limitation the
17 #// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 #// sell copies of the Software, and to permit persons to whom the Software is
19 #// furnished to do so, subject to the following conditions:
20 #//
21 #// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 jim.wunderlich 1.1 #// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 #// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 #// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 #// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 #// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 #// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 #// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #//
30 #//==============================================================================
31
32 # ============================================================================
33 # File Specific coding convention
34 # ====================================
35 #
36 # There are to levels of usage statements supported within this Makefile.
37 # They are usage and usage_all. These are both implemented by doing a search
38 # across the file for 3 or 2 consecutive # charecters.
39 #
40 # This means all comments not to be dispalyed as part of these usae statements
41 # must be made with a single # charecter.
42 #
43 jim.wunderlich 1.1 # ============================================================================
44
45 ### =========================================================================
46 ###
47 ### Makefile for managing a Pegasus source task branch
48 ###
49 ### Refer to OpenPegasus PEP108 and PEP 248 for more information about
50 ### OpenPegasus use of task branches and processes within OpenPegasus
51 ###
52 ### NOTE:
53 ### This is a Preliminary version for testing.
54 ### The Module is set to junk rather than pegasus
55 ### This has not been tested on Windows
56 ###
57 ## Author: Jim Wunderlich (Jim_Wunderlich@prodigy.net)
58 ##
59 ### ========================================================================
60 ###
61 ### General Guidelines:
62 ### Mnay of the rules will operate from any directory while others require
63 ### them to be executed at a specific directory. The commands that require a
64 jim.wunderlich 1.1 ### a specific location will return an error if they are not executed at the
65 ### appropriate directory. Here are specifics:
66 ###
67 ### The following are directory position independent.
68 ### branch_create, branch_delete, branch_rename
69 ### branch_lists, usage usage_all
|
70 jim.wunderlich 1.2 ### defaults, branch_diff_to_root, branch_diff_to_trunk
|
71 jim.wunderlich 1.1 ### branch_diff_unmerged_branch,
72 ### branch_diff_unmerged_trunk
73 ###
74 ### The following should be excuted from above the $(MODULE) directory.
75 ### Note that some of these commands instantiate the working copy of the
76 ### branch source tree(They have a * before and after them ).
77 ### * branch_checkout *, branch_status
78 ### * branch_merge_in *, branch_merge_in_commit, branch_merge_in_finish
79 ### * branch_merge_out *, branch_merge_out_commit, branch_merge_out_finish
80 ### * branch_migrate *, branch_migrate_commit, branch_migrate_finish
81 ###
82 ### The following can be executed from anyware within a working branch
83 ### source tree.
84 ### branch_commit, branch_diff
85 ###
86 ### These rules all depend on the user having already logged into cvs with
87 ### appropriate user permissions.
88 ###
89 ### These rules do not set or maintain cvs defaults. All cvs defaults should
90 ### come from the users's .cvsrc file. These rules set specific options that
91 ### are required for the operation to be performed.
92 jim.wunderlich 1.1 ###
93 ###
94 ## Functions:
95 ## usage
96 ## usage_all
97 ## defaults
98 ##
99 ## branch_list
100 ## branch_status
101 ## branch_create
102 ## branch_rename
103 ## branch_delete
|
104 jim.wunderlich 1.2 ## branch_checkout
105 ## branch_commit
|
106 jim.wunderlich 1.1 ## branch_diff_to_root
107 ## bracnh_diff_unmerged_branch
108 ## branch_diff_unmerged_trunk
|
109 jim.wunderlich 1.3 ## branch_diff_to_trund
|
110 jim.wunderlich 1.1 ## branch_merge_in
111 ## branch_merge_out
112 ## branch_migrate
113 ##
114 ## ==========================================================================
115 ##
116 ## Tags created/maintained to manage the task branch by the rules within this Makefile
117 ##
118 ## The [BRANCH NAME] is expected to be PEP number like PEP_XXX or
119 ## BUG number like BUG_XXXX and functionality based like like
120 ## PEP_XXX_Config_Changes or BUG_XXXX_Config_changes.
121 ##
122 ##
123 ## Branch and branch management tag naming convention
124 ##
|
125 jim.wunderlich 1.4 ## TASK_[BRANCH_NAME]-[ACTION]_[DIRECTION]_[LOCATION]
|
126 jim.wunderlich 1.1 ##
127 ## Where:
128 ## TASK - is constant to associate all tags to a TASK branch
129 ## BRANCH_NAME - is the name of the branch as described above.
130 ## ACTION - is the action or purpose of the tag. It is one of the following:
131 ## root, branch, merged_in, merged_out, merging_in or merging_out.
132 ## DIRECTION - is the direction of the ACTION relative to the LOCATION.
133 ## LOCATION - is the associated location of the tag. It is either on the trunk
134 ## or branch.
135 ## Note that the ACTION root does not have a DIRECTION or LOCATION
136 ## as it is always on the trunk. This also means that task branches
137 ## do not support sub branches.
138 ## Note that the ACTION branch does not have a DIRECTION or LOCATION
139 ## as it is the branch.
140 ##
|
141 jim.wunderlich 1.4 ## (1) TASK_[BRANCH NAME]-root - tag on trunk representing the
|
142 jim.wunderlich 1.1 ## root of the branch.
143 ##
|
144 jim.wunderlich 1.4 ## (2) TASK_[BRANCH NAME]-branch - head of the branch
|
145 jim.wunderlich 1.1 ##
146 ##
|
147 jim.wunderlich 1.4 ## (3) TASK_[BRANCH NAME]-merged_out_from_trunk - The tag on the trunk which
|
148 jim.wunderlich 1.1 ## marks the place where the last merge out operation occurred.
149 ## It could also be said that changes on the trunk up
150 ## to this label are contained on the branch.
151 ##
|
152 jim.wunderlich 1.4 ## (4) TASK_[BRANCH NAME]-merged_out_to_branch - The tag on the branch which
|
153 jim.wunderlich 1.1 ## marks the place where the last merge out operation occurred.
154 ##
|
155 jim.wunderlich 1.4 ## (5) TASK_[BRANCH NAME]-merged_in_to_trunk - The tag on the trunk which
|
156 jim.wunderlich 1.1 ## marks the place where the last merge in operation occurred.
157 ##
|
158 jim.wunderlich 1.4 ## (6) TASK_[BRANCH NAME]-merged_in_from_branch - The tag on the branch which
|
159 jim.wunderlich 1.1 ## marks the place where the last merge in operation occurred.
160 ## It could also be said that changes on the branch up to
161 ## this label have been merged into the trunk.
162 ##
163 ##
164 ## For Example if the branch name is PEPXX_FUNC then the following tags will
165 ## be in use:
|
166 jim.wunderlich 1.4 ## TASK_PEPXX_FUNC-root
167 ## TASK_PEPXX_FUNC-branch
168 ## TASK_PEPXX_FUNC-merged_in_to_trunk
169 ## TASK_PEPXX_FUNC-merged_out_from_trunk
170 ## TASK_PEPXX_FUNC-merged_in_from_branch
171 ## TASK_PEPXX_FUNC-merged_out_to_branch
|
172 jim.wunderlich 1.1 ##
173 ##
174 ## Consider the following diagram:
175 ##
176 ## NOTE: The numbers in these diagrams refer to the branch maintainence
177 ## symbols above.
178 ##
179 ## After task branch has been created, and changes have been made on both
180 ## the trunk and the branch.
181 ##
182 ## ------------------------------------------------------HEAD
183 ## /
184 ## /
185 ## |
186 ## |
187 ## X--------------------------------------------------------BRANCH (2)
188 ##
189 ## X = 1 = 3 = 4 = 5 = 6
190 ##
191 ##
192 ## After task branch has been merged out once
193 jim.wunderlich 1.1 ## and more changes have been made on both the trunk and the branch.
194 ##
195 ##
196 ## ----Y--------------------------------------------------HEAD
197 ## / \
198 ## / \
199 ## | _\/
200 ## | \
201 ## X-----------Z---------------------------------------------BRANCH (2)
202 ##
203 ## X = 1 = 5 = 6
204 ## Y = 3
205 ## Z = 4
206 ##
207 ##
208 ## After task branch has been merged out several times, merged in once
209 ## and more changes have been made on both the trunk and the branch.
210 ##
211 ## ---------------------Y------------V---------------------HEAD
212 ## / \ \ \ _/
213 ## / \ \ \ /|
214 jim.wunderlich 1.1 ## | _\/ _\/ _\/ /
215 ## | \ \ \ /
216 ## X----------------------------Z--U--------------------------BRANCH (2)
217 ##
218 ## X = 1
219 ## Y = 3
220 ## Z = 4
221 ## U = 6
222 ## V = 5
223 ##
224 ## After branch has been merged out several times, merged in several times
225 ## and more changes have been made on both the trunk and the branch.
226 ##
227 ## -------------------------------------Y-----------V-------HEAD
228 ## / \ \ \ _/ \ _/
229 ## / \ \ \ /| \ /|
230 ## | _\/ _\/ _\/ / _\/ /
231 ## | \ \ \ / \ /
232 ## X--------------------------------------------Z-U-----------BRANCH (2)
233 ##
234 ## X = 1
235 jim.wunderlich 1.1 ## Y = 3
236 ## Z = 4
237 ## U = 6
238 ## V = 5
239 ##
240 ## ==========================================================================
241
242 # ===========================================================================
243 # Area to specifiy include files
244 # ===========================================================================
245
246
247
248 # ===========================================================================
249 # Area to define commands that are platform dependent.
250 #
251 # If these are already set, by a file previously included, then they will not be
252 # set here. In either case it will be verified that the command is on the search
253 # path.
254 #
255 # ===========================================================================
256 jim.wunderlich 1.1 # pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$subst :, ,$(PATH))))
257
258 pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
259
260 MAKE ?= make
261 MAKE_FULL_PATH = $(call pathsearch, $(MAKE))
262
263 CVS ?= cvs
264 CVS_FULL_PATH = $(call pathsearch,$(CVS))
265
266 ECHO ?= echo
267 ECHO_FULL_PATH = $(call pathsearch,$(ECHO))
268
269 GREP ?= grep
270 GREP_FULL_PATH = $(call pathsearch,$(GREP))
271
272
273 PATCH ?= patch
274 PATCH_FULL_PATH = $(call pathsearch,$(PATCH))
275
276
277 jim.wunderlich 1.1
278
279 # ===============================================================================
280 # Shell internal commands
281 # ===============================================================================
282 CD ?= cd
283
284
285 # ===============================================================================
286 # Area to set defaults
287 # ===============================================================================
288
289
290 ROOT ?= $(subst \,/,$(PEGASUS_ROOT))
291
292 FILE_PATH = $(ROOT)/mak
293
294 FILE_NAME = TaskMakefile
295
296
297 FILE = $(FILE_PATH)/$(FILE_NAME)
298 jim.wunderlich 1.1
299
300 # ===============================================================================
301 # The remaining defaults will be set only if they are not already set.
302 # ===============================================================================
303
304 # MODULE_NAME ?= pegasus
305 MODULE_NAME ?= junk
306
307 ifeq ($(MODULE_NAME),pegasus)
308 BFILE ?= env_var.status
309 else
310 # must be junk module
311 BFILE ?= a.cpp
312 endif
313
314 #
315 # diff and rdiff support different options.
316 # diff supports more options than rdiff does.
317 #
318
319 jim.wunderlich 1.1 DIFF_OPTIONS ?=
320
321 RDIFF_OPTIONS ?=
322
323
324 # ==================================================================================
325 # Rule definitions starts here
326 # ==================================================================================
327
328 .PHONY: FORCE
329
330 # =====================
331 # This rule must be the first in the file so if no make command is specified then
332 # the usage information will be displayed.
333 default: usage
334
335 # =====================
336 # assure that a minimum of commands exist.
337 #
338 # Without ECHO and CVS essentially nothing can be done.
339 exists_minimum: exists_MAKE exists_CVS exists_ECHO
340 jim.wunderlich 1.1
341 # ======================
342 # assure that MAKE exists
343 #
344 exists_MAKE: FORCE
345 ifeq ($(MAKE_FULL_PATH),)
|
346 jim.wunderlich 1.4 $(error ERROR: MAKE command ($(MAKE)) not found in PATH $(PATH))
|
347 jim.wunderlich 1.1 endif
348
349
350 # ======================
351 # assure that CVS exists
352 #
353 exists_CVS: FORCE
354 ifeq ($(CVS_FULL_PATH),)
|
355 jim.wunderlich 1.4 $(error ERROR: CVS command ($(CVS)) not found in PATH $(PATH))
|
356 jim.wunderlich 1.1 endif
357
358
359 # ======================
360 # assure that PATCH exists
361 #
362 exists_PATCH: FORCE
363 ifeq ($(PATCH_FULL_PATH),)
|
364 jim.wunderlich 1.4 $(error ERROR: PATCH command ($(PATCH)) not found in PATH $(PATH))
|
365 jim.wunderlich 1.1 endif
366
367 # ======================
368 # assure that GREP exists
369 #
370 exists_GREP: FORCE
371 ifeq ($(GREP_FULL_PATH),)
|
372 jim.wunderlich 1.4 $(error ERROR: GREP command ($(GREP)) not found in PATH $(PATH))
|
373 jim.wunderlich 1.1 endif
374
375 # ======================
376 # assure that ECHO exists
377 #
378 exists_ECHO: FORCE
379 ifeq ($(ECHO_FULL_PATH),)
|
380 jim.wunderlich 1.4 $(error ERROR: ECHO command ($(ECHO)) not found in PATH $(PATH))
|
381 jim.wunderlich 1.1 endif
382
383
384
385 # ======================
386 # assure that BNAME exists
387 #
388 exists_BNAME: FORCE
389 ifeq ($(BNAME),)
390 @ $(ECHO)
391 @ $(ECHO) " BNAME not set, set is on the command line. "
392 @ $(ECHO) " IE: $(MAKE) -f $(FILE_NAME) [command] BNAME=PEPX_Y "
393 @ $(ECHO)
394 @ $(MAKE) -f $(FILE) parm_error PARM_MSG="BNAME not set"
395 endif
396
397 # ======================
398 # assure that NEW_BNAME exists
399 #
400 exists_NEW_BNAME: FORCE
401 ifeq ($(NEW_BNAME),)
402 jim.wunderlich 1.1 @ $(ECHO)
403 @ $(ECHO) " NEW_BNAME not set, set is on the command line. "
404 @ $(ECHO) " IE: $(MAKE) -f $(FILE_NAME) [command] NEW_BNAME=PEPX_Y "
405 @ $(ECHO)
406 @ $(MAKE) -f $(FILE) parm_error PARM_MSG="NEW_BNAME not set"
407 endif
408
409 parm_error: FORCE
|
410 jim.wunderlich 1.4 $(error ERROR: $(PARM_MSG))
|
411 jim.wunderlich 1.1
412
413
414 ## =====================
415 ##
416 ### Function: usage - displays usage information
417 ## Usage: usage
418 ##
419 usage: exists_GREP
420 @ $(GREP) "\#\#\#" $(FILE)
421
422 ## =====================
423 ##
424 ### Function: usage_all - displays usage information
425 ## Usage: usage_all
426 ##
427 usage_all: exists_GREP
428 @ $(GREP) "\#\#" $(FILE)
429
430 ## =====================
431 ##
432 jim.wunderlich 1.1 ### Function: defaults - displays default settings
433 ## Usage: defaults
434 ##
435 defaults: exists_minimum
436 @ $(ECHO) =======================================================================
437 @ $(ECHO)
438 @ $(ECHO) "CVS defaults should be set within the .cvsrc file."
439 @ $(ECHO)
440 @ $(ECHO) --------------------------
441 @ $(ECHO) "Default External Commands used within this Makefile"
442 @ $(ECHO)
443 @ $(ECHO) "CVS = $(CVS)"
444 @ $(ECHO) "CVS_FULL_PATH = $(CVS_FULL_PATH)"
445 @ $(ECHO)
446 @ $(ECHO) "PATCH = $(PATCH)"
447 @ $(ECHO) "PATCH_FULL_PATH = $(PATCH_FULL_PATH)"
448 @ $(ECHO)
449 @ $(ECHO) "GREP = $(GREP)"
450 @ $(ECHO) "GREP_FULL_PATH = $(GREP_FULL_PATH)"
451 @ $(ECHO)
452 @ $(ECHO) "ECHO = $(ECHO)"
453 jim.wunderlich 1.1 @ $(ECHO) "ECHO_FULL_PATH = $(ECHO_FULL_PATH)"
454 @ $(ECHO)
455 @ $(ECHO) --------------------------
456 @ $(ECHO) "Defaults used within this Makefile."
457 @ $(ECHO)
458 @ $(ECHO) "FILE_PATH = $(FILE_PATH)"
459 @ $(ECHO) "FILE_NAME = $(FILE_NAME)"
460 @ $(ECHO)
461 @ $(ECHO) --------------------------
462 @ $(ECHO) "Defaults used within this Makefile that can be overridden from the"
463 @ $(ECHO) " command line."
464 @ $(ECHO)
465 @ $(ECHO) "MODULE_NAME = $(MODULE_NAME)"
466 @ $(ECHO) "BFILE = $(BFILE)"
467 @ $(ECHO)
468 @ $(ECHO) "DIFF_OPTIONS = $(DIFF_OPTIONS)"
469 @ $(ECHO) "RDIFF_OPTIONS = $(RDIFF_OPTIONS)"
470 @ $(ECHO)
471 @ $(ECHO) "For example"
472 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_checkout BNAME=PEPX_Y MODULE=module"
473 @ $(ECHO)
474 jim.wunderlich 1.1 @ $(ECHO) =======================================================================
475
476 ## =====================
477 ##
478 ### Function: branch_list - List branches and other symbolic links
479 ## Usage: branch_list [BFILE=(FILE NAME)]
480 ##
481 ## Note: A log is performed on a chosen file, such as the env_var.status
482 ## file since it has been in the trunk for a while, having most
483 ## symbolic variables assigned to it, and very few revisions.
484 ##
485 branch_list: exists_minimum
486 -$(CVS) rlog $(MODULE_NAME)/$(BFILE) | $(GREP) TASK
487
488
489 # =====================
490 ##
491 ### Function: branch_status - Show "branch" status
492 ## Usage: branch_status [BFILE=(FILE NAME)]
493 ##
494 ## Note: Must be executed from the directory above $(MODULE_NAME),
495 jim.wunderlich 1.1 ## the top of the trunk.
496 ##
497 ## Note: A log is performed on a chosen file, such as the env_var.status
498 ## file since it has been in the trunk for a while, having most
499 ## symbolic variables assigned to it, and very few revisions.
500 ##
501 branch_status: exists_minimum
502 $(CD) $(MODULE_NAME)
503 $(CVS) status $(MODULE_NAME)/$(BFILE)
504
505
506
507 ## =====================
508 ##
509 ### Function: branch_create - Creates branch and the tags to manage it.
510 ## Usage: branch_create BNAME=(BRANCH NAME)
511 ##
512 ##
513 ## Process:
514 ## Create "root" tag on main branch
515 ## Create "branch" using the "root" tag
516 jim.wunderlich 1.1 ## Create a "merged_in_to_trunk" tag for later use in the merge in.
517 ## Create a "merged_out_from_trunk" tag for later use in the merge out.
518 ## Create a "merged_in_from_branch" tag for later use in the merge in.
519 ## Create a "merged_out_to_branch" tag for later use in the merge out.
520 ##
521 ##
522 branch_create: exists_minimum exists_BNAME
|
523 jim.wunderlich 1.4 $(CVS) rtag -f TASK_$(BNAME)-root $(MODULE_NAME)
524 $(CVS) rtag -b -r TASK_$(BNAME)-root TASK_$(BNAME)-branch $(MODULE_NAME)
525 $(CVS) rtag -r TASK_$(BNAME)-root TASK_$(BNAME)-merged_in_to_trunk $(MODULE_NAME)
526 $(CVS) rtag -r TASK_$(BNAME)-root TASK_$(BNAME)-merged_out_from_trunk $(MODULE_NAME)
527 $(CVS) rtag -r TASK_$(BNAME)-branch TASK_$(BNAME)-merged_in_from_branch $(MODULE_NAME)
528 $(CVS) rtag -r TASK_$(BNAME)-branch TASK_$(BNAME)-merged_out_to_branch $(MODULE_NAME)
|
529 jim.wunderlich 1.1
530
531 ## =====================
532 ##
533 ### Function: branch_rename - Renames existing branch and all the tags to manage it.
534 ## Usage: branch_rename BNAME=(OLD NAME) NEW_BNAME=(NEW NAME)
535 ##
536 ##
537 ## Process:
|
538 jim.wunderlich 1.4 ## Rename TASK_[BNAME]-root to TASK_[NEW_BNAME]-root
539 ## Rename TASK_[BNAME]-branch to TASK_[NEW_BNAME]-branch
540 ## Rename TASK_[BNAME]-merged_in_to_trunk
541 ## to TASK_[NEW_BNAME]-merged_in_to_trunk
542 ## Rename TASK_[BNAME]-merged_out_from_trunk
543 ## to TASK_[NEW_BNAME]-merged_out_from_trunk
544 ## Rename TASK_[BNAME]-merged_in_from_branch
545 ## to TASK_[NEW_BNAME]-merged_in_from_branch
546 ## Rename TASK_[BNAME]-merged_out_to_branch
547 ## to TASK_[NEW_BNAME]-merged_out_to_branch
548 ## Delete Branch TASK_[BNAME]
|
549 jim.wunderlich 1.1 ##
550 branch_rename: exists_minimum exists_BNAME exists_NEW_BNAME
|
551 jim.wunderlich 1.4 ifeq ($(BNAME),$(NEW_BNAME))
552 $(error ERROR: BNAME=NEW_BNAME=($(BNAME)), They must be different.)
553 endif
554 $(CVS) rtag -r TASK_$(BNAME)-root TASK_$(NEW_BNAME)-root $(MODULE_NAME)
555 $(CVS) rtag -b -r TASK_$(BNAME)-branch TASK_$(NEW_BNAME)-branch $(MODULE_NAME)
556 $(CVS) rtag -r TASK_$(BNAME)-merged_in_to_trunk TASK_$(NEW_BNAME)-merged_in_to_trunk $(MODULE_NAME)
557 $(CVS) rtag -r TASK_$(BNAME)-merged_out_from_trunk TASK_$(NEW_BNAME)-merged_out_from_trunk $(MODULE_NAME)
558 $(CVS) rtag -r TASK_$(BNAME)-merged_in_from_branch TASK_$(NEW_BNAME)-merged_in_from_branch $(MODULE_NAME)
559 $(CVS) rtag -r TASK_$(BNAME)-merged_out_to_branch TASK_$(NEW_BNAME)-merged_out_to_branch $(MODULE_NAME)
|
560 jim.wunderlich 1.1 $(MAKE) -f $(FILE) branch_delete BNAME=$(BNAME)
561
562
563 ## =====================
564 ##
565 ### Function: branch_delete - Delete the named branch and its management tags.
566 ## Usage: branch_delete BNAME=(BRANCH NAME)
567 ##
568 ## Process:
569 ## Delete "root" tag
570 ## Delete the "merged_in_to_trunk" tag.
571 ## Delete the "merged_out_from_trunk" tag.
572 ## Delete the "merged_in_from_branch" tag.
573 ## Delete the "merged_out_to_branch" tag.
574 ## Delete the "merging_in_to_trunk" tag.
575 ## Delete the "merging_out_from_trunk" tag.
576 ## Delete the "merging_in_from_branch" tag.
577 ## Delete the "merging_out_to_branch" tag.
578 ## Delete the branch
579 ##
580 ##
581 jim.wunderlich 1.1 branch_delete: exists_minimum exists_BNAME
|
582 jim.wunderlich 1.4 $(CVS) rtag -d TASK_$(BNAME)-root $(MODULE_NAME)
583 $(CVS) rtag -d TASK_$(BNAME)-merged_in_to_trunk $(MODULE_NAME)
584 $(CVS) rtag -d TASK_$(BNAME)-merged_out_from_trunk $(MODULE_NAME)
585 $(CVS) rtag -d TASK_$(BNAME)-merged_in_from_branch $(MODULE_NAME)
586 $(CVS) rtag -d TASK_$(BNAME)-merged_out_to_branch $(MODULE_NAME)
587 $(CVS) rtag -d TASK_$(BNAME)-merging_in_to_trunk $(MODULE_NAME)
588 $(CVS) rtag -d TASK_$(BNAME)-merging_out_from_trunk $(MODULE_NAME)
589 $(CVS) rtag -d TASK_$(BNAME)-merging_in_from_branch $(MODULE_NAME)
590 $(CVS) rtag -d TASK_$(BNAME)-merging_out_to_branch $(MODULE_NAME)
591 $(CVS) rtag -B -d TASK_$(BNAME)-branch $(MODULE_NAME)
|
592 jim.wunderlich 1.1
593 ## =====================
594 ##
595 ### Function: branch_checkout - checks out the head of the branch trunk
596 ## Aliases: branch_co
597 ## Usage: branch_checkout BNAME=(BRANCH NAME)
598 ## Note: Must be executed from the directory where the top pegasus
599 ## directory shall be placed.
600 ##
601 branch_co branch_checkout: exists_minimum
|
602 jim.wunderlich 1.4 $(CVS) checkout -r TASK_$(BNAME)-branch $(MODULE_NAME)
|
603 jim.wunderlich 1.1
604
605 ## =====================
606 ##
607 ### Function: branch_commit - checks into the head of the branch trunk
608 ## Aliases: branch_ci
609 ## Usage: branch_ci BNAME=(BRANCH NAME)
610 ## Note: Must be executed from within a directory of a working trunk
611 ##
612 branch_ci branch_commit: exists_minimum
613 $(CVS) commit $(MODULE_NAME)
614
615
616 ## =====================
617 ##
618 ### Function: branch_diff - diffs current working tree to the head of the
619 ### branch tree
620 ## Usage: branch_diff [DIFF_OPTIONS=(OPTIONS)]
621 ## Note: Must be executed from within a directory of a working tree
622 ##
623 branch_diff: exists_minimum
624 jim.wunderlich 1.1 $(CVS) diff $(DIFF_OPTIONS) $(MODULE_NAME)
625
626 ## =====================
627 ##
628 ### Function: branch_diff_to_root - diffs branch to its root
629 ## Usage: branch_diff_to_root BNAME=(BRANCH NAME) [RDIFF_OPTIONS=(OPTIONS)]
630 ##
631 branch_diff_to_root: exists_minimum exists_BNAME
|
632 jim.wunderlich 1.4 $(CVS) rdiff $(RDIFF_OPTIONS) -r TASK_$(BNAME)-root -r TASK_$(BNAME)-branch $(MODULE_NAME)
|
633 jim.wunderlich 1.1
634 ## =====================
635 ##
636 ### Function: branch_diff_to_trunk - diffs branch head to the head of the trunk
637 ## Usage: branch_diff_to_trunk BNAME=(BRANCH NAME) [RDIFF_OPTIONS=(OPTIONS)]
638 ##
639 branch_diff_to_trunk: exists_minimum exists_BNAME
|
640 jim.wunderlich 1.4 $(CVS) rdiff $(RDIFF_OPTIONS) -r TASK_$(BNAME)-branch $(MODULE_NAME)
|
641 jim.wunderlich 1.1
642 ## =====================
643 ##
644 ### Function: branch_diff_unmerged_branch - shows all changes on the
645 ### branch since the last merge in.
646 ## Usage: branch_diff_unmerged_branch BNAME=(BRANCH NAME) [RDIFF_OPTIONS=(OPTIONS)]
647 ##
648 branch_diff_unmerged_branch: exists_minimum exists_BNAME
|
649 jim.wunderlich 1.4 $(CVS) rdiff $(RDIFF_OPTIONS) -r TASK_$(BNAME)-merged_in_from_branch -r TASK_$(BNAME)-branch $(MODULE_NAME)
|
650 jim.wunderlich 1.1
651
652 ## =====================
653 ##
654 ### Function: branch_diff_unmerged_trunk - shows all changes on the
655 ### trunk since the last merge out
656 ## Usage: branch_diff_unmerged_trunk BNAME=(BRANCH NAME) [RDIFF_OPTIONS=(OPTIONS)]
657 ##
658 branch_diff_unmerged_trunk: exists_minimum exists_BNAME
|
659 jim.wunderlich 1.4 $(CVS) rdiff $(RDIFF_OPTIONS) -r TASK_$(BNAME)-merged_out_from_trunk $(MODULE_NAME)
|
660 jim.wunderlich 1.1
661
662 ## =====================
663 ##
664 ### Function: branch_merge_in - starts the two part process to merge
665 ### the changes in the branch into the trunk.
666 ## Usage: branch_merge_in BNAME=(BRANCH NAME)
667 ##
668 ## Note: Must be executed from the directory where the top pegasus
669 ## directory shall be placed when the checkout is performed
670 ## to instantiate the working copy of the trunk within which
|
671 jim.wunderlich 1.3 ## the merge will be performed.
672 ##
673 ## Note: You can start this process over prior to the commit by
674 ## removing the working copy of the tree and starting over with
675 ## the branch_merge_in command.
|
676 jim.wunderlich 1.1 ##
677 ## Process:
678 ##
679 ## branch_merge_in BNAME=(BRANCH NAME)
680 ## - Tag main trunk with the merging_in_to_trunk tag.
681 ## - Tag branch with the merging_in_from_branch tag.
682 ## - Checkout the trunk head into a working copy of the trunk.
683 ## NOTE: The merging_in tag is not used because that
684 ## would result in a sticky tag that will preclude the
685 ## subsequent commit of the merged files. The
686 ## merging_in tag is created because if any other commits
687 ## occur while the merge is in process they will be detected
688 ## and merged on the subsequent merge_in. It is safer to
689 ## do this than to risk the chance of missing a commit.
690 ## - Use update to merge in the branch changes since last the merge_in.
691 ## - Manually resolve any conflicts in the working copy of the trunk.
692 ##
693 ## branch_merge_in_commit BNAME=(BRANCH NAME)
|
694 jim.wunderlich 1.3 ## - Check in merged changes from the working copy of the trunk in.
695 ## - executes branch_merge_in_finish
696 ##
697 ## If you chose to do a manual checkin then execute branch_merge_in_finish
|
698 jim.wunderlich 1.1 ##
699 ## branch_merge_in_finish BNAME=(BRANCH NAME)
700 ## - Move the merged_in_to_trunk tag to the merging_in_to_trunk tag
701 ## - Move the merged_in_from_branch tag to
702 ## the merging_in_from_branch tag
|
703 jim.wunderlich 1.4 ## - Delete the TASK_$(BNAME)-merging_in_to_trunk tag
704 ## - Delete the TASK_$(BNAME)-merging_in_from_branch tag
|
705 jim.wunderlich 1.1 ##
706 ##
707 branch_merge_in: exists_minimum exists_BNAME
|
708 jim.wunderlich 1.4 $(CVS) rtag -F TASK_$(BNAME)-merging_in_to_trunk $(MODULE_NAME)
709 $(CVS) rtag -F -r TASK_$(BNAME)-branch TASK_$(BNAME)-merging_in_from_branch $(MODULE_NAME)
|
710 jim.wunderlich 1.1 $(CVS) checkout -P $(MODULE_NAME)
711 $(CD) $(MODULE_NAME)
|
712 jim.wunderlich 1.4 $(CVS) update -P -d -j TASK_$(BNAME)-merged_in_from_branch -j TASK_$(BNAME)-merging_in_from_branch $(MODULE_NAME)
|
713 jim.wunderlich 1.1 @ $(ECHO)
714 @ $(ECHO) Differences from branch now merged into
715 @ $(ECHO) the local working copy of the trunk.
716 @ $(ECHO)
717 @ $(ECHO) Now manually:
718 @ $(ECHO) 1. Resolve any merge conflicts.
719 @ $(ECHO) 2. Review differences to assure commit integrity.
|
720 jim.wunderlich 1.4 @ $(ECHO) That is do not check in unintended white space changes,
|
721 jim.wunderlich 1.1 @ $(ECHO) test or debug code.
722 @ $(ECHO) 3. Check for aded files and directories and do a cvs add
723 @ $(ECHO) command for them.
724 @ $(ECHO)
725 @ $(ECHO) Then check in the files. Either manually or by using
726 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_merge_in_ci BNAME=$(BNAME)"
727 @ $(ECHO) within the $(MODULE_NAME) directory.
728 @ $(ECHO)
729 @ $(ECHO) If you chose to do a manual commit then after the commit
730 @ $(ECHO) is complete then do a:
731 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_merge_in_finish BNAME=$(BNAME)"
732 @ $(ECHO) within the $(MODULE_NAME) directory to reset the appropriate
733 @ $(ECHO) branch management tags.
734 @ $(ECHO)
|
735 jim.wunderlich 1.3 @ $(ECHO) You can start this process over prior to the commit by removing
736 @ $(ECHO) the working copy of the tree and then start over with
737 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_merge_in BNAME=$(BNAME)"
738 @ $(ECHO)
|
739 jim.wunderlich 1.1 @ $(ECHO)
740
741
742 branch_merge_in_ci branch_merge_in_commit: exists_minimum exists_BNAME
743 $(CD) $(MODULE_NAME)
744 $(CVS) commit
745 @ $(ECHO)
746 @ $(ECHO) Check in of merged files from branch into trunk complete.
747 @ $(ECHO)
748 $(MAKE) -f $(FILE) branch_merge_in_finish BNAME=$(BNAME)
749
750
751 branch_merge_in_finish: exists_minimum exists_BNAME
|
752 jim.wunderlich 1.4 $(CVS) rtag -F -r TASK_$(BNAME)-merging_in_to_trunk TASK_$(BNAME)-merged_in_to_trunk $(MODULE_NAME)
753 $(CVS) rtag -F -r TASK_$(BNAME)-merging_in_from_branch TASK_$(BNAME)-merged_in_from_branch $(MODULE_NAME)
754 $(CVS) rtag -d TASK_$(BNAME)-merging_in_to_trunk $(MODULE_NAME)
755 $(CVS) rtag -d TASK_$(BNAME)-merging_in_from_branch $(MODULE_NAME)
|
756 jim.wunderlich 1.1 @ $(ECHO)
757 @ $(ECHO) Branch Management tags have now been updated to reflect the new branch status.
758 @ $(ECHO)
759
760
761
762 ## =====================
763 ###
764 ### Function: branch_merge_out - starts the two part process to merge
765 ### the changes in the trunk into the branch.
766 ## Usage: branch_merge_out BNAME=(BRANCH NAME)
767 ##
768 ## Note: Must be executed from the directory where the top pegasus
769 ## directory shall be placed when the checkout is performed
770 ## to instantiate the working copy of the trunk within which
771 ## the merge will be performed
772 ##
|
773 jim.wunderlich 1.3 ## Note: You can start this process over prior to the commit by
774 ## removing the working copy of the tree and starting over with
775 ## the branch_merge_out command.
776 ##
|
777 jim.wunderlich 1.1 ## Process:
778 ##
779 ## branch_merge_out BNAME=(BRANCH NAME)
780 ## - Tag main trunk with the merging_out_from_trunk tag.
781 ## - Tag branch with the merging_out_to_branch tag.
782 ## - Checkout the trunk head into a working copy of the trunk.
783 ## NOTE: The merging_out tag is not used because that
784 ## would result in a Sticky tag that will preclude the
785 ## subsequent commit of the merged files. The
786 ## mergeing_out tag is created because if any other commits
787 ## occur while the merge is in process they will be detected
788 ## and merged on the subsequent merge_out. It is safer to
789 ## do this than to risk the chance of missing a commit.
790 ## - Use update to merge in the trunk changes since last the merge_out.
|
791 jim.wunderlich 1.3 ## - Manually resolve any conflicts in the working copy of the branch.
|
792 jim.wunderlich 1.1 ##
793 ## branch_merge_out_commit BNAME=(BRANCH NAME)
|
794 jim.wunderlich 1.3 ## - Check in merged changes from the working copy of the branch in.
795 ## - executes branch_merge_out_finish
796 ##
797 ## If you chose to do a manual checkin then execute branch_merge_out_finish
|
798 jim.wunderlich 1.1 ##
799 ## branch_merge_out_finish BNAME=(BRANCH NAME)
800 ## - Move the merged_out_from_trunk tag to the merging_out_from_trunk tag
801 ## - Move the merged_out_to_branch tag to
802 ## the merging_out_to_branch tag
|
803 jim.wunderlich 1.4 ## - Delete the TASK_$(BNAME)-merging_out_from_trunk tag
804 ## - Delete the TASK_$(BNAME)-merging_out_to_branch tag
|
805 jim.wunderlich 1.1 ##
806 ##
807 branch_merge_out: exists_minimum exists_BNAME
|
808 jim.wunderlich 1.4 $(CVS) rtag -F TASK_$(BNAME)-merging_out_from_trunk $(MODULE_NAME)
809 $(CVS) rtag -F -r TASK_$(BNAME)-branch TASK_$(BNAME)-merging_out_to_branch $(MODULE_NAME)
810 $(CVS) checkout -P -r TASK_$(BNAME)-branch $(MODULE_NAME)
|
811 jim.wunderlich 1.1 $(CD) $(MODULE_NAME)
|
812 jim.wunderlich 1.4 $(CVS) update -d -j TASK_$(BNAME)-merged_out_from_trunk -j TASK_$(BNAME)-merging_out_from_trunk
|
813 jim.wunderlich 1.1 @ $(ECHO)
814 @ $(ECHO) Differences from trunk now merged into
815 @ $(ECHO) the local working copy of the branch.
816 @ $(ECHO)
817 @ $(ECHO) Now manually:
818 @ $(ECHO) 1. Resolve any merge conflicts.
819 @ $(ECHO) 2. Check for added files and directories and do a cvs add
820 @ $(ECHO) command for them.
821 @ $(ECHO)
822 @ $(ECHO) Then check in the files. Either manually or by using
823 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_merge_out_ci BNAME=$(BNAME)"
824 @ $(ECHO) within the $(MODULE_NAME) directory.
825 @ $(ECHO)
826 @ $(ECHO) If you chose to do a manual commit then after the commit
827 @ $(ECHO) is complete do a:
828 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_merge_out_finish BNAME=$(BNAME)"
829 @ $(ECHO) within the $(MODULE_NAME) directory to reset the appropriate
830 @ $(ECHO) branch management tags.
831 @ $(ECHO)
|
832 jim.wunderlich 1.3 @ $(ECHO) You can start this process over prior to the commit by removing
833 @ $(ECHO) the working copy of the tree and then start over with
834 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_merge_out BNAME=$(BNAME)"
835 @ $(ECHO)
|
836 jim.wunderlich 1.1 @ $(ECHO)
837
838 branch_merge_out_ci branch_merge_out_commit: exists_minimum exists_BNAME
839 $(CD) $(MODULE_NAME)
840 $(CVS) commit
841 @ $(ECHO)
842 @ $(ECHO) Check in of merged files from trunk into branch is complete.
843 @ $(ECHO)
844 $(MAKE) -f $(FILE) branch_merge_out_finish BNAME=$(BNAME)
845
846 branch_merge_out_finish: exists_minimum exists_BNAME
|
847 jim.wunderlich 1.4 $(CVS) rtag -F -r TASK_$(BNAME)-merging_out_from_trunk TASK_$(BNAME)-merged_out_from_trunk $(MODULE_NAME)
848 $(CVS) rtag -F -r TASK_$(BNAME)-merging_out_to_branch TASK_$(BNAME)-merged_out_to_branch $(MODULE_NAME)
849 $(CVS) rtag -d TASK_$(BNAME)-merging_out_from_trunk $(MODULE_NAME)
850 $(CVS) rtag -d TASK_$(BNAME)-merging_out_to_branch $(MODULE_NAME)
|
851 jim.wunderlich 1.1 @ $(ECHO)
852 @ $(ECHO) Branch Management tags have now been updated to reflect the new branch status.
853 @ $(ECHO)
854
855
856
857
858 ## =====================
859 ###
860 ### Function: branch_migrate - starts the process to migrate the
861 ### branch to the HEAD of the trunk.
862 ###
863 ## Usage: branch_migrate BNAME=(BRANCH NAME)
864 ##
865 ## Note: Must be executed from the directory where the top pegasus
866 ## directory shall be placed when the checkout is performed
867 ## to instantiate the working copy of the trunk within which
|
868 jim.wunderlich 1.3 ## the merge will be performed.
869 ##
870 ## Note: You can start this process over prior to the commit by
871 ## removing the working copy of the tree and doing a
872 ## "branch_delete (BNAME)_new" and then starting over with
873 ## the branch_migrate command.
|
874 jim.wunderlich 1.1 ##
875 ## Process:
876 ##
877 ## branch_migrate BNAME=(BRANCH NAME)
878 ## - get diffs of unmerged_changes_branch into a local patch_diff file.
879 ## - create the new branch to migrate to.
880 ## - Checkout the new branch
881 ## - Apply the patch_diff file to the working trunk
882 ## - Manually resolve any merge conflicts in the working trunk.
883 ##
884 ## branch_migrate_commit BNAME=(BRANCH NAME)
885 ## - Commit the changes into the new branch
886 ##
887 ## EITHER
888 ## branch_migrate_finish BNAME=(BRANCH NAME)
889 ## - Remove the old branch.
890 ## - Rename all branch tags
891 ##
892 ## OR
893 ## branch_rename BNAME=(BRANCH_NAME)_new NEW_BNAME=(BRANCH NAME)_X
894 ##
895 jim.wunderlich 1.1 ##
896 branch_migrate: exists_minimum exists_BNAME
897 $(MAKE) -f $(FILE) branch_diff_unmerged_branch BNAME=$(BNAME) 1>branch_migrate_diffs
898 $(MAKE) -f $(FILE) branch_create BNAME=$(BNAME)_new
|
899 jim.wunderlich 1.4 $(CVS) checkout -P -r TASK_$(BNAME)_new-branch $(MODULE_NAME)
|
900 jim.wunderlich 1.1 $(PATCH) -b -p0 --global-reject-file=global-reject-patch-file < branch_migrate_diffs
901 @ $(ECHO)
902 @ $(ECHO)
903 @ $(ECHO) Differences from previous branch are now merged into
904 @ $(ECHO) the local working copy of the new branch.
905 @ $(ECHO)
906 @ $(ECHO) Now manually:
907 @ $(ECHO) 1. Resolve any merge conflicts.
908 @ $(ECHO) Check the global-patch-reject file in this directory.
909 @ $(ECHO) If it does not exist then there were no patch errors.
910 @ $(ECHO) 2. Check for added files and directories and do a cvs add
911 @ $(ECHO) command for them prior to the commit..
912 @ $(ECHO)
913 @ $(ECHO) Then check in the files. Either manually or by using
914 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_migrate_ci BNAME=$(BNAME)"
915 @ $(ECHO) within the $(MODULE_NAME) directory.
916 @ $(ECHO)
|
917 jim.wunderlich 1.3 @ $(ECHO) After the commit is complete do either one of the following
918 @ $(ECHO) dependent on wheter you want the previous branch deleted or saved.
919 @ $(ECHO)
920 @ $(ECHO) This will delete the previous branch and move the branch management.
921 @ $(ECHO)
922 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_migrate_finish BNAME=$(BNAME)"
|
923 jim.wunderlich 1.1 @ $(ECHO) within the $(MODULE_NAME) directory to reset the appropriate
924 @ $(ECHO) branch management tags.
925 @ $(ECHO)
|
926 jim.wunderlich 1.3 @ $(ECHO) This will rename the branch just migrated to keeping the old branch.
927 @ $(ECHO)
928 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_rename BNAME=$(BNAME)_new NEW_BNAME=$(BNAME)_(VER)"
929 @ $(ECHO)
930 @ $(ECHO) You can start this process over prior to the commit by removing
931 @ $(ECHO) the working copy of the tree and then deleting the new branch this
932 @ $(ECHO) process created with
|
933 jim.wunderlich 1.1 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_delete BNAME=$(BNAME)_new"
|
934 jim.wunderlich 1.3 @ $(ECHO) and then start over with
935 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_migrate BNAME=$(BNAME)"
936 @ $(ECHO)
|
937 jim.wunderlich 1.1 @ $(ECHO)
938
939 branch_migrate_ci branch_migrate_commit: exists_minimum exists_BNAME
940 $(CD) $(MODULE_NAME)
941 $(CVS) commit
942 @ $(ECHO)
943 @ $(ECHO) Check in of merged files from previous branch into
944 @ $(ECHO) new branch is complete.
945 @ $(ECHO)
946 $(CD) ..
947 $(MAKE) -f $(FILE) branch_diff_to_root BNAME=$(BNAME) > diff_to_root_$(BNAME)
948 $(MAKE) -f $(FILE) branch_diff_to_root BNAME=$(BNAME)_new > diff_to_root_$(BNAME)_new
949 @ $(ECHO) Do a
950 @ $(ECHO) " diff diff_to_root_$(BNAME) diff_to_root_$(BNAME)_new"
|
951 jim.wunderlich 1.4 @ $(ECHO) to verify TASK_$(BNAME)_new has all the changes.
|
952 jim.wunderlich 1.1 @ $(ECHO)
953 @ $(ECHO) Then do a
954 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_migrate_finish BNAME=$(BNAME)"
|
955 jim.wunderlich 1.4 @ $(ECHO) which will remove TASK_$(BNAME), the old branch, and then rename TASK_$(BNAME)_new to TASK_$(BNAME)
|
956 jim.wunderlich 1.1 @ $(ECHO) Alternatively you can keep the old branch around for a while and just
957 @ $(ECHO) rename the new branch by doing a
958 @ $(ECHO) " $(MAKE) -f $(FILE_NAME) branch_rename BNAME=$(BNAME)_new NEW_BNAME=($BNAME)_X"
959 @ $(ECHO) where X is something you chose to identify the new branch.
960
961
962 branch_migrate_finish: exists_minimum exists_BNAME
963 $(MAKE) -f $(FILE) branch_delete BNAME=$(BNAME)
964 $(MAKE) -f $(FILE) branch_rename BNAME=$(BNAME)_new NEW_BNAME=$(BNAME)
965 @ $(ECHO)
966 @ $(ECHO) Branch Management tags have now been updated to reflect the new branch status.
967 @ $(ECHO)
968
969
970
971
|