Git удалить некоторые файлы в рабочем дереве после rm --cached и перемещения между ветками - PullRequest
0 голосов
/ 21 декабря 2018

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

Из нового локального репо

git init

Я создаю несколько файлов

touch file1.txt | touch file2.txt

Я хочу игнорировать file1

echo file1.txt > .gitignore

Я поставил и зафиксировал

git add .
git commit -m "Initial commit"

Я создаю новую ветку (без проверки)

git branch dev

Iбыл неправ, я тоже хочу игнорировать file2!Так что я unstaged file2

git rm --cached file2.txt

Я помещаю file2 в gitignore

echo file2.txt >> .gitignore

Я ставлю и фиксирую

git add .
git commit -m "file2 in gitignore"

Я перехожу в ветку dev (больше ничего не делаю)

git checkout dev

Я возвращаюсь к мастеру (больше ничего не делаю)

git checkout master

file2.txt был удален в моем рабочем дереве!

Что я делаю не так??: (

Является ли file2.txt удаленным, потому что я извлекаю из филиала, где .gitignore отличается?

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Я предполагаю, что ваше ожидаемое поведение, поскольку вы проигнорировали file2.txt, заключается в том, что git не удалит его при переключении ветвей.

Но в ветви, которую вы покидаете, file2.txt не игнорируется;на самом деле этого не может быть, поскольку он проиндексирован.И при переходе от туда master, один из изменений является удаление file2.txt.

1008 * Это крайний случай, когда «правильное» поведение является дискуссионным.Иногда можно ожидать (или, по крайней мере, хотеть) одного, а иногда - другого.

Но вы наблюдаете документированное поведение git.

Обратите внимание, что еслиВы также удалите file2.txt из dev

git checkout dev
git rm --cached file2.txt
git echo file2.txt >> .gitignore
git add .
git commit 

, а затем переключение между ветвями оставляет file2.txt нетронутым.И если фиксация file2.txt была в первую очередь ошибкой, то как минимум удаление из всех ветвей имеет смысл.

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

ПРИМЕЧАНИЕ , что если вы делаете это, вы хотите убедиться, что вы восстановили копии рабочего дерева file2.txt.(Если вы этого не сделаете, то все равно можно будет (на некоторое время) восстановить их впоследствии, но не так просто.) Поэтому, как только эти файлы будут безопасно восстановлены

git filter-branch --index-filter 'git rm --cached --ignore-unmatch :/:file2.txt' -- --all
0 голосов
/ 21 декабря 2018

Выглядит странно, верно?

git rm работает с двумя разными уровнями,

rm --cached пометит файл как удаленный только в промежуточном индексе. Он сохранит файл в рабочем каталоге как есть. Подробнее здесь

Тогда волшебство происходит с командой git checkout

согласно официальной документации здесь .

Обновляет файлы в рабочем дереве в соответствии с версией в индексе

Это означает, что working directory будет обновляться с содержимым staging index. Так как вы удалили файл из промежуточного индекса с помощью команды git rm --cached, тогда рабочий каталог будет заменен на staging index content командой git checkout master.

...