.git/hooks/push-to-checkout.sample
changeset 762 0147c0a9ce2b
equal deleted inserted replaced
761:e4e656f19771 762:0147c0a9ce2b
       
     1 #!/bin/sh
       
     2 
       
     3 # An example hook script to update a checked-out tree on a git push.
       
     4 #
       
     5 # This hook is invoked by git-receive-pack(1) when it reacts to git
       
     6 # push and updates reference(s) in its repository, and when the push
       
     7 # tries to update the branch that is currently checked out and the
       
     8 # receive.denyCurrentBranch configuration variable is set to
       
     9 # updateInstead.
       
    10 #
       
    11 # By default, such a push is refused if the working tree and the index
       
    12 # of the remote repository has any difference from the currently
       
    13 # checked out commit; when both the working tree and the index match
       
    14 # the current commit, they are updated to match the newly pushed tip
       
    15 # of the branch. This hook is to be used to override the default
       
    16 # behaviour; however the code below reimplements the default behaviour
       
    17 # as a starting point for convenient modification.
       
    18 #
       
    19 # The hook receives the commit with which the tip of the current
       
    20 # branch is going to be updated:
       
    21 commit=$1
       
    22 
       
    23 # It can exit with a non-zero status to refuse the push (when it does
       
    24 # so, it must not modify the index or the working tree).
       
    25 die () {
       
    26 	echo >&2 "$*"
       
    27 	exit 1
       
    28 }
       
    29 
       
    30 # Or it can make any necessary changes to the working tree and to the
       
    31 # index to bring them to the desired state when the tip of the current
       
    32 # branch is updated to the new commit, and exit with a zero status.
       
    33 #
       
    34 # For example, the hook can simply run git read-tree -u -m HEAD "$1"
       
    35 # in order to emulate git fetch that is run in the reverse direction
       
    36 # with git push, as the two-tree form of git read-tree -u -m is
       
    37 # essentially the same as git switch or git checkout that switches
       
    38 # branches while keeping the local changes in the working tree that do
       
    39 # not interfere with the difference between the branches.
       
    40 
       
    41 # The below is a more-or-less exact translation to shell of the C code
       
    42 # for the default behaviour for git's push-to-checkout hook defined in
       
    43 # the push_to_deploy() function in builtin/receive-pack.c.
       
    44 #
       
    45 # Note that the hook will be executed from the repository directory,
       
    46 # not from the working tree, so if you want to perform operations on
       
    47 # the working tree, you will have to adapt your code accordingly, e.g.
       
    48 # by adding "cd .." or using relative paths.
       
    49 
       
    50 if ! git update-index -q --ignore-submodules --refresh
       
    51 then
       
    52 	die "Up-to-date check failed"
       
    53 fi
       
    54 
       
    55 if ! git diff-files --quiet --ignore-submodules --
       
    56 then
       
    57 	die "Working directory has unstaged changes"
       
    58 fi
       
    59 
       
    60 # This is a rough translation of:
       
    61 #
       
    62 #   head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
       
    63 if git cat-file -e HEAD 2>/dev/null
       
    64 then
       
    65 	head=HEAD
       
    66 else
       
    67 	head=$(git hash-object -t tree --stdin </dev/null)
       
    68 fi
       
    69 
       
    70 if ! git diff-index --quiet --cached --ignore-submodules $head --
       
    71 then
       
    72 	die "Working directory has staged changes"
       
    73 fi
       
    74 
       
    75 if ! git read-tree -u -m "$commit"
       
    76 then
       
    77 	die "Could not update working tree to new HEAD"
       
    78 fi