You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
2.7 KiB

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