#!/bin/bash
MYP4BIN=$HOME/bin
P4BIN=$MYP4BIN/p4.bin
P4DBIN=$MYP4BIN/p4d.bin
if [ ! -f $P4BIN ]; then
what=$(uname)
if [ "$what" == 'Darwin' ]; then
MYPLAT="bin.darwin90x86_64"
else
MYPLAT="bin.linux26x86_64"
fi
echo "Downloading required Perforce binaries for $MYPLAT ..."
which wget > /dev/null
if [ $? -eq 0 ]; then
wget -q -O $P4BIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4
wget -q -O $P4DBIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4d
else
curl -q -o $P4BIN ftp://ftp.perforce.com/perforce/r14.2/$MYPLAT/p4
curl -q -o $P4DBIN ftp://ftp.perforce.com/perforce/r14.2/$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 [ "$1" == "check" ] || [ $(($RANDOM / 911)) -eq 0 ]; then
THIS_REV=29
NEWER_REV=$(($THIS_REV+1))
which wget > /dev/null
if [ $? -eq 0 ]; then
wget -S --spider \
https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4?v=$NEWER_REV \
> /dev/null 2> /dev/null
if [ $? -eq 0 ]; then
echo "A newer version of myp4 is available"
echo "https://swarm.workshop.perforce.com/files/guest/alan_h_teague/myp4/p4"
elif [ "$1" == "check" ]; then
echo "No newer version is available"
exit 0
fi
else
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"
elif [ "$1" == "check" ]; then
echo "No newer version is available"
exit 0
fi
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" <<FOOBAR
P4USER=$USER
P4CLIENT=$USER
P4IGNORE=$P4IGNORE
P4PORT=rsh:$P4DBIN -r "$rootDir" -Llog_file -i -vserver=3
FOOBAR
cat > "$baseDir/$P4IGNORE" <<FOOBAR
.git
.gitignore
$P4CONFIG
.myp4d
$P4IGNORE
*.swp
FOOBAR
cat > "$baseDir/.gitignore" <<FOOBAR
.git
.gitignore
$P4CONFIG
.myp4d
$P4IGNORE
*.swp
FOOBAR
cd "$baseDir"
$P4BIN configure set serviceUser=$USER > /dev/null
$P4BIN depot -d depot > /dev/null
$P4BIN depot -o branch | $P4BIN depot -i > /dev/null
$P4BIN protect -o | $P4BIN protect -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/nomodtime/modtime/' \
-e 's/submitunchanged/revertunchanged/' | \
$P4BIN client -i > /dev/null
# Create the initial client
$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
;;
server)
if [ -z "$2" ]; then
echo ":1666" > "$rootDir/myPort"
else
echo "$2" > "$rootDir/myPort"
fi
port=$(head -1 "$rootDir/myPort")
$P4DBIN -r "$rootDir" -vserver=3 -Llog_file -p $port -d
echo "Stop server by running: p4 -p $port admin stop"
exit 0
;;
checkpoint)
$P4BIN reconcile -m -f //$P4CLIENT/...
oops=$($P4BIN reconcile -n -m -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
;;
switch)
if [ "$2" == '-a' ]; then
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
exit 0
fi
if [ "$2" != '-b' ]; then
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 (use -b to create)"
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/<enter description here>/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 -s -t $branch_client > /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
fi
newBranch=$3
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 (i.e., no -b)"
exit 1
fi
if [[ $newBranch == *-* ]]; then
echo "Branch names cannot contain dashes."
exit 1
fi
if [[ $newBranch =~ \ ]]; then
echo "Branch names cannot contain spaces."
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/<enter description here>/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
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 -s -t branches-$newBranch > /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/<enter description here>/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 merge-$fromBranch-$curBranch"
$P4BIN -ztag client -o branches-$fromBranch | \
egrep '^... View[0-9]' | \
awk '{ print $3; }' > .$$.left
$P4BIN -ztag client -o branches-$curBranch | \
egrep '^... View[0-9]' | \
awk '{ print $3; }' > .$$.right
echo "Something like: p4 branchspec merge-$fromBranch-$curBranch"
echo "View:"
lcnt=$(wc -l .$$.left | awk '{ print $1;}' )
rcnt=$(wc -l .$$.right | awk '{ print $1;}' )
if [ $lcnt -lt $rcnt ]; then
num=$(($rcnt - $lcnt))
for(( i=0; i < $num; i++ )); do
echo "//???/..." >> .$$.left
done
elif [ $rcnt -lt $lcnt ]; then
num=$(($lcnt - $rcnt))
for(( i=0; i < $num; i++ )); do
echo "//???/..." >> .$$.right
done
fi
paste .$$.left .$$.right | sed -e 's/^/ /'
\rm .$$.left .$$.right
exit 1
fi
if [ -n "$complexTo" ]; then
echo "$curBranch is complex aka multiple lines in View"
echo "Need to define a branchspec for merge-$fromBranch-$curBranch"
$P4BIN -ztag client -o branches-$fromBranch | \
egrep '^... View[0-9]' | \
awk '{ print $3; }' > .$$.left
$P4BIN -ztag client -o branches-$curBranch | \
egrep '^... View[0-9]' | \
awk '{ print $3; }' > .$$.right
echo "Something like: p4 branchspec merge-$fromBranch-$curBranch"
echo "View:"
lcnt=$(wc -l .$$.left | awk '{ print $1;}' )
rcnt=$(wc -l .$$.right | awk '{ print $1;}' )
if [ $lcnt -lt $rcnt ]; then
num=$(($rcnt - $lcnt))
for(( i=0; i < $num; i++ )); do
echo "//???/..." >> .$$.left
done
elif [ $rcnt -lt $lcnt ]; then
num=$(($lcnt - $rcnt))
for(( i=0; i < $num; i++ )); do
echo "//???/..." >> .$$.right
done
fi
paste .$$.left .$$.right | sed -e 's/^/ /'
\rm .$$.left .$$.right
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..."
;;
help)
$P4BIN "$@"
echo
echo "Extra local commands:"
echo " p4 switch {branchName} Switch to specified branch or report current"
echo " p4 switch -b newBranchName Create new branch"
echo " p4 switch -a List the defined branches"
echo
echo " p4 branch 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"
echo " Only needed if branches use multi-line views"
echo " p4 checkpoint {description} Reconcile and submit if needed"
echo " p4 server {port} Start up a network accessible p4d linked to"
echo " this Perforce storage structure"
echo " p4 check Force a check for updates of myp4"
;;
*)
$P4BIN "$@"
exit $?
;;
esac
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #29 | 10704 | Alan H Teague | Updating to 14.2 p4/p4d binaries | ||
| #28 | 9724 | Alan H Teague | Clean up help | ||
| #27 | 9700 | Alan H Teague | Adding in p4 check command | ||
| #26 | 9175 | Alan H Teague | Revise new version check to work on systems without curl | ||
| #25 | 9136 | Alan H Teague | fix incorrect test and try to guess platform | ||
| #24 | 9029 | Alan H Teague | update the rev counter | ||
| #23 | 9028 | Alan H Teague |
Remove 'p4 branch' 'p4 branches' 'p4 branchspec' 'p4 branchspecs' Add 'p4 switch -a' to list all branches Add 'p4 switch -b NEWBRANCH' to create new branch Update help accordingly |
||
| #22 | 9027 | Alan H Teague | use client -s -t to switch client view | ||
| #21 | 9022 | Alan H Teague | use modtime and -m for checkpoint | ||
| #20 | 8982 | Alan H Teague | Suggest a merge branchspec for complex branches | ||
| #19 | 8974 | Alan H Teague |
Exclude vi .swp files Switch from back-tick to $() syntax for subcommands |
||
| #18 | 8921 | Alan H Teague |
Allow for spaces in directory names Update help for current set of commands Prevent creating of branches which contain spaces |
||
| #17 | 8920 | Alan H Teague | Add in 'p4 server {port}' to launch network server | ||
| #16 | 8918 | Alan H Teague | Add 'p4 checkpoint' command to reconcile/submit | ||
| #15 | 8891 | Alan H Teague | don't check for new versions often | ||
| #14 | 8878 | Alan H Teague | Fix inserted issues, correct test | ||
| #13 | 8877 | Alan H Teague | Missing fi fi fi | ||
| #12 | 8876 | Alan H Teague | set version | ||
| #11 | 8875 | Alan H Teague | Add rcs'ism | ||
| #10 | 8874 | Alan H Teague | Fix reconcile bug - aka losing files | ||
| #9 | 8861 | Alan H Teague |
Cleanup return codes Normalize test of strings exist/not exist |
||
| #8 | 8860 | Alan H Teague |
Modify myp4 to use existing P4CONFIG and P4IGNORE values. This change also simplifies the root construction code a bit. #review @alan_h_teague Will make some immediate changes... ;-) |
||
| #7 | 8806 | Alan H Teague |
Revert back to using branch instead of newbranch Add in conversion from 'p4 branchspec(s)' to 'p4 branch(es)' Add in hints to above Append to 'p4 help' Check for complex views in mergefrom command |
||
| #6 | 8802 | Alan H Teague | Update to add mergedown | ||
| #5 | 8799 | Alan H Teague |
Create client template per branch instead of using filesystem structure Enable user specific shelving and non-user specific use of branches |
||
| #4 | 8791 | Alan H Teague |
Change from depot to branch for base depot for branches Enable use of user-defined branches based off clients named USER-BRANCH |
||
| #3 | 8778 | Alan H Teague | Make it work with both basic p4 and wrapped p4 | ||
| #2 | 8776 | Alan H Teague | Remove indirection of branch names | ||
| #1 | 8774 | Alan H Teague | Initial import of the myp4 project |