Не возможно переключить ветку после --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 с помощью этой команды:)

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

Что сработало для меня в моем случае:

  1. git update-index --no-skip-worktree path_to_fileотменить пропуск в первую очередь.

  2. удалил все мои локальные ветки (вы можете использовать:git branch | grep -v "master" | xargs git branch -D), пошел к мастеру и изменил файл с конфиденциальной информацией.

  3. git update-index --skip-worktree path_to_fileснова.

  4. git checkout any__new_local_branchработает просто отлично сейчас.

Кредиты и спасибо @kise в комментариях к исходному вопросу.

Пока что --assume-неизменен и --skip-worktree не работают, как я обнаружил. Моя git-версия: git-версия 2.8.4 (Apple Git-73). Stash - единственный способ, который работает до сих пор.

Другие вопросы по тегам