Есть ли способ заставить `git switch` отображать, какие локальные файлы он изменяет по мере его продвижения? - PullRequest
0 голосов
/ 17 марта 2020

Я немного расстраиваюсь из-за того, что git switch меняет кучу локальных файлов, но я не имею четкого представления о том, что, если только я не различаю ветки явно.

Я надеялся, что git switch --progress покажет мне это, но, увы, он по-прежнему ничего не показывает, хотя ветви, которые я переключаю, явно отличаются (как показано git diff), и я даже получаю "файлы изменены на диске "уведомления в моем редакторе, когда / после git switch работает.

Итак, есть ли способ заставить git switch показывать, что он делает с локально извлеченными файлами (не так полно, как diff, только одна строка статуса на файл, фактически измененный, будет делать), как он изменяет эти файлы?

(я использую git версия 2.25.1.)

1 Ответ

0 голосов
/ 17 марта 2020

Короткий ответ - нет: вам придется привыкнуть к такому поведению. (Это может помочь узнать, что Git делает и почему.)

Как и Джефф Меркадо, упомянутый в комментарии , вы можете получить git diff для скажу вам, что будет делать будущее git switch. Обратите внимание, что основная задача git diff заключается в сравнении двух коммитов или в сравнении одного коммита с рабочим деревом . 1 Другими словами, мы извлекаем первый коммит во временную область, затем извлеките второй коммит во временную область - или используйте рабочее дерево вместо второго коммита - и сравните их, с первым коммитом на «левой стороне» сравнения и вторым на правой стороне

Если вы просто запустите git diff <em>commit-specifier</em> без параметров, Git сделает такое сравнение, а затем даст следующий рецепт: добавьте этот новый файл, удалите этот файл полностью, удалите эти строки из файла A, добавьте эти строки в файл B и так далее. Следование этому рецепту изменит левый коммит на правый (или в соответствии с рабочим деревом).

Если вы добавите опцию --name-only, Git скажет вам меньше : вместо того, чтобы давать вам рецепт, он просто перечисляет имен файлов, которые будут добавлены, удалены или изменены .

Если вы используете вместо этого --name-status, Git сообщает вам промежуточную сумму: он по-прежнему перечисляет имена файлов, но на этот раз он префикс каждого из них с буквенным кодом: A для добавить этот файл , D для удалите этот файл , а M для измените этот файл вместо . (Есть еще несколько буквенных кодов; см. документацию для всех деталей.)

Следовательно:

git diff otherbranch

дает вам рецепт для создания снимка, представленного как последний коммит ветви с именем otherbranch и превращение этого снимка в то, что находится в вашем рабочем дереве прямо сейчас. Итак:

git diff --name-status otherbranch

скажет вам, какие файлы нужно будет добавить к , которые обязуются производить то, что у вас есть в вашем рабочем дереве: такие файлы, как правило, будут удалено при переключении на этот коммит. Он скажет вам, какие файлы должны быть удалены из этого коммита, чтобы создать то, что у вас есть в вашем рабочем дереве: такие файлы, как правило, будут добавлены при переключении на что совершать. И он скажет вам, какие файлы должны быть изменены. Если бы вы Git показали вам, какие изменения должны быть сделаны, то git checkout otherbranch, по сути, внесет противоположные изменения.


1 git diff Команда на самом деле имеет несколько основных заданий, и я пропускаю то, которое вы получаете, если вы запускаете git diff без аргументов вообще. Это сравнивает содержимое Git index с содержимым рабочего дерева. Я стараюсь, чтобы в этом ответе не было информации об индексе Git, за исключением этих сносок.


Почему все это задом наперед?

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

Помните, что каждый коммит содержит полный и полный снимок каждого файла . Когда вы делаете Git коммит, Git сохраняет - навсегда 2 - замороженный, сжатый, только для чтения, Git только снимок каждого файла , который вы сказали Git о. 3 Эти замороженные и Git -тифицированные копии файлов никогда не могут быть изменены, и будут действовать так же долго, как и коммит (см. Сноску 2).

Но только Git могут использовать эти файлы. Это означает, что эти коммиты хороши как архивы, но бесполезны для выполнения любой реальной работы. Чтобы использовать коммит, вам нужно получить Git, чтобы извлечь его, превратив все замороженные, Git файлы с изменениями в обычные повседневные файлы, которые вы можете просматривать и работать с ними.

Эти обычные файлы go в ваше рабочее дерево . Это файлы, которые вы можете открыть в своем редакторе. Следовательно, весь смысл git switch (или в более старых версиях Git, git checkout) заключается в замене всего рабочего дерева одним из некоторого другого коммита. Поскольку каждый коммит имеет полный снимок всех файлов, имеет смысл только удалить этот и проверить / переключиться на другой.

Так что этот вид git diff возможно, наиболее полезный, когда выполняется просто как:

git diff HEAD

, который сравнивает то, что находится в текущем коммите - тот, который вы выбрали ранее с git switch - с тем, что находится в рабочем дереве прямо сейчас , Любые различия - это то, что вы можете git add, а затем git commit: ваш новый коммит, после того как вы все настроите с помощью git add, будет содержать новый снимок, основанный на файлах, которые вы скопировали в индекс и затем зафиксировали , ... Упс, я пошел и упомянул index в теле ответа.


