Распространяются ли правила git update-index--assume-неизмененные на клиентов по запросу?




git теги (2)

Индекс является локальным для вашей рабочей станции, любые внесенные вами изменения не распространяются на другие клоны того же пульта.

(обновлено, после того, как вопрос был обновлен)

Файл .gitignore

Есть случаи, когда я не могу использовать файл .gitignore, иначе при git push критические файлы удаляются с удаленного компьютера.

Это неправда. Файл git ignore не влияет на файлы, которые уже отслеживаются в хранилище. Если вы добавите файл в .gitignore после его .gitignore , он останется внутри репозитория; это не будет очищено. На самом деле, он ведет себя так, как будто его вообще не игнорируют.

Вы можете легко проверить это во временном хранилище:

$ mkdir -p /tmp/repo
$ cd /tmp/repo
$ git init
Initialized empty Git repository in /tmp/repo/.git/
$ echo red > a.txt
$ git commit -am '1'
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt
$ echo a.txt > .gitignore
$ echo b.txt >> .gitignore
$ git commit -am '2'
 1 file changed, 2 insertions(+)
 create mode 100644 .gitignore

Хранилище теперь содержит два файла: a.txt и .gitignore . Оба ведут себя нормально, что вы можете увидеть при клонировании:

$ cd ..
$ git clone file://repo repo2
$ ls -A repo2
.git       .gitignore a.txt
$ cd repo

Если мы изменим оба игнорируемых файла и git status , мы увидим, что a.txt считается измененным, несмотря на то, что он был gitignored. Мы можем добавить и зафиксировать это как обычно; на самом деле, если вы добавляете отслеживаемый файл в gitignore, он ведет себя почти так же, как и в gitignore.

$ echo green > a.txt
$ echo blue > b.txt
$ git status --short
 M a.txt
$ git add a.txt

Файл b.txt отличается, потому что он был проигнорирован до того, как git начал его отслеживать. Этот файл обычно не попадает в репозиторий, но мы можем принудительно сделать это, если захотим.

$ git add b.txt
The following paths are ignored by one of your .gitignore files:
b.txt
Use -f if you really want to add them.
fatal: no files added
$ git add -f b.txt

Выпуск git commit теперь фиксирует два файла, которые оба были проигнорированы git:

$ git commit -m '3'
 2 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 b.txt

Короче говоря, подумайте о git игнорировать правила в качестве руководства :-)

Размножение предполагает - без изменений

После применения правил, предполагающих неизменность, и вызова git push, будут ли эти правила присоединены к удаленной ветви, чтобы все последующие извлечения (от других клиентов) унаследовали их? Или эти клиенты также должны запускать команды git update-index --assume-неизмененные по отдельности на своих машинах?

Последний. Самое близкое, что вы можете получить, это добавить сценарий оболочки в репозиторий, который вносит изменения за вас.

Хук сервера?

Если команды не наследуются - кто-нибудь ранее писал для этого хук сервера? Вместо того, чтобы требовать, чтобы все нынешние и будущие клиенты защитились от этого?

Если ваша цель состоит в том, чтобы написать перехват сервера, который удаляет критические файлы, как будто они вообще не были частью push, это невозможно. Git push имеет дело прежде всего с коммит- objectsrefs ). Их зависимые объекты, такие как деревья и объекты, передаются по мере необходимости, в зависимости от достижимости при коммите. Все сводится к тому, что, если он не зафиксирован, вы не можете отправить его на удаленный компьютер (это упрощение, но оно справедливо для файлов в хранилище). Кроме того, git коммиты криптографически защищены. Вы не можете изменить коммит, не изменив хеш коммита, и если вы измените хеш коммита, у вас в основном будет другой, новый коммит (который может иметь тот же diff, что и старый).

Это означает, что сервер не может переписать коммиты; по крайней мере, без серьезной путаницы с клиентом, который сделал push (у которого все еще будет копия старых объектов коммита).

Что вы можете сделать, это написать хук после получения, который отклоняет коммиты, если они содержат файлы, которые вы не хотите обновлять. Это на самом деле не решит вашу проблему, потому что если у вас возникнут проблемы с объяснением git commit --assume-unchanged вашим коллегам, то у вас, вероятно, будет еще больше проблем с объяснением того, как они могут использовать интерактивный rebase для воссоздания своих коммитов без нежелательных файлов. в них.

Короче говоря, я думаю, что преследовать всех за то, чтобы продолжать использовать предположения без изменений (возможно, в сочетании с ловушкой после получения), - это ваш наименее плохой выбор, если вы имеете дело с файлами, которые следует фиксировать один раз, а не после, как сейчас.

Возможный обходной путь

Ваша жизнь станет намного проще, если вы сможете сохранить эти файлы от git во всей их полноте. Одна из вещей, о которых я могу думать:

  • переместите файлы в хранилище в каталог lib, где они не изменяются постоянно
  • .gitignore файлы в их определенном месте, где они должны быть, но постоянно получают нежелательные изменения
  • добавьте сценарий «init» в свой репозиторий, который люди должны запустить один раз после клонирования и перед началом работы. Этот скрипт копирует файлы в нужное место.

Есть случаи, когда я не могу использовать файл .gitignore , иначе при git push критические файлы удаляются с удаленного компьютера. В этих случаях я применяю git update-index --assume-unchanged <file> к файлам, которые я хочу игнорировать.

После применения правил, предполагающих неизменность, и вызова git push , будут ли эти правила присоединены к удаленной ветви, чтобы все последующие извлечения (от других клиентов) унаследовали их? Или эти клиенты также должны запускать команды git update-index --assume-unchanged <file> отдельности на своих компьютерах?

Если команды не наследуются - кто-нибудь ранее писал для этого хук сервера? Вместо того, чтобы требовать, чтобы все нынешние и будущие клиенты защитились от этого?


Одно из возможных решений - написать хук на стороне клиента, чтобы люди не могли вносить локальные изменения в файлы, которые вы хотите игнорировать.

Эти ловушки являются скриптами, которые запускаются при определенных событиях в git, таких как pre-commit, post-commit, pre-push и т. Д. Примеры вы можете посмотреть в <your_repo>/.git/hooks/ .

Плохая новость заключается в том, что они также не находятся под контролем версий , поэтому вы должны написать свой собственный скрипт установки, чтобы скопировать скрипт хука в .git/hooks/ .

Вот небольшой пример перехвата перед фиксацией, который предотвращает фиксацию файла LTD.txt (его можно адаптировать для получения списка файлов):

ROOT_DIR="$(pwd)/"
LIST=$(git diff --cached --name-only --diff-filter=ACRM)

for file in $LIST
do
    if [ "$file" == “forbidden.txt” ]; then
        echo You cannot commit file $file. Please reset it and try again.
        exit 1
    fi
done
exit 0




gitignore