Подтвердить что ты не робот

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

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

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

Любые предложения?

4b9b3361

Ответ 1

Поскольку единственным жизнеспособным решением является отслеживание файла 'f' в любое время, вы можете добавить только в ветке B, smudge/clean process с драйвер фильтра gitattributes:

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

Когда ветка проверки B:

  • процесс smudge изменится:

    • сохранить содержимое 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 контент.

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

У меня возникла аналогичная ситуация, и я делаю это:

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

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

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

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

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

Ответ 5

Ответ

Если вы игнорируете файл только в ветки 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