Не возможно переключить ветку после --skip-worktree
ЧТО Я ХОЧУ СДЕЛАТЬ
У меня есть файл, который содержит конфиденциальные данные, поэтому я не хочу передавать содержимое этого файла на удаленный сервер.
ЧТО Я СДЕЛАЛ?
Чтобы добиться этого, я сделал коммит, когда файл был пуст, и отправил этот пустой файл на сервер (GitHub). А затем заполните файл с чувствительными данными и применены git update-index --skip-worktree path/to/file
, Но я не сделал никаких обязательств.
Сейчас я пытаюсь переключить свою ветку, но я получаю эту ошибку:
error: Your local changes to the following files would be overwritten by checkout:
path/to/file
Please, commit your changes or stash them before you can switch branches.
Aborting
ПОЧЕМУ Я ИСПОЛЬЗУЮ skip-worktree
ВМЕСТО assume-unchanged
?
Я прочитал несколько ТАКИХ вопросов по этому вопросу и нашел ответ Бореалида.
--assume-неизмененный предполагает, что разработчик не должен изменять файл. Этот флаг предназначен для повышения производительности для неизменяемых папок, таких как SDK.
--skip-worktree полезен, когда вы указываете git не трогать определенный файл, потому что разработчики должны изменить его. Например, если основной репозиторий содержит несколько готовых файлов конфигурации и вы не хотите случайно фиксировать изменения в этих файлах, --skip-worktree - именно то, что вам нужно.
После этого я нашел вопрос Джеффа и ответ VonC. Проблема Джеффа почти такая же, как у меня, и я последовал решению VonC. Однако это не работа для меня. Возможно из-за разницы в git-версии. Потому что этот вопрос 2012 года. Мы поговорили с VonC, и он сказал задать этот вопрос как новый вопрос, потому что не мог вспомнить ответ.
Я пытался использовать --assume-unchanged
а также --skip-worktree
вместе, и мягкий сброс рабочего дерева. Но ничего не изменилось.
ТАК?
Можете ли вы помочь мне в моей проблеме?
Спасибо.
8 ответов
Я не смог найти подходящее решение для этого, поэтому я использую .bat
файл для запуска --no-skip-worktree
на поврежденные файлы. После, я stash
, переключить ветку, stash apply
, а затем использовать другой .bat
файл для запуска --skip-worktree
на одни и те же файлы.
Это нехорошо, но это самый простой и быстрый способ, который я нашел до сих пор.
Ну, это грубое решение, но, кажется, работает достаточно хорошо (хотя это только слегка проверено):
Создайте файл с именем git-checkoutsw
где-то в вашем PATH
со следующим содержанием:
#!/bin/bash
ignored=( $(git ls-files -v | grep "^S " | cut -c3-) )
for x in "${ignored[@]}"; do
git update-index --no-skip-worktree -- "$x"
done
git checkout -m $@
for x in "${ignored[@]}"; do
git update-index --skip-worktree -- "$x"
done
Сценарий захватывает список игнорируемых файлов, игнорирует их, проверяет новую ветку с помощью -m
(для слияния) и любые другие параметры были указаны, а затем игнорирует их снова.
Теперь вы можете сделать git checkoutsw
вместо git checkout
,
Вы можете включить разреженную проверку и добавить туда файл вместе с добавлением флага skip-worktree (если вы добавите только разреженную проверку, он, вероятно, будет удален).
Чтобы исключить файл, вы должны поместить его в файл sparse-checkout (см. Руководство по git-read-tree):
/*
!unwanted
Тогда это не будет затронуто при обновлении (так что вы не получите там содержимое другой ветки, вместо этого сохраните ваши изменения). Это может быть не то, что вы хотите.
Есть ли причина, по которой пустой вариант этого файла будет зарегистрирован? Если не
git rm --cached path/to/file
echo 'path/to/file' >> .gitignore
git commit -m'stop tracking path/to/file'
может решить вашу проблему. (Необходимо будет повторить для каждой ветви, в которой находится файл. Или, если вы не возражаете против переписывания истории, используйте git filter-branch
чтобы избавиться от него в предыдущих коммитах тоже.)
У меня возникла та же проблема, и она сводилась к тому, чтобы быть вызванным входящими изменениями в файле, который я хотел предположить - без изменений.
Поэтому, если я просто не изменю файл, сохраню его, извлечу последнюю версию, открою тайник и снова предположу, что он останется неизменным.
Так что теперь я могу переключать ветви снова.
Просто найдите одну строку, чтобы сделать --no-skip-worktree для всех файлов
git ls-files -v | grep "^S" | cut -c 3- | xargs -L1 git update-index --no-skip-worktree
Вы можете легко сделать небольшой alias.unhideall с помощью этой команды:)
Как упоминалось в комментарии (я пишу это здесь только как ответ, надеясь, что люди, которые не читают комментарии или могут пропустить их, увидят это), работает, но только если файл одинаков во всех ваших локальных (я предполагаю, что локальный ) ветви.
Что сработало для меня в моем случае:
git update-index --no-skip-worktree path_to_file
отменить пропуск в первую очередь.удалил все мои локальные ветки (вы можете использовать:
git branch | grep -v "master" | xargs git branch -D
), пошел к мастеру и изменил файл с конфиденциальной информацией.git update-index --skip-worktree path_to_file
снова.git checkout any__new_local_branch
работает просто отлично сейчас.
Кредиты и спасибо @kise в комментариях к исходному вопросу.
Пока что --assume-неизменен и --skip-worktree не работают, как я обнаружил. Моя git-версия: git-версия 2.8.4 (Apple Git-73). Stash - единственный способ, который работает до сих пор.