Pre-commit scripts are run when the user clicks Commit Changes in the commit view, but before the commit is started (see the commit process for more information).
A pre-commit script can be run in one of two ways:
Once for the entire working copy
The script is run once. The POSIX path of the working copy’s top folder is passed to the script as its only parameter.
Pre-commit scripts are run even if no items are checked in the commit view’s Changes list.
Once for each checked item in the commit view’s Changes list
The script is run multiple times, once for each checked item in the commit view’s Changes list. The POSIX path of the changed item is passed to the script as its only parameter.
Cornerstone will abort script execution as soon as the first error is encountered.
The user is prompted when a pre-commit script raises an error—i.e. exits with a value other than zero—with the option to continue or cancel the commit.
Pre-commit scripts can therefore be used to validate changes before a commit.
On the face of it, pre-commit scripts sound similar to prepare scripts. This is true when run once for the entire working copy. However there are significant differences when run once per item:
Prepare scripts can modify the working copy to change the set of items to be committed. This is not the case with a pre-commit script.
For example, if you need to change unmodified files (or revert changed files)—thus changing the set of files to be committed—then you should use a prepare script.
The user may invest significant time writing their log message selecting the files for commit. Subsequently aborting the commit as a result of pre-commit validation would not be appropriate.
Pre-commit validation is better suited to prepare scripts.
Per-item pre-commit scripts are run once for each item to be committed. Unchecked items in the commit view’s Changes list are not committed and are therefore not passed to the pre-commit script.
Time-consuming operations should therefore be placed in pre-commit scripts.
The user has the opportunity to cancel the commit while the commit view is displayed. Destructive, non-repeatable operations should therefore be run as pre-commit scripts.
Pre-commit scripts are defined for each working copy:
Start a commit operation by selecting one or more changed items and choosing the Commit command from the Working Copy menu (key equivalent ⌘T).
Expand the Options section at the bottom of the commit view.
Locate the Before continuing options in the Actions section.
Check the Run script button.
Use the pop-up to choose the script to run.
Specify whether the script should be run once for the entire working copy or once for each item.
Updating the thumbnail for a modified image file and storing it as a custom property.
Assign properties to newly-added files if the file pattern matching provided by Subversion’s auto-props feature is insufficient.
Purpose |
Create a 120px thumbnail image for the specified image and store it in a custom property called The script also demonstrates how to update the sidecar property ( |
Type | Item |
Argument | Path to an image file |
#!/usr/bin/env bash # Updates the thumbnail of the specified file and writes the sidecar # property for the thumbnail such that information about the thumbnail # is displayed in Cornerstone's inspector # # Usage: # GenerateThumbnail file # # Arguments: # $1 path to the file to generate a thumbnail for dir="${1%/*}" # ============================================================================= # # Generates a thumbnail for file specified as $1 and stores # it as the property named $2 # # Arguments: # $1 The path of the file to generate a thumbnail for # $2 The name of the property to assign the thumbnail to # $3 The name of the thumbnail file # $4 The format of the thumbnail, e.g. "jpeg" or "png" # # ============================================================================= function generate_thumbnail() { # Generate a 120px thumbnail and assign it to the specifed property sips -Z 120 -s format "$4" "$1" --out "$dir/$3" svn propset "$2" "$1" --file "$dir/$3" # Get file system and image information about the thumbnail file # and store it globally where it can be accessed later as needed eval $(stat -s "$dir/$3") sips -g allxml "$dir/$3" > "$dir/sips.plist" width=$(defaults read "$dir/sips" pixelWidth) height=$(defaults read "$dir/sips" pixelHeight) # Remove the temporary files created by this function rm "$dir/$3" rm "$dir/sips.plist" } # ============================================================================= # # Generates a thumbnail attributes sidecar property and stores # it as the property named $2:attributes # # Arguments: # $1 The path of the file to assign the property to # $2 The name of the property to assign the attributes to # $3 The name of the thumbnail file # $4 The UTI of the thumbnail file, e.g. "public.jpeg", or "public.png" # # ============================================================================= function generate_attributes() { # Create or update the sidecar property withinformation about the # thumnail we generated svn propget "$2" "$1" > "$dir/attrs.plist" # Generate a 48px thumbnail icon and format it as uppercase hex sips -Z 48 -s format png "$1" --out "$dir/icon.png" data=$(cat "$dir/icon.png" | hexdump -v -e '1/1 "%02x" ""' | tr "[:lower:]" "[:upper:]") # Assign file system and image information to the file's sidecar attributes property. # Note that the st_* vars are initialized by the call to stat in generate_thumbnail() defaults write "$dir/attrs" name "$3" defaults write "$dir/attrs" display-name "${3%.*}" defaults write "$dir/attrs" size $st_size defaults write "$dir/attrs" creation-date $(date -r $st_ctime +"%Y-%m-%dT%TZ") defaults write "$dir/attrs" modification-date $(date -r $st_mtime +"%Y-%m-%dT%TZ") defaults write "$dir/attrs" type "file" defaults write "$dir/attrs" kind "Preview Document" defaults write "$dir/attrs" immutable -bool false defaults write "$dir/attrs" uti "$4" defaults write "$dir/attrs" posix-permissions -int 420 defaults write "$dir/attrs" extension-hidden -bool true defaults write "$dir/attrs" icon -data $data defaults write "$dir/attrs" additional-information "$width x $height" # Using 'defaults' to write to the attributes plist file causes the file to # be converted from xml to binary format. Convert the file back to xml format # using the plutil utility and then assign the plist file to the thumbnail's # sidecar attributes property plutil -convert xml1 "$dir/attrs.plist" svn propset "$2" "$1" --file "$dir/attrs.plist" # Remove temporary files created by this function rm "$dir/attrs.plist" rm "$dir/icon.png" } # ============================================================================= # # Entry point for the script # # Arguments: # $1 The path of file to generate the thumbnail for # $2 The name of the property to assign the thumbnail to # $3 The format of the thumbnail file, e.g. "jpeg" or "png". The thumbnail's # file extension and UTI will also be derived from this value. # $4 Optional. Specify "--with-attrs" to store thumbnail attributes in a # sidecar property # # ============================================================================= function run() { # Check that the specified file is an image file, i.e. has a UTI that is # derived from "public.image". Exit silently if input file is not an image if [ $(mdls -name kMDItemContentTypeTree "$1" | grep -c "\"public.image\"") -eq 0 ] then return 0 fi # Generate the thumbnail for the input file name="${1##*/}" name="${name%.*}-thumbnail.$3" generate_thumbnail "$1" "$2" "$name" "$3" # Generate attributes property for the thumbnail if the --with-attrs # argument was specified. Otherwise delete attributes property. attrs="$2:attributes" if [ "${4-}" == "--with-attrs" ] then generate_attributes "$1" "$attrs" "$name" "image.$3" else svn propdel --quiet "$attrs" "$1" fi } # Run the script by calling the run() entry point function. Omit the # --with-attrs argument to not generate an ":attributes" sidecar property. run "$1" "thumbnail" "jpeg" "--with-attrs"
$1
is used to reference the path of the item that will be committed. It is supplied as the $1’s single argument.
It is recommended that $1
be placed in quotation marks in order that the script functions correctly with paths containing space characters.