
When we install Git we also install a set of default templates that both git-init(1) and git-clone(1) populate into our build directories. The way the pristine templates are laid out in our source directory is somewhat weird though: instead of reconstructing the actual directory hierarchy in "templates/", we represent directory separators with "--". The only reason I could come up with for why we have this is the "branches/" directory, which is supposed to be empty when installing it. And as Git famously doesn't store empty directories at all we have to work around this limitation. Now the thing is that the "branches/" directory is a leftover to how branches used to be stored in the dark ages. gitrepository-layout(5) lists this directory as "slightly deprecated", which I would claim is a strong understatement. I have never encountered anybody using it today and would be surprised if it even works as expected. So having the "--" hack in place for an item that is basically unused, unmaintained and deprecated doesn't only feel unreasonable, but installing that entry by default may also cause confusion for users that do not know what this is supposed to be in the first place. Remove this directory from our templates and, now that we do not require the workaround anymore, restructure the templates to form a proper hierarchy. This makes it way easier for build systems to install these templates into place. We should likely think about removing support for "branch/" altogether, but that is outside of the scope of this patch series. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
79 lines
2.7 KiB
Bash
Executable File
79 lines
2.7 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# An example hook script to update a checked-out tree on a git push.
|
|
#
|
|
# This hook is invoked by git-receive-pack(1) when it reacts to git
|
|
# push and updates reference(s) in its repository, and when the push
|
|
# tries to update the branch that is currently checked out and the
|
|
# receive.denyCurrentBranch configuration variable is set to
|
|
# updateInstead.
|
|
#
|
|
# By default, such a push is refused if the working tree and the index
|
|
# of the remote repository has any difference from the currently
|
|
# checked out commit; when both the working tree and the index match
|
|
# the current commit, they are updated to match the newly pushed tip
|
|
# of the branch. This hook is to be used to override the default
|
|
# behaviour; however the code below reimplements the default behaviour
|
|
# as a starting point for convenient modification.
|
|
#
|
|
# The hook receives the commit with which the tip of the current
|
|
# branch is going to be updated:
|
|
commit=$1
|
|
|
|
# It can exit with a non-zero status to refuse the push (when it does
|
|
# so, it must not modify the index or the working tree).
|
|
die () {
|
|
echo >&2 "$*"
|
|
exit 1
|
|
}
|
|
|
|
# Or it can make any necessary changes to the working tree and to the
|
|
# index to bring them to the desired state when the tip of the current
|
|
# branch is updated to the new commit, and exit with a zero status.
|
|
#
|
|
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
|
|
# in order to emulate git fetch that is run in the reverse direction
|
|
# with git push, as the two-tree form of git read-tree -u -m is
|
|
# essentially the same as git switch or git checkout that switches
|
|
# branches while keeping the local changes in the working tree that do
|
|
# not interfere with the difference between the branches.
|
|
|
|
# The below is a more-or-less exact translation to shell of the C code
|
|
# for the default behaviour for git's push-to-checkout hook defined in
|
|
# the push_to_deploy() function in builtin/receive-pack.c.
|
|
#
|
|
# Note that the hook will be executed from the repository directory,
|
|
# not from the working tree, so if you want to perform operations on
|
|
# the working tree, you will have to adapt your code accordingly, e.g.
|
|
# by adding "cd .." or using relative paths.
|
|
|
|
if ! git update-index -q --ignore-submodules --refresh
|
|
then
|
|
die "Up-to-date check failed"
|
|
fi
|
|
|
|
if ! git diff-files --quiet --ignore-submodules --
|
|
then
|
|
die "Working directory has unstaged changes"
|
|
fi
|
|
|
|
# This is a rough translation of:
|
|
#
|
|
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
|
|
if git cat-file -e HEAD 2>/dev/null
|
|
then
|
|
head=HEAD
|
|
else
|
|
head=$(git hash-object -t tree --stdin </dev/null)
|
|
fi
|
|
|
|
if ! git diff-index --quiet --cached --ignore-submodules $head --
|
|
then
|
|
die "Working directory has staged changes"
|
|
fi
|
|
|
|
if ! git read-tree -u -m "$commit"
|
|
then
|
|
die "Could not update working tree to new HEAD"
|
|
fi
|