Как внести изменения в.gitattributes вступить в силу

Я работаю над проектом, в котором мы недавно начали использовать git. Настройка не была идеальной с самого начала, поэтому я настроил.gitattributes после того, как люди начали клонировать / работать, и я все еще делаю некоторые изменения в этом файле.

Рассмотрим следующую настройку...

Алиса и Боб клонировали "repo.git", а хранилище содержит файл /myproj/src/file.ending with \n как конец строки, т.е. файл не содержит \r персонажи.

Они также оба имеют .gitattributes со следующей настройкой:

/myproj/src/file.ending -text

Это говорит Git, что file.ending не должен рассматриваться как текстовый файл и, следовательно, не должно происходить преобразование конца строки.

Соответственно, файлы в рабочем дереве Алисы и Боба также имеют \n как конец строки.

Теперь Алиса вносит следующие изменения в.gitattributes:

/myproj/src/file.ending text

Алиса хотела бы, чтобы это изменение вступило в силу как для нее, так и для Боба.

Единственный способ, который я знаю прямо сейчас, довольно навязчив:

git rm --cached -r .
git reset --hard

Я хотел бы избежать двух вещей:

  • Алиса должна зафиксировать свой файл `.gitattributes`, прежде чем она сможет на самом деле проверить его (сброс выше перезапишет ее изменения).
  • Боб должен стереть свой индекс и рабочее дерево, чтобы получить обновление. Боб не счастлив.

Каков предпочтительный способ сделать это?

5 ответов

Вам не нужно сильно сбрасывать (если я правильно понимаю, что вы делаете).

Мой случай похож. Я добавил .gitattributes в работающем проекте. Мне нужны файлы, которые у меня есть, и файлы в онлайн-репозитории, которые должны управляться gitattr.

# This will force git to recheck and "reapply" gitattributes changes.
git rm --cached -r .
git add -A

Ваш коммит заново добавит все .ending файлы, которые вы упоминаете, и вы не потеряете изменения, которые вы можете иметь. Конечно, Бобу придется потянуть, чтобы получить это.

osse на irc://chat.freenode.net/#git дал мне этот метод, и он работает достаточно хорошо:

git rm -r :/ && git checkout HEAD -- :/

Он будет жаловаться, если в вашем дереве есть незафиксированные изменения.

Похоже, что должен быть способ получше.

Под "хотел бы, чтобы это изменение вступило в силу", вы имеете в виду, что Алиса хочет, чтобы рабочие копии переключались на окончания строк в стиле Windows для нее и Боба? Тогда первая проблема: почему Алиса берет на себя ответственность за то, что находится в рабочем дереве Боба?

Если файл лучше описывается новыми атрибутами, пусть будет так; .gitattributes Файл может быть отредактирован, протестирован и передан так же, как и любой другой.

Процедура, которую вы предлагаете, чтобы новые атрибуты вступили в силу, не имеет большого смысла по двум причинам:

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

Во-вторых, почему вы стираете все с индекса? Только пути, атрибуты которых изменились, должны быть адресованы.

Так что в вашем примере, если Алиса хочет локально отразить новые атрибуты, самое большее, что должно быть необходимо, это

rm myproj/src/file.ending
git checkout -- myproj/src/file.ending

Поскольку эта процедура не перезаписывает файл.gitattributes, нет необходимости преждевременно фиксировать его.

Мне не ясно, что именно делает Боба несчастным из-за твоей первоначальной процедуры, поэтому я не знаю, делает ли это его счастливее. Возможно, он просто хочет, чтобы обновление было автоматическим, когда он тянет; хотя ожидать этого не является необоснованным, я не уверен, что это в картах, как работает git.

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

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

Так что, если это произойдет один раз, просто позвольте команде общаться. "Атрибуты для этого пути меняются; возможно, вы захотите обновить ваши рабочие копии затронутых файлов".

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

После того, как вы зафиксировали изменения для.gitattributesвыполните следующее, чтобы применить изменения

      git rm --cached -r .
git reset --hard

Чтобы изменения вступили в силу, вам понадобится какой-нибудь git-сервер — например Gitlab. Отправьте репозиторий в Gitlab, а затем создайте новую папку.в новую папку, которую вы создали, а затем клонируйте в нее репозиторий с помощью

      git clone <repository> .

и тогда изменения должны быть применены правильно.

Таким образом вы избегаете довольно навязчивого другого варианта, о котором вы упомянули.

Другие вопросы по тегам