2 Коммит действительно остается только долго как вы можете найти это. Каждый коммит имеет уникальный га sh ID , и Git имеет способы найти эти идентификаторы ha sh, чтобы вы - и Git - могли найти коммиты. Если вам действительно нужно избавиться от коммита, это будет сложно, но вы можете заставить Git «забыть» коммит, если вы также хотите забыть всех его потомков. В этом случае фиксация в конечном итоге будет удалена через Git сборщик мусора , git gc.

3 Технически, Git делает каждый новый совершать из копий файлов, которые появляются в индексе Git. Вы используете git add, чтобы скопировать файл из вашего рабочего дерева в индекс Git. Когда вы переключаете на коммит, Git заполняет его индекс из этого коммита, а затем заполняет ваше рабочее дерево из того, что сейчас в индексе.


Краткий обзор индекс

Индекс - это выражение подразумевает, что есть только один, хотя на самом деле есть один для каждого рабочего дерева, что важно, если вы начнете использовать git worktree - имеет много ролей в Git, и следовательно, имеет три разных имени, которые означают одно и то же. Его часто называют областью подготовки , а иногда - редко в наши дни - кеш . Он делает много вещей, но его главная главная функция заключается в том, что именно здесь вы строите следующий коммит, чтобы сделать .

Индекс содержит копию каждого файла, который будет go в следующий коммит. 5 Как упоминалось в сноске 3, переключение на коммит копирует файлы, которые фиксируют файлы, в индекс и вашего рабочего дерева. Индексная копия каждого файла находится в замороженном Git -только внутреннем формате, готовом к go в следующем коммите. Копия рабочего дерева полезна для вас , поэтому Git записывает ее в область, предназначенную в основном для вашего использования.

Вы можете измените копирование рабочего дерева, сколько хотите. Это не влияет на копию index . Итак, если вы изменили копию рабочего дерева и хотели бы, чтобы обновленный файл был в следующем коммите, вам нужно выполнить:

git add path/to/file

сообщить Git: Скопировать копию рабочего дерева обратно в индекс, заменив там предыдущую копию. Git извлечет sh файл в замороженном формате и будет готов go в следующий коммит.

Когда вы запускаете git commit, Git просто упаковывает все, что находится в индексе в то время и делает это снимком для нового коммита. Вот почему вам нужно git add так часто: вам нужно заменить индексную копию, теперь, когда вы изменили копию рабочего дерева.

Вы не можете изменить копию HEAD: она внутри коммит, и все коммиты замораживаются на все время. Конечно, вы можете сделать новый коммит, после чего Git автоматически переключит на новый коммит - поэтому после коммита HEAD идентифицирует новый коммит и новый Замерзшая на все время копия commit соответствует замороженной (но заменяемой) копии индекса. Обратите внимание, что копия рабочего дерева не имела отношения к этому процессу.

(Git не записывает в вашу копию рабочего дерева в этом автоматическом c -switch-to- new-commit, поскольку реального переключения не происходит. Более подробно об этом см. Извлечение другой ветки при наличии незафиксированных изменений в текущей ветке .)


5 Технически, индекс содержит ссылку на копию содержимого файла в замороженном формате.


неотслеживаемые файлы

Стоит упомянуть одну последнюю морщинку. Во всех вышеперечисленных случаях ваше рабочее дерево в основном ваше , причем как угодно, за исключением того факта, что git checkout или git switch должны заполнить его из коммита, который, конечно, заменяет все ваши файлы.

Но так как ваше рабочее дерево является вашим, вы можете создавать в нем файлы, которых сейчас нет в индексе Git. , Вы также можете использовать git add или git rm, чтобы скопировать файлы в индекс, которых там никогда не было, или удалить файлы из индекса, которые были там (в результате переключения или извлечения), чтобы они не в индексе больше. В любом случае, довольно легко увидеть, что вы можете создать файл в вашем рабочем дереве, который не находится в индексе Git.

Файл, который не в index прямо сейчас - это неотслеживаемый файл . Это на самом деле довольно просто. Файл не отслеживается, если его нет в индексе. (Конечно, оно должно быть в вашем рабочем дереве. Если оно тоже не в вашем рабочем дереве, его просто нет вообще, так почему мы об этом говорим?) Поскольку git add помещает файлы в индекс, и git rm удаляет их, 6 вы можете изменить статус файла с неотслеживаемого на отслеживаемый или наоборот. Это никогда не изменит ни одного существующего коммита: файлы, хранящиеся в коммите, будут заморожены таким образом на все времена.

Отслеживается или не отслеживается является свойством индекс , который является временным так же, как ваше рабочее дерево является временным. Committed является постоянным, пока сам коммит продолжает существовать. Цель git switch состоит в том, чтобы выбрать коммит и заполнить дерево индекса и работы из этого коммита. Git, как правило, не допускает засорения неотслеживаемых файлов, которые вы поместили в ваше рабочее дерево. , но думайте о вашем рабочем дереве как о временном , потому что это: коммиты имеют значение, в конце концов.


6 Как ни странно, git add может удалить индексную копию файла. Предположим, что path/to/file находится в индексе прямо сейчас, а не в вашем рабочем дереве по какой-либо причине (вы, или что-то, что вы запустили, возможно, удалили его). Если вы сейчас запустите git add path/to/file, Git удалит копию из индекса. Это связано с тем, что git add на самом деле означает сделать индексное соответствие рабочему дереву , а не просто копировать из рабочего дерева в индекс .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...