Git удаляет проигнорированный файл, когда я переключаю ветки
У меня есть одна ветвь (назовем это B), которая игнорирует определенный файл, который не игнорируется в некоторых других ветвях (например, ветвь A). Когда я переключаюсь с ветви B на ветку A, а затем снова на B, файл был удален.
Это нормально? Я могу как-то увидеть, как это произойдет, в том смысле, что ветвь B думает, что его там нет, а ветвь A думает, что это так, поэтому, когда я возвращаюсь к B, это "убирает его". Но это отчасти раздражает.
Какие-либо предложения?
6 ответов
Поскольку единственное жизнеспособное решение - отслеживать файлf
Простите, можете добавить, только в ветке B
, пятно / чистый процесс с драйвером фильтра gitattributes:
При оформлении заказа филиала 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
но не на вашем местном. Вы можете добавить файл после загрузки на этих машинах.
объяснение
У меня была точно такая же проблема. Вот как это случилось со мной:
- Файл
test.json
был когда-то отслежен вB
, - Я создал ветку
A
отB
(так что файлtest.json
также отслеживается вA
). - Позже я проигнорировал файл
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, сделайте коммит и будьте счастливы.