В настоящее время я подумываю сменить мою VCS (с subversion) на git. Можно ли ограничить размер файла внутри коммита в репозитории git? Для е. грамм. subversion есть ловушка: http://www.davidgrant.ca/limit_size_of_subversion_commit_with_this_hook
По моему опыту, люди, особенно неопытные, иногда имеют тенденцию фиксировать файлы, которые не должны попадать в VCS (например, большой файл системные изображения).
Этот довольно хорошо:
#!/bin/bash -u
#
# git-max-filesize
#
# git pre-receive hook to reject large files that should be commited
# via git-lfs (large file support) instead.
#
# Author: Christoph Hack <chack@mgit.at>
# Copyright (c) 2017 mgIT GmbH. All rights reserved.
# Distributed under the Apache License. See LICENSE for details.
#
set -o pipefail
readonly DEFAULT_MAXSIZE="5242880" # 5MB
readonly CONFIG_NAME="hooks.maxfilesize"
readonly NULLSHA="0000000000000000000000000000000000000000"
readonly EXIT_SUCCESS="0"
readonly EXIT_FAILURE="1"
# main entry point
function main() {
local status="$EXIT_SUCCESS"
# get maximum filesize (from repository-specific config)
local maxsize
maxsize="$(get_maxsize)"
if [[ "$?" != 0 ]]; then
echo "failed to get ${CONFIG_NAME} from config"
exit "$EXIT_FAILURE"
fi
# skip this hook entirely if maxsize is 0.
if [[ "$maxsize" == 0 ]]; then
cat > /dev/null
exit "$EXIT_SUCCESS"
fi
# read lines from stdin (format: "<oldref> <newref> <refname>\n")
local oldref
local newref
local refname
while read oldref newref refname; do
# skip branch deletions
if [[ "$newref" == "$NULLSHA" ]]; then
continue
fi
# find large objects
# check all objects from $oldref (possible $NULLSHA) to $newref, but
# skip all objects that have already been accepted (i.e. are referenced by
# another branch or tag).
local target
if [[ "$oldref" == "$NULLSHA" ]]; then
target="$newref"
else
target="${oldref}..${newref}"
fi
local large_files
large_files="$(git rev-list --objects "$target" --not --branches=\* --tags=\* | \
git cat-file можно настроить размер в серверной стороне config
файл путем добавления:
[hooks]
maxfilesize = 1048576 # 1 MiB
--batch-check=%(objectname)\t%(objecttype)\t%(objectsize)\t%(rest)' | \
awk -F '\t' -v maxbytes="$maxsize" '$3 > maxbytes' | cut -f 4-)"
if [[ "$?" != 0 ]]; then
echo "failed to check for large files in ref ${refname}"
continue
fi
IFS= можно настроить размер в серверной стороне config
файл путем добавления:
[hooks]
maxfilesize = 1048576 # 1 MiB
\n'
for file in $large_files; do
if [[ "$status" == 0 ]]; then
echo ""
echo "-------------------------------------------------------------------------"
echo "Your push was rejected because it contains files larger than $(numfmt --to=iec "$maxsize")."
echo "Please use https://git-lfs.github.com/ to store larger files."
echo "-------------------------------------------------------------------------"
echo ""
echo "Offending files:"
status="$EXIT_FAILURE"
fi
echo " - ${file} (ref: ${refname})"
done
unset IFS
done
exit "$status"
}
# get the maximum filesize configured for this repository or the default
# value if no specific option has been set. Suffixes like 5k, 5m, 5g, etc.
# can be used (see git config --int).
function get_maxsize() {
local value;
value="$(git config --int "$CONFIG_NAME")"
if [[ "$?" != 0 ]] || [[ -z "$value" ]]; then
echo "$DEFAULT_MAXSIZE"
return "$EXIT_SUCCESS"
fi
echo "$value"
return "$EXIT_SUCCESS"
}
main
можно настроить размер в серверной стороне config
файл путем добавления:
[hooks]
maxfilesize = 1048576 # 1 MiB
Да, у git также есть крючки ( git hooks ). Но это зависит от того, какой рабочий процесс вы будете использовать.
Если у вас есть неопытные пользователи, гораздо безопаснее потянуть за них, чем позволить им подтолкнуть. Таким образом, вы можете быть уверены, что они не испортят основной репозиторий.
Я использую gitolite, и хук обновления уже использовался - вместо хука обновления я использовал хук предварительного получения. Сценарий, опубликованный Chriki, работал невероятно, за исключением того, что данные передаются через stdin - поэтому я сделал одно изменение строки:
- refname=$3
+ read a b refname
(может быть более элегантный способ сделать это, но это работает)
Вы можете использовать ловушку , ловушку pre-commit
(на клиенте) или ловушку update
(на сервере). Сделайте git ls-files --cached
(для предварительной фиксации) или git ls-tree --full-tree -r -l $3
(для обновления) и действуйте соответственно.
git ls-tree -l
даст что-то вроде этого:
100644 blob 97293e358a9870ac4ddf1daf44b10e10e8273d57 3301 file1
100644 blob 02937b0e158ff8d3895c6e93ebf0cbc37d81cac1 507 file2
Возьмите четвертый столбец, и это размер. Используйте git ls-tree --full-tree -r -l HEAD | sort -k 4 -n -r | head -1
, чтобы получить самый большой файл. cut
извлечь, if [ a -lt b ]
проверить размер и т. Д.
Извините, я думаю, что если вы программист, вы сможете сделать это самостоятельно.