Helix Core is now P4. Product user interfaces will be updated soon. Learn more >>

P4 Server Administration Documentation | 2025.2

# Change-content triggers

Use the `change-content` trigger type to create triggers that fire after changelist creation and file transfer, but prior to committing the submit to the database. Change-content triggers can access file contents by using the `p4 diff2`, `p4 files`, `p4 fstat`, and `p4 print` commands with the `@=change` revision specifier, where `change` is the number of the pending changelist as passed to the trigger script in the `%changelist%` variable.

Use change-content triggers to validate file contents as part of changelist submission and to abort changelist submission if the validation fails.

Even when a `change-submit` or `change-content` trigger script succeeds, the submit can fail because of subsequent trigger failures, or for other reasons. Use `change-submit` and `change-content` triggers only for validation, and use `change-commit` triggers for operations that are contingent on the successful completion of the submit.

Replicas that are metadata-only do not support triggers of type `change-commit` and `change-content`.

Example:

The following change-content trigger is a Bourne shell script that ensures that every file in every changelist contains a copyright notice for the current year.

The script assumes the existence of a client workspace called `copychecker` that includes all of `//depot/src`. This workspace does not have to be synced.

Copy

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/bin/sh
    # Set target string, files to search, location of p4 executable...
    TARGET="Copyright 'date +%Y' Example Company"
    DEPOT_PATH="//depot/src/..."
    CHANGE=$1
    P4CMD="/usr/local/bin/p4 -p 1666 -c copychecker"
    XIT=0
    echo ""
    # For each file, strip off #version and other non-filename info
    # Use sed to swap spaces w/"%" to obtain single arguments for "for"
    for FILE in `$P4CMD files $DEPOT_PATH@=$CHANGE | \
      sed -e 's/\(.*\)\#[0-9]* - .*$/\1/' -e 's/ /%/g'`
    do
      # Undo the replacement to obtain filename...
      FILE="'echo $FILE | sed -e 's/%/ /g''"
    # ...and use @= specifier to access file contents:
      # p4 print -q //depot/src/file.c@=12345
      if $P4CMD print -q "$FILE@=$CHANGE" | grep "$TARGET" > /dev/null
      then echo ""
      else
          echo "Submit fails: '$TARGET' not found in $FILE"
          XIT=1
      fi
    done
    exit $XIT

To use the trigger, add the following line to your triggers table:

    sample2  change-content //depot/src/... "copydate.sh %change%"

The trigger fires when any changelist with at least one file in `//depot/src` is submitted. The corresponding `DEPOT_PATH` defined in line 4 of the script ensures that of all the files in the triggering changelist, only those files actually under `//depot/src` are checked.

Your search for returned results