#!/bin/bash MYP4BIN=$HOME/bin MYPLAT="bin.darwin90x86_64" P4BIN=$MYP4BIN/p4.bin P4DBIN=$MYP4BIN/p4d.bin if [ ! -f $P4BIN ]; then echo "Downloading required Perforce binaries for $MYPLAT ..." which wget > /dev/null if [ -z $? ]; then wget -q -O $P4BIN ftp://ftp.perforce.com/perforce/r14.1/$MYPLAT/p4 wget -q -O $P4DBIN ftp://ftp.perforce.com/perforce/r14.1/$MYPLAT/p4d else curl -q -o $P4BIN ftp://ftp.perforce.com/perforce/r14.1/$MYPLAT/p4 curl -q -o $P4DBIN ftp://ftp.perforce.com/perforce/r14.1/$MYPLAT/p4d fi chmod a+x $P4BIN chmod a+x $P4DBIN echo "Done." fi # Check every so often like every 32 times or so if [ $(($RANDOM / 911)) -eq 0 ]; then THIS_REV=16 NEWER_REV=$(($THIS_REV+1)) cur=$(curl -o /dev/null --silent --head --write-out "%{http_code}\n" https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4?v=$NEWER_REV) if [ "$cur" == "200" ]; then echo "A newer version of myp4 is available" echo "https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4" fi fi if [ -z "$P4CONFIG" ]; then export P4CONFIG=".myp4" fi if [ -z "$P4IGNORE" ]; then export P4IGNORE=".myp4ignore" fi rootDir=`$P4BIN -ztag set | \ egrep "^P4CONFIG=$P4CONFIG" | \ cut -d "'" -f 2 | \ sed "s/$P4CONFIG/.myp4d/"` if [ "$rootDir" == 'noconfig' ]; then if [ "$1" != 'init' ]; then $P4BIN "$@" exit $? fi echo 'Initializing...' baseDir="$PWD" if [ -n "$2" ]; then baseDir="$PWD/$2" fi rootDir="$baseDir/.myp4d" if [ -d $rootDir ]; then echo "Perforce storage already maps to $rootDir" exit 1 fi mkdir -p $rootDir cat > $baseDir/$P4CONFIG < $baseDir/$P4IGNORE < $baseDir/.gitignore < /dev/null $P4BIN depot -d depot > /dev/null $P4BIN depot -o branch | $P4BIN depot -i > /dev/null $P4BIN client -o branches-master | \ sed -e 's=//branch/... //branches-master/...=//branch/master/... //branches-master/...=' \ -e 's/noallwrite/allwrite/' \ -e 's/normdir/rmdir/' \ -e 's/submitunchanged/revertunchanged/' | \ $P4BIN client -i > /dev/null $P4BIN client -o -t branches-master | \ $P4BIN client -i > /dev/null exit 0 fi if [ ! -d $rootDir ]; then $P4BIN "$@" exit $? fi curBranch=`$P4BIN client -o | \ egrep "//branch/[^/]+/... " | head -1 | \ sed -e 's=^.*//branch/==' -e 's=/[.][.][.].*$=='` P4USER=$USER P4CLIENT=$USER case $1 in init) echo "Already within a Perforce storage structure: $rootDir" exit 1 ;; checkpoint) $P4BIN reconcile -f //$P4CLIENT/... oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | grep 'no file(s) to reconcile' | wc -l) if [ $oops -eq 0 ]; then echo "There is a problem with reconcile. Fix it before continuing" exit 1 fi cnt=$($P4BIN -ztag opened //$P4CLIENT/... 2>&1 | wc -l) if [ $cnt -gt 0 ]; then if [ -z "$2" ]; then $P4BIN submit -d "Auto-checkpoint" else $P4BIN submit -d "$2" fi fi exit 0 ;; branches) for f in `$P4BIN -ztag clients -e 'branches-*' | \ grep '... client ' | \ sed -e 's/branches-//' -e 's/... client //'`; do if [ "$f" == "$curBranch" ]; then echo "$f *" else echo $f fi done echo " (use 'p4 branchspecs' to list out branchspecs)" exit 0 ;; switch) toBranch="$2" if [ -z "$toBranch" ]; then echo "Current branch $curBranch" exit 0 fi branch_client=`$P4BIN -ztag clients -e "branches-$2" | \ grep "... client " | \ sed -e 's/... client //'` if [ -z "$branch_client" ]; then echo "Branch $2 does not exist, yet" exit 1 fi if [ "$toBranch" == "$curBranch" ]; then echo "Already there, wasn't that fast?" exit 0 fi work=`$P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l` if [ $work -eq 0 ]; then work=`$P4BIN -ztag status //$P4CLIENT/... 2> /dev/null | wc -l` fi if [ $work -gt 0 ]; then echo "There are pending changes, how do you want to proceed?" # One day add in (m) Move changes read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \ answer case $answer in s) newChange=`$P4BIN change -o | \ sed -e "s//Shelf for $curBranch/" | \ $P4BIN change -i | sed -e 's/^Change //' -e 's/ .*//'` $P4BIN reconcile -f -c $newChange //$P4CLIENT/... oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | grep 'no file(s) to reconcile' | wc -l) if [ $oops -eq 0 ]; then echo "There is a problem with reconcile. Fix it before continuing" exit 1 fi $P4BIN shelve -c $newChange > /dev/null $P4BIN key "branchShelf-$USER-$curBranch" $newChange > /dev/null $P4BIN revert -w //branch/$curBranch/... > /dev/null ;; r) read -p 'New files will be deleted, edits discarded, etc. Are you sure? (y/n) ' \ answer if [ "$answer" == "y" ]; then $P4BIN reconcile -f //$P4CLIENT/... > /dev/null 2> /dev/null $P4BIN revert -w //branch/$curBranch/... else echo "Aborting..." exit 1 fi ;; q) exit 0 ;; esac fi echo "Switch from $curBranch to $toBranch" if [ -z "$branch_client" ]; then $P4BIN client -o | \ sed -e "s=//branch/[^/]*/... //$USER/...=//branch/$toBranch/... //$USER/...=" | \ $P4BIN client -i > /dev/null else $P4BIN client -o -t $branch_client | \ $P4BIN client -i > /dev/null fi $P4BIN sync -q //$P4CLIENT/... 2> /dev/null curShelf=`$P4BIN key "branchShelf-$USER-$toBranch"` if [ $curShelf != 0 ]; then echo "Unshelving $curShelf" $P4BIN unshelve -s $curShelf $P4BIN shelve -d -c $curShelf > /dev/null $P4BIN change -d $curShelf > /dev/null $P4BIN key -d "branchShelf-$USER-$toBranch" > /dev/null fi exit 0 ;; branch) newBranch=$2 if [ -z "$newBranch" ]; then echo "Current branch $curBranch" exit 0 fi branch_client=`$P4BIN -ztag clients -e "branches-$2" | \ grep "... client " | \ sed -e 's/... client //'` if [ -n "$branch_client" ]; then echo "Existing branch $newBranch" echo "Perhaps you meant to say: p4 switch $newBranch" exit 1 fi if [[ $newBranch == *-* ]]; then echo "Branch names cannot contain dashes." echo " (use 'p4 branchspec NAME' to create/edit branchspecs)" exit 1 fi work=`$P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l` if [ $work -eq 0 ]; then work=`$P4BIN -ztag status //$P4CLIENT/... 2> /dev/null | wc -l` fi if [ $work -gt 0 ]; then echo "There are pending changes, how do you want to proceed?" # One day add in (m) Move changes read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \ answer case $answer in s) newChange=`$P4BIN change -o | \ sed -e "s//Shelf for $curBranch/" | \ $P4BIN change -i | sed -e 's/^Change //' -e 's/ .*//'` $P4BIN reconcile -f -c $newChange //$P4CLIENT/... oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | grep 'no file(s) to reconcile' | wc -l) if [ $oops -eq 0 ]; then echo "There is a problem with reconcile. Fix it before continuing" exit 1 fi $P4BIN shelve -c $newChange > /dev/null $P4BIN key "branchShelf-$USER-$curBranch" $newChange > /dev/null $P4BIN revert -w //branch/$curBranch/... > /dev/null ;; r) read -p 'New files will be deleted, edits discarded, etc. Are you sure? (y/n) ' \ answer if [ "$answer" == "y" ]; then $P4BIN reconcile -f //$P4CLIENT/... > /dev/null 2> /dev/null $P4BIN revert -w //branch/$curBranch/... else echo "Aborting..." exit 1 fi ;; q) exit 0 ;; esac fi emptyBranch=`$P4BIN -ztag files -m1 ... 2> /dev/null | egrep '^[.][.][.]' | wc -l` if [ $emptyBranch == 0 ]; then echo "No files to branch" else $P4BIN populate -d "Branching //branches/$curBranch to //branches/$newBranch" \ //branch/$curBranch/... //branch/$newBranch/... if [ $? != 0 ]; then echo "Failed to create branch $2 mapping to //branch/$newBranch" exit 1 fi fi mkdir -p $rootDir/branch/$newBranch echo "Switch from $curBranch to $newBranch" $P4BIN client -o -t branches-master branches-$newBranch | \ sed -e "s=//branch/[^/]*/... //=//branch/$newBranch/... //=" | \ $P4BIN client -i > /dev/null $P4BIN client -o -t branches-$newBranch | \ $P4BIN client -i > /dev/null $P4BIN sync -q //$P4CLIENT/... 2> /dev/null exit 0 ;; mergefrom) fromBranch="$2" if [ -z "$fromBranch" ]; then echo 'Please specify the branch from which to merge' exit 1 fi branch_client=`$P4BIN -ztag clients -e "branches-$fromBranch" | \ grep "... client " | \ sed -e 's/... client //'` if [ -z "$branch_client" ]; then echo "Branch $2 does not exist" exit 1 fi if [ "$fromBranch" == "$curBranch" ]; then echo 'Mobius branches are not supported' exit 0 fi work=`$P4BIN -ztag opened //$P4CLIENT/... 2> /dev/null | wc -l` if [ $work -eq 0 ]; then work=`$P4BIN -ztag status //$P4CLIENT/... 2> /dev/null | wc -l` fi if [ $work -gt 0 ]; then echo "There are pending changes, how do you want to proceed?" read -p '(s) Shelve changes for later (r) Revert changes (q) Quit? ' \ answer case $answer in s) newChange=`$P4BIN change -o | \ sed -e "s//Shelf for $curBranch/" | \ $P4BIN change -i | sed -e 's/^Change //' -e 's/ .*//'` $P4BIN reconcile -f -c $newChange //$P4CLIENT/... oops=$($P4BIN reconcile -n -f //$P4CLIENT/... 2>&1 | grep 'no file(s) to reconcile' | wc -l) if [ $oops -eq 0 ]; then echo "There is a problem with reconcile. Fix it before continuing" exit 1 fi $P4BIN shelve -c $newChange > /dev/null $P4BIN key "branchShelf-$USER-$curBranch" $newChange > /dev/null $P4BIN revert -w //branch/$curBranch/... > /dev/null ;; r) read -p 'New files will be deleted, edits discarded, etc. Are you sure? (y/n) ' \ answer if [ "$answer" == "y" ]; then $P4BIN reconcile -f //$P4CLIENT/... > /dev/null 2> /dev/null $P4BIN revert -w //branch/$curBranch/... else echo "Aborting..." exit 1 fi ;; q) exit 0 ;; esac fi integ_dir="" branch_branch=`$P4BIN -ztag branches -e "merge-$fromBranch-$curBranch" | \ grep "... branch " | \ sed -e 's/... branch //'` if [ -z "$branch_branch" ]; then branch_branch=`$P4BIN -ztag branches -e "merge-$curBranch-$fromBranch" | \ grep "... branch " | \ sed -e 's/... branch //'` integ_dir="-r" fi if [ -z "$branch_branch" ]; then # Simple integ, perhaps complexFrom=`$P4BIN -ztag client -o branches-$fromBranch | egrep '^... View1'` complexTo=`$P4BIN -ztag client -o branches-$curBranch | egrep '^... View1'` if [ "$complexFrom" != "" ]; then echo "$fromBranch is complex aka multiple lines in View" echo "Need to define a branchspec for $fromBranch-$curBranch" exit 1 fi if [ -n "$complexTo" ]; then echo "$curBranch is complex aka multiple lines in View" echo "Need to define a branchspec for $fromBranch-$curBranch" exit 1 fi $P4BIN integ //branch/$fromBranch/... //branch/$curBranch/... $P4BIN resolve -am else # Defined integ, simple echo "Merging using branchspec $branch_branch" $P4BIN integ -b $branch_branch $integ_dir $P4BIN resolve -am fi echo "Assuming no issues, you should now submit..." ;; branchspecs) shift $P4BIN branches "$@" ;; branchspec) shift $P4BIN branch "$@" ;; help) $P4BIN "$@" echo echo "Extra local commands:" echo " p4 switch {branchName} Switch to specified branch or report current" echo " p4 branch {newBranchName} Create new branch or report current" echo " p4 branches List the defined branches" echo echo " p4 branchspecs List out the branchspecs" echo " p4 branchspec FROM-TO Define how to merge between two branches" echo " Only needed if branches use multi-line views" echo " p4 mergefrom BRANCHNAME Run integ from named branch into current one" ;; *) $P4BIN "$@" exit $? ;; esac