Git удаляет проигнорированный файл, когда я переключаю ветки

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

Это нормально? Я могу как-то увидеть, как это произойдет, в том смысле, что ветвь B думает, что его там нет, а ветвь A думает, что это так, поэтому, когда я возвращаюсь к B, это "убирает его". Но это отчасти раздражает.

Какие-либо предложения?

6 ответов

Поскольку единственное жизнеспособное решение - отслеживать файлfПростите, можете добавить, только в ветке B, пятно / чистый процесс с драйвером фильтра gitattributes:

https://raw.github.com/adisp007/ProGit/master/figures/18333fig0702-tn.png

При оформлении заказа филиала B:

  • процесс размазывания изменится:

    • сохранить содержимое f во временном файле
    • заменить содержание f с одним fbis файл (отслеживаемый файл, который будет содержать, для ветви B"B содержание f")
  • чистый процесс будет:

    • спасти f содержание (как изменено в B) в fbis (fbis совершает с f модификации в ветке B)
    • восстановить f содержание (с временным файлом), значение f не совершено (игнорируется в B)

Вы можете добавить, еще в ветке B пользовательский драйвер слияния, который будет защищать fbis в случае слияния из других филиалов в B:
драйвер слияния всегда будет B версия fbis содержание, убедившись, что проигнорированный файл f возвращает свой контент всякий раз, когда филиал B проверено.

Поскольку эти драйверы (фильтрация и слияние) не фиксируются в других ветвях, файл 'f' фиксируется в других ветвях со всеми его изменениями.
В ветке B, его содержание никогда не изменится, и все же "локальные изменения" сделаны для f все еще восстанавливаются всякий раз, когда B проверено.

Если это восстановление контента не требуется, вам не нужно управлять fbis,
Просто сохраните драйвер фильтра, и вы будете уверены, что любые изменения, которые вы делаете для f в ветке Bэти изменения никогда не будут приняты, фактически игнорируя f содержание.

Это нормально, хотя я немного удивлен одним шагом.

Когда вы переключаетесь с B на A, git видит, что файл должен быть обновлен, чтобы соответствовать версии A, и делает это молча, потому что вы проигнорировали его, говоря, что для ветви B файл не имеет значения. Он должен сделать это - единственная альтернатива - отказаться от проверки ветви А. (Если бы файл не игнорировался, он бы отказался, сказав, что "файл неотслеживаемого рабочего дерева" будет перезаписан слиянием ". Я действительно удивлен в этом случае он тоже этого не делает. У кого-нибудь есть понимание, является ли это функцией или ошибкой?)

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

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

Ответ

Если вы игнорируете файл только в ветке B но не в ветке A то вы не сможете предотвратить его удаление при переключении с A в B,

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

git rm --cached <file>

Осторожнее, если вы нажмете ветку A в ваш репозиторий. Это приводит к тому, что файл будет удален на репозитории и других машинах разработчиков на их следующей git pull но не на вашем местном. Вы можете добавить файл после загрузки на этих машинах.


объяснение

У меня была точно такая же проблема. Вот как это случилось со мной:

  1. Файл test.json был когда-то отслежен в B,
  2. Я создал ветку A от B (так что файл test.json также отслеживается в A).
  3. Позже я проигнорировал файл test.json в ветке B, Однако git продолжит отслеживать любые файлы, которые уже отслеживаются. Чтобы остановить отслеживание файла, я удалил его из индекса git rm --cached foo/test.json,

После этих 3-х шагов следующие счастье: если я в филиале B файл test.json существует. Если я переключусь на A это все еще существует. Если я вернусь к B его нет Итак, я заметил так же, как и вы:

Я могу как-то увидеть, как это произойдет, в том смысле, что ветвь B думает, что его там нет, а ветвь A думает, что это так, поэтому, когда я возвращаюсь к B, это "убирает его". Но это отчасти раздражает.

я добавил test.json в .gitignore файл из ветки A но он все равно был удален при переключении обратно на B, И это потому, что он был отслежен в A прежде чем я проигнорировал это.

Таким образом вам нужно удалить его из индекса в ветке A, Тогда его игнорируют и не отслеживают A а также B и он не удаляется при переключении обратно из A в B,

Игнорирование файлов в git не означает, что они вышли из ревизии. Вы можете зарегистрировать файл и управлять им в git и игнорировать его в .gitignore,

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

Я испытал подобную ситуацию, и я делаю это:

Я назову файл, который удалил в оформлении index.php.

В вашем.gitignore ветви A и ветви B удалите строку, которая игнорирует ваш index.php, после этого зафиксируйте ваш.gitignore в обеих ветках.

В ветви A создайте резервную копию index.php, удалите ее и подтвердите.

Восстановите в ветви A файл index.php из ранее созданной резервной копии и в своем.gitignore снова проигнорируйте файл index.php и подтвердите это.

В вашей ветке B добавьте index.php, игнорируйте файл в вашем.gitignore, сделайте коммит и будьте счастливы.

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