#!/bin/bash #------------------------------------------------------------------------------ # Repro for: job085992 set -u # Usage: # ./repro.sh N [-i tweaks_value] [-f] 2>&1 | tee repro.Scenario_N.log # # N is the scenario number, 1, 2, 3, or 4. # Scenario 1: Lost Rename # Scenario 2: Found Rename w/TOFU SNAFU # Scenario 3: No Renames on Main # Scenario 4: Populate/Copy Overlay Model # Scenario 5: Move Tracking with a Branch Spec export P4CONFIG=.p4config export P4ENVIRO=/dev/null/.p4enviro declare Version=1.1.2 # Micro functions. function msg () { echo -e "${1:-Hi}"; } function bail () { msg "Error: ${1:-Unknown Error}"; exit ${2:-1}; } function cmd () { msg "${2:-Executing command: $1}"; $1; return $?; } declare -i shiftArgs=0 declare -i Force=0 declare -i Scenario=1 declare ScenarioTitle= declare StartPointR1= #------------------------------------------------------------------------------ # Command Line Args set +u; while [[ $# -gt 0 ]]; do case $1 in (-f) Force=1;; (1) Scenario=1; ScenarioTitle="Lost Rename";; (2) Scenario=2; ScenarioTitle="Found Rename w/TOFU SNAFU";; (3) Scenario=3; ScenarioTitle="No Renames on Main";; (4) Scenario=4; ScenarioTitle="Populate/Copy Overlay Model";; (5) Scenario=5; ScenarioTitle="Move Tracking with a Branch Spec";; (*) usageError "Unknown arg ($1).";; esac # Shift (modify $#) the appropriate number of times. shift; while [[ $shiftArgs -gt 0 ]]; do [[ $# -eq 0 ]] && usageError "Bad usage." shiftArgs=$shiftArgs-1 shift done done set -u ReproDir=/tmp/repro msg "Started ${0##*/} v$Version at $(date)." msg "ReproDir=$ReproDir" [[ -d $ReproDir && $Force -eq 1 ]] && /bin/rm -rf "$ReproDir" [[ -d $ReproDir ]] && bail "Old repro dir [$ReproDir] exists." mkdir $ReproDir cd $ReproDir msg "==============================================================================\nScenario $Scenario: $ScenarioTitle\n" msg "\nPreliminary info: Show versions of p4/p4d on the PATH:" cmd "p4 -V" cmd "p4d -V" msg "\nPreliminary setup: Spin up a local repo." cmd "p4 init" if [[ $Scenario -eq 5 ]]; then export MT_DEBUG=1 export MT_VERBOSE=1 msg "Creating branch spec r1_to_r2." echo -e "Branch: r1_to_r2\n\nView:\n\t//stream/r1/... //stream/r2/...\n\n" | p4 -s branch -i cmd "cp -p $OLDPWD/MoveTracker.sh ." msg "Installing move tracker trigger." echo -e "Triggers:\n\tMoveTracker.1 change-commit //stream/main/... \"$ReproDir/MoveTracker.sh r1_to_r2 %changelist%\"\n\tMoveTracker.2 change-commit //stream/r2/... \"$ReproDir/MoveTracker.sh r1_to_r2 %changelist%\"\n\n" | p4 -s triggers -i fi msg "\nAdd some files." echo -e "// ONE_H\n#ifndef ONE_H\n#define ONE_H 1\n\n//Stuff goes here\n\n#endif //ONE_H\n" > One.h echo -e "// TWO_H\n#ifndef TWO_H\n#define TWO_H 1\n\n//Stuff goes here\n\n#endif //TWO_H\n" > Two.h cmd "p4 status" msg "Reconcile and submit." p4 rec && p4 submit -d "Added One.h and Two.h in main." msg "\n== Release r1 ==" p4 stream -t release -P //stream/main -o //stream/r1 | p4 stream -i cmd "p4 populate -f -r -S //stream/r1" StartPointR1=$(p4 -ztag -F %change% changes -m 1 //stream/main/...) msg "Start point of r1 on main is change @$StartPointR1." if [[ $Scenario -eq 1 || $Scenario -eq 2 || $Scenario -eq 4 || $Scenario -eq 5 ]]; then msg "\nRename Two.h directly in main." p4 edit Two.h && p4 move Two.h TheNumberTwo.h && p4 submit -d "Rename Two.h in main." fi msg "\n== Release r2 ==" p4 stream -t release -P //stream/main -o //stream/r2 | p4 stream -i if [[ $Scenario -eq 1 || $Scenario -eq 2 || $Scenario -eq 3 || $Scenario -eq 5 ]]; then cmd "p4 populate -f -r -S //stream/r2" elif [[ $Scenario -eq 4 ]]; then msg "Using the Copy Overlay Model to seed r2 with deep history." msg "Seed with start point of r1 on main." cmd "p4 populate -f -r -S //stream/r2 -s //stream/main/...@$StartPointR1" cmd "p4 switch r2" p4 switch msg "Overlay with current tip of main." cmd "p4 copy -F -r -S r2" p4 submit -d "Overlay with current tip of main." fi if [[ $Scenario -eq 3 ]]; then msg "\nRename Two.h in r2." cmd "p4 switch r2" p4 switch p4 edit Two.h && p4 move Two.h TheNumberTwo.h && p4 submit -d "Rename Two.h in r2." fi if [[ $Scenario -eq 1 || $Scenario -eq 3 || $Scenario -eq 4 || $Scenario -eq 5 ]]; then msg "\nReparent flow of change to: r1 --> r2 --> main." msg "This is follow the best practice North of Main merge flow. That means the flow of change for release streams (North of Main, as opposed to development branches that live South of Main), should be managed such that changes flow from older branches to newer ones, to newer, and finally to main. The basic idea is that merge should Laura Wingerd's Google Talk from 2006 reinforces this. Listen to the section from 24:40 – 27:15: http://www.youtube.com/watch?v=AJ-CpGsCpM0 Laura recommends the oldest-to-newest merging model and does a nice job explaining the rationale for it.\n" p4 stream -o //stream/r1|sed s:main:r2:g|p4 stream -i cmd "p4 stream -o //stream/r1" | grep -v '^#' fi msg "\n== Bug Fix in r1 ==" msg "Make changes in r1." cmd "p4 switch r1" p4 switch msg "\nUpdating One.h and Two.h in r1." cmd "p4 edit One.h Two.h" sed 's:Stuff:Cool Stuff:g' One.h > NEW mv -f NEW One.h sed 's:Stuff:Cool Stuff:g' Two.h > NEW mv -f NEW Two.h msg "\nSubmitting." p4 submit -d "Updated One.h and Two.h in r1." if [[ $Scenario -eq 1 || $Scenario -eq 3 || $Scenario -eq 4 ]]; then msg "\nScenario $Scenario: Merging r1->r2 direct." msg "\n== Merging r1 to r2 ==" cmd "p4 switch r2" cmd "p4 switch" msg "\nMerging ..." cmd "p4 merge -S r1" msg "\nResolving with -am ..." cmd "p4 resolve -am" elif [[ $Scenario -eq 5 ]]; then msg "\nScenario $Scenario: Merge using a move-tracking branch spec." msg "\n== Merging r1 to r2 using branch spec r1_to_r2 ==" cmd "p4 switch r2" cmd "p4 switch" msg "\nMerging ..." cmd "p4 merge -b r1_to_r2" msg "\nResolving with -am ..." cmd "p4 resolve -am" msg "Submitting: Merged r1 -> r2." p4 submit -d "Merged r1 -> r2." msg "\nYay! We get the optimal result for rename handling in Scenario 5." fi if [[ $Scenario -eq 1 ]]; then msg "\nUh oh, it lost track of renames, and created an extra file, and" msg "not getting the content to the correct target file. The desired" msg "behaviour when doing 'p4 resolve -am' would be that content from" msg "//stream/r1/Two.h#2 would be propagated to //stream/r2/TheNumberTwo.h.\n" elif [[ $Scenario -eq 3 ]]; then msg "Submitting: Merged r1 -> r2." p4 submit -d "Merged r1 -> r2." msg "\nOK, so we can get the optimal result for rename handling in" msg "Scenario 3 because the integration engine benefits from the renames" msg "occuring directly in the source and target paths." msg "\nThe problem is, renames will surely occur in the mainline between" msg "creation of new release streams. This flow illustrates the engine" msg "does the right thing when renames occur directly in the source and" msg "target stream. The desired behavior is to get this 'Scenario 3'" msg "merge result when we use the basic Scenario 1 flow." elif [[ $Scenario -eq 4 ]]; then msg "Submitting: Merged r1 -> r2." p4 submit -d "Merged r1 -> r2." msg "\nYay! We get the optimal result for rename handling in Scenario 4" msg "by seeding the r2 stream correctly.\n" msg "\nRecap: To create a new stream:\n" msg "Do a 'p4 populate' from main --> new release stream, but starting from" msg "the branch point on main from which the prior release was created." msg "\nThen, do a 'p4 copy' from main -> new release stream, so that the" msg "new stream has content that matches the start of main." fi if [[ $Scenario -eq 2 ]]; then msg "\nScenario 2: Merging 2-step r1->main, main->r2. TOFU SNAFU." msg "\n== Merging r1 to main ==" cmd "p4 switch main" cmd "p4 switch" msg "\nMerging ..." cmd "p4 merge -S r1" msg "\nResolving with -am ..." cmd "p4 resolve -am" msg "Submitting: Merged r1 -> main." p4 submit -d "Merged r1 -> main." cmd "p4 switch r2" cmd "p4 switch" msg "\nMerging main -> r2..." cmd "p4 merge -F -r -S r2" msg "\nResolving with -am ..." cmd "p4 resolve -am" msg "Submitting: Merged main -> r2." p4 submit -d "Merged main -> r2." msg "\nLooks like it's right this time.\n" msg "However, it's suboptimal because:\n" msg "1. We need to use '-F' to Merge up. That's suboptimal. That's a TOFU SNAFU." msg "2. It goes against the North of Main merge flow. The optimal path for" msg "content is to merge from older -> newer -> newer -> main, e.g. " msg "r1 -> r2 -> r3 -> main. Having to merge thru main just to handle" msg "renames properly is wrong." fi exit 0
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 19482 | C. Thomas Tyler | Updated to repro.sh v1.1.2, adding sample MoveTracker.sh. | ||
#5 | 19286 | C. Thomas Tyler |
Added Scenario 5, Move tracking via branch spec, including re-usable StreamMoveTracker.sh script. Added env.sh with convenience alias. Reran test suite to capture slight output normalization tweaks. Removed '-i' flag for toying with dm.integ.tweaks, as it has no effect on the given repro scenarios. |
||
#4 | 19088 | C. Thomas Tyler |
Added Scenario 4, The "North of Main" Populate/Copy Overlay Strategy, which works around the problem. |
||
#3 | 18865 | C. Thomas Tyler |
Added Scenario 1 and 2. Both are broken in different ways. |
||
#2 | 18864 | C. Thomas Tyler | Added job ref. | ||
#1 | 18862 | C. Thomas Tyler | Added repro. |