Git удаляет проигнорированный файл, когда я переключаю ветки - PullRequest
31 голосов
/ 22 апреля 2010

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

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

Есть предложения?

Ответы [ 5 ]

5 голосов
/ 22 апреля 2010

Поскольку единственным жизнеспособным решением является постоянное отслеживание файла '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.

2 голосов
/ 22 апреля 2010

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

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

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

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

1 голос
/ 10 октября 2012

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

0 голосов
/ 05 апреля 2019

Ответ

Если вы игнорируете файл только в ветви 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 думает, что это не там, и ветвь А думает, что это так, поэтому, когда я иду назад к B это 'убирает это'. Но это немного раздражает.

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

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

0 голосов
/ 10 октября 2012

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...