Отмените git update-index --no-предположить-неизмененный (не работает) и сможете снова увидеть эти локальные изменения
Обновление: Мои проблемы с разрешениями каким-то образом исправились произвольно, поскольку теперь работает та же команда создания удаленной ветви, поэтому (как вы, наверное, догадались) это не было вызвано этой проблемой отслеживания.
Сейчас я просто пытаюсь решить проблему с отслеживанием. Спасибо!
Оригинал: я изначально применил следующее к нескольким файлам:
git update-index --assume-unchanged filename.py
ссылаясь на эту документацию:
https://git-scm.com/docs/git-update-index
скрыть определенные файлы от изменений моего рабочего каталога (как добавление файлов в .git/info/exclude
похоже, что это не дает эффекта - файл все еще был виден, несмотря на то, что путь был правильным и он не был зафиксирован).
Затем я столкнулся с некоторыми проблемами, выдвигающими удаленную ветку, которой раньше не было, стандарт
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Итак, учитывая, что у меня не было проблем с доступом прямо перед запуском update-index
Я решил вернуть это --assume-unchanged
так как я не делал никаких других проблем с моим git-репо.
Я был в состоянии просмотреть эти assume-unchanged
файлы, использующие
git ls-files -v | grep '^[a-z]'
Я пытался вернуть assume-unchanged
используя
git update-index --really-refresh
как указано здесь на возвращение assume-unchanged
через несколько файлов:
Отменить git update-index --assume-unchanged
Это не восстановило их, и я тогда попробовал
git ls-files -v | grep '^[a-z]' | cut -c 3- | tr '\012' '\000' | xargs -0 git update-index --no-assume-unchanged
согласно этой рекомендации:
Отменить git update-index --assume-unchanged
Файлы все еще невидимы, и теперь я больше не могу их просматривать, запустив
git ls-files -v | grep '^[a-z]'
Я также экспериментально попытался сделать это на одном из моих файлов:
git update-index --skip-worktree file.py
согласно здесь
https://git-scm.com/docs/git-update-index
насколько я знаю skip-worktree
берет на себя assume-unchanged
поэтому я надеялся увидеть какое-то изменение состояния в этом файле. Еще ничего.
Как мне восстановить файлы, чтобы они стали видимыми, а изменения отслеживаются в моем рабочем каталоге?
И в качестве дополнительного вопроса, есть ли идеи, как это могло повлиять на мои права доступа для создания новой удаленной ветви?
1 ответ
У вас есть две разные проблемы здесь. Твой fatal: Could not read from remote repository
Ошибка совершенно не зависит от битов флага, которые вы установили или очистили в своем индексе. Это подразумевает, что либо:
- для любого протокола, который вы используете для доступа к другому хранилищу (
http
,https
,ssh://
, или жеgit://
), соединение с другим Git не удалось, или - соединение установилось успешно, но затем другой хост, который предположительно содержит этот другой Git-репозиторий, сказал "Я не вижу Git-репозиторий здесь" (в остальной части URL).
Если само соединение не удалось, вы должны увидеть дополнительную информацию до fatal:
линия, сообщающая вам, что произошло, например, не удалось разрешить имя хоста в IP-адрес, имя пользователя и / или пароль требуется, но отсутствует, и так далее. Используйте это для диагностики плохих соединений. Если соединение установилось успешно, но хост говорит "здесь нет Git-репо", используйте любую информацию, которую вы можете получить о хосте, чтобы узнать, куда пошел репозиторий (например, можете ли вы войти на хост напрямую и покопаться?).
Теперь, что касается assume-unchanged
а также skip-worktree
немного, я боюсь, что это становится немного сложным и техническим. Вам нужно знать кое-что из этого, чтобы использовать Git, так что стоит поработать. Я также отмечу здесь, что совет использовать --really-refresh
в принципе неправильно. Это временно игнорирует assume-unchanged
бит для обновления кэшированных данных статистики в индексе, но не влияет на фактический предполагаемый бит без изменений. Способ очистить этот бит действительно использовать --no-assume-unchanged
как в приведенном выше модном конвейере, который заканчивается | xargs -0 git update-index --no-assume-unchanged
, То же самое относится к биту skip-worktree, за исключением того, что вы очищаете его --no-skip-worktree
, 1
Что такое индекс и что это git update-index
команды делают?
При работе с Git важно понимать, что у вас есть три вещи, которые я всегда называю активными копиями каждого файла. 2 Одна из этих трех копий - это то, что было в коммите, который вы проверили. Эта копия только для чтения. Вы не можете изменить его: он зафиксирован в коммите и останется там, в этом коммите, пока этот коммит существует - по сути, навсегда. 3 Это означает, что замороженная копия безопасна: ничто из того, что вы делаете, не будет ее засорять; Вы всегда можете получить его обратно. Для просмотра замороженной копии файла с именем path/to/file.ext
использовать git show HEAD:path/to/file.ext
, Этот HEAD:file
синтаксис работает с git show
и позволяет увидеть замороженную копию в текущем коммите. (Вы также можете увидеть замороженную копию в любом другом коммите.)
Теперь эти замороженные копии находятся в специальном, только для чтения, сжатом формате Git. Ни одна из других программ на вашем компьютере не может получить к ним доступ напрямую (если они не слишком много узнали о внутренностях Git). И, поскольку они не могут быть изменены, они хороши для архивирования, но совершенно бесполезны для выполнения любой новой работы. Итак, когда вы git checkout
Git извлекает все замороженные файлы, превращая их в обычные повседневные файлы, которые вы можете видеть и работать с ними как обычно. Вы можете изменить эти обычные файлы для чтения / записи или делать с ними все, что захотите, включая добавление новых и удаление существующих, все обычным способом, который вы делаете с компьютером.
Эти пригодные для использования файлы находятся в том, что Git называет вашим рабочим деревом. Вот где вы делаете свою работу. Это вторая копия каждого файла. Вам не нужно делать ничего особенного: это просто файлы. Если вы хотите посмотреть на файл с именем file
используйте любые инструменты (редактор, средство просмотра файлов и т. д.), которые вы всегда используете для просмотра файла с именем file
, Его зовут просто file
,
Третья копия каждого файла, где Git становится хитрым. Здесь и начинается индекс. Индекс также называется промежуточной областью, а иногда - редко в наши дни - кэшем. Это все имена для одного и того же. Третья копия каждого файла находится в индексе, и вы можете просмотреть индексную копию файла с именем file
с помощью git show :file
, Это, git show
перед двоеточием подразумевается: покажи мне копию в индексе. git ls-files
Команда, которую вы использовали в причудливом конвейере, также перечисляет, что находится в индексе.
Третья копия файла находится в формате, который Git использует для постоянного хранения замороженных файлов, но не совсем заморожена. Вы можете в любое время перезаписать его. Вы можете заменить индексную копию file
с любым новым контентом, который вам нравится. Вы делаете это с git add
, которые берут копию рабочего дерева - предположительно, вы уже изменили эту копию - и заменяете индексную копию этой версией. Или, если хотите, вы можете удалить индексную копию file
, с помощью git rm
, который удаляет как индексную копию, так и копию рабочего дерева.
Технически, в индексе есть только много данных из кэша о файле, а также несколько флагов, а также ссылка на сохраненную копию файла в замороженном формате. Когда вы впервые проверяете коммит, чтобы ваш HEAD
и копии рабочего дерева совпадают, ваша индексная копия действительно просто повторно использует замороженные HEAD
скопируйте напрямую, так что это не займет лишнего места вообще. Когда вы используете git add
чтобы перезаписать его, Git берет копию рабочего дерева, сжимает ее в замороженную, готовую к постоянному хранению копию, помещает эту копию куда-то в 4 и обновляет ссылку на индекс.
Это один из секретов, который делает git commit
так быстро. Git не должен смотреть на ваше рабочее дерево. Не нужно повторно сжимать все ваши файлы. Они уже там, в вашем индексе, готовы к работе. Все git commit
необходимо упаковать предварительно замороженные файлы в коммит. Он просто фиксирует все, что есть в вашем индексе во время выполнения git commit
, Следовательно, хороший способ думать об этом состоит в том, что индекс - это ваш следующий предложенный коммит. какая git add
а также git rm
сделать это обновить предложенный коммит. Бег git commit
просто сделайте снимки того, что находится в вашем индексе - в промежуточной области, готово для фиксации - даже если это в основном то же самое, что и предыдущий коммит. git add
а также git rm
Команды - это то, что фактически обновляет индекс.
Вот почему и как каждый коммит является полным снимком каждого файла. Любой файл, который вы не обновляете, все еще находится в индексе ("на стадии") и будет в следующем коммите.
git status
использует флаги
Предположим, у вас есть 3000 файлов в проверенном в данный момент коммите (и, следовательно, в вашем рабочем дереве), и вы изменили один в своем рабочем дереве и git add
чтобы получить обновление в вашем индексе / промежуточной области. Если вы бежите git status
в настоящее время, git status
не потрудился сказать вам, что 2999 из ваших 3000 файлов совпадают, так как это бесполезная информация. какая git status
говорит вам, что один файл обновлен.
Путь git status
Для этого, по крайней мере, в принципе, нужно выполнить два отдельных сравнения:
Первый,
git status
будет сравнивать каждый файл вHEAD
зафиксировать копию в индексе. Для каждого файла, который здесь одинаков, ничего не сказано. Но если файл здесь другой, он говорит: готовится к коммиту.Следующий,
git status
будет сравнивать каждый файл в индексе с копией в рабочем дереве. Опять же, если файлы одинаковые, это ничего не говорит. Если файлы разные, там написано: не подготовлено для коммита.
когда git status
Если сравнить это, то первая часть идет довольно быстро из-за внутреннего представления Git содержимого файла в виде хеш-идентификаторов BLOB-объектов. Так что, в буквальном смысле, просто сравнивает каждый файл. Это займет всего несколько миллисекунд, чтобы решить, что 2999 из 3000 файлов одинаковы и один отличается. Но вторая часть медленная: на самом деле сравнение всех 3000 файлов может занять несколько секунд!
Так, git status
читы. Это где аспект кэша индекса вступает в игру. Каждая запись индекса содержит ссылку на файл замороженного формата, который готов к фиксации; но он также содержит некоторые данные, полученные в результате ОС lstat
системный вызов. 5 Git может сделать другое lstat
системный вызов файла в рабочем дереве. В большинстве случаев в результате stat
данные совпадают с тем, что Git сохранял ранее, только в том случае, если файл в рабочем дереве по- прежнему совпадает с копией, которую Git имеет в замороженном формате, как это кэшируется в записи индекса. Если вы изменили копию рабочего дерева, ОС обновит stat
данные также.
Итак, представьте, что вы git status
, сравнивая каждый файл в индексе с его копией в рабочем дереве, так что вы можете сказать, что он не подготовлен для фиксации, если это необходимо. Вы можете открыть каждый файл рабочего дерева и прочитать его полностью, и сравнить его содержимое с тем, что вы получите, если распакуете замороженную индексную копию. Это скажет вам, если они одинаковые или разные, но вау, это большая работа, это может занять несколько секунд. Но у вас есть это в кеше stat
данные, и если вы сравните данные статистики с результатом другого lstat
Ну, это занимает гораздо меньше времени и работы. Таким образом, вы делаете это вместо этого. Если lstat
Результаты соответствуют кэшированным результатам, файл должен быть таким же, и вы можете ничего не говорить и переходить к следующему файлу.
Но на самом деле каждый lstat
Системный вызов также довольно медленный. Конечно, это в тысячи раз быстрее, чем чтение каждого файла, но это может занять сотни микросекунд. А что, если у ОС действительно ужасно медленно lstat
что занимает 3 миллисекунды? Выполнение этого для 3000 файлов, если каждый занимает 3 миллисекунды, займет девять секунд, а это слишком долго!
У Git есть флаг для этого. --assume-unchanged
flag, который является устанавливаемым флагом в каждой записи индекса, говорит Git: не беспокойтесь о вызове lstat
в этой копии рабочего дерева просто предположим, что она соответствует кэшированным данным статистики. У него есть второй, немного более мощный флаг, --skip-worktree
, который достигает того же результата. (Это немного более мощный, потому что некоторые команды, такие как git update-index --really-refresh
, будет игнорировать первый флаг, но не второй.)
Если вы установите любой бит, операции, которые будут сравнивать кэшированный индекс stat
данные против реальных stat
данные из рабочего дерева, чтобы сказать, действительно ли файл был изменен, просто предположим, что файл не был изменен. Очистите оба бита, и эти операции Git вызовут stat
после всего. затем git status
должно увидеть обновление файла, если stat
данные, которые возвращает ОС, также обновляются. Есть приемы уровня ОС, которые побеждают это, но вы обычно можете победить эти приемы уровня ОС, используя touch
:
touch path/to/file
удостоверяется, что stat
данные о path/to/file
теперь новее любого кешируемого stat
данные, которые Git может хранить.
Эта картина должна быть достаточно ясной, если она немного сложная: область индекса / промежуточного хранения содержит кэшированные данные о каждом файле рабочего дерева из предыдущего lstat
системный вызов. Если кэшированные данные соответствуют тому, что ОС сообщает о новом lstat
вызов, копия индекса должна соответствовать копии рабочего дерева. Если вы установите биты флага, Git не потрудится сделать lstat
call: он просто предполагает, что два набора данных совпадают, так что индексная копия совпадает с копией рабочего дерева, действительно ли это так. Очистить биты и Git возвращается к вызову lstat
и получает - мы надеемся - точный отчет от ОС.
Эта картина больше не является полностью верной, поскольку Git теперь также имеет возможность использовать монитор файловой системы, чтобы избежать вызова lstat
без необходимости. Но это тема для другого вопроса полностью.
1 Обратите внимание, что модный конвейер предполагает, что у вас есть LC_COLLATE
установлен в C
в какой-то версии grep
подчиняться LC_COLLATE
флаг. Это:
git ls-files -v | grep '^[a-z]'
может перечислить каждый файл в зависимости от LC_COLLATE
, В нем также перечислены --skip-worktree
файлы, но вы должны сбросить этот флаг с отдельным git update-index --no-skip-worktree
команда. Это одна из причин, по которой я написал git-flagged
, (Перечисление слишком много файлов из-за grep
слишком большое совпадение безвредно: просто git update-index
команды, которые на самом деле не нужно запускать.)
Я не сделал мой git-flagged
Скрипт поддерживает новые / недействительные биты fsmonitor. Если ваша система использует fsmonitor, и это идет не так, у вас есть большая проблема, и, возможно, вам следует отключить fsmonitor глобально, через git config
и core.fsmonitor
установка.
2 Это предполагает нормальное (не --bare
), и что вы не добавили дополнительные рабочие деревья, используя git worktree add
, Каждое рабочее дерево, которое вы добавляете git worktree add
получает свой собственный индекс и рабочее дерево и свой собственный HEAD
Таким образом, каждый получает еще три из этих активных копий.
3 После того, как вы сделаете коммит и получите определенный хеш-код, вы можете использовать этот хеш-код, чтобы увидеть, существует ли коммит еще. Если он существует - и, вероятно, существует, - то файлы, в которые вы его заморозили, также все еще существуют в этой замороженной форме.
Сложно на самом деле избавиться от плохого коммита. Это может быть сделано, так что коммиты не обязательно вечны, но это своего рода способ думать о них.
4 "Где-то" на самом деле прямо в хранилище. Если вы фиксируете эту копию файла, замороженная копия используется; если нет, то часто Git в конечном итоге очищается от мусора. Если у вас постоянно слишком мало места на диске, вам не нужно беспокоиться об этих вещах, которые git fsck
покажет как свисающие капли. Просто позвольте Git вычистить их позже, самостоятельно.
5 Это относится конкретно к POSIX lstat
системный вызов, который производит stat
данные. Если ваша базовая ОС не имеет или не использует stat
данные, Git все еще должен что-то кешировать, и будет использовать какой-то синтетический stat
данные, которые должны быть достаточно хороши, чтобы сделать остальную часть этой работы.