Восстановление от забывания до .gitignore

Я был пойман тем, что кажется довольно распространенной проблемой для git новичков.

Я забыл .gitignore конкретный файл и добавив его в .gitignore после того, как он совершил ошибку, не имеет значения.

Я нашел эту страницу на gitready, в которой объясняется, как удалить файл из репозитория, не удаляя его из рабочего дерева (с помощью команды git rm --cached <file>, который работает нормально, за исключением того, что если я попытаюсь объединить это обратно в другую ветку, файлы в рабочем дереве будут удалены.

Шаги для воспроизведения в пустой папке:

git init
touch want.txt
touch wantnot.txt
git add .
git commit -m "Initial"
git checkout -b BranchForIgnore
git rm --cached wantnot.txt
cat > .gitignore
wantnot.txt  [Ctrl-D Ctrl-D here to exit cat]
git add .
git commit -m "Ignoring file"

До сих пор все нормально

git checkout master
git merge BranchForIgnore

В этот момент мои файлы wantnot.txt больше не находятся в моем хозяине, и, очевидно, проверка BranchForIgnore тоже не поможет.

Что делать?

Ответ 1

Я забыл .gitignore конкретный файл и добавив его в .gitignore после того, как он совершил ошибку.

Ну, конечно, нет. Игнорирование - это файлы untrecked (что означает, что файлы не находятся под управлением версиями).

Я нашел страницу на gitready, которая объясняет, как удалить файл из репозитория, не удаляя его из рабочего дерева (используя команду git rm --cached <file>, которая работает нормально, за исключением того, что если я затем попытаюсь объединить это обратно в другая ветвь, файлы в рабочем дереве удаляются.

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

Решение заключалось бы в том, чтобы зафиксировать "отстреливание" файла (удаление файла из контроля версий) во всех ветвях, используя git cherry-pick, или сделать git rm --cached <file> && git commit -a в отдельной ветки фиксации, а затем объединить эту ветку темы во всех ветвях ( а затем восстановление файла из отслеживаемой версии).

Ответ 2

Переименуйте файл во временное имя (не используя git), завершите удаление плюс файл .gitignore, а затем переименуйте файл обратно в исходное имя.

mv wantnot.txt wantnot.txt.tmp
git rm wantnot.txt
echo wantnot.txt >.gitignore
git add .gitignore
git commit -m "remove mistakenly committed wantnot.txt"
mv wantnot.txt.tmp wantnot.txt

Использование отдельной ветки для этого может быть излишне запутанным.