Понимание вывода статуса git с помощью короткого флага - PullRequest
0 голосов
/ 06 июля 2018
$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

Имеется два столбца для вывода: левый столбец указывает состояние промежуточной области, а правый столбец - состояние рабочего дерева. Так, например, в этих выходных данных файл README изменяется в рабочем каталоге, но еще не подготовлен, а файл lib / simplegit.rb - изменен и подготовлен. Rake-файл был изменен, подготовлен, а затем снова изменен, поэтому в него внесены изменения, как поэтапные, так и неустановленные.

Вышесказанное принадлежит Pro Git Скотта Чакона и Бена Штрауба и опубликовано Apress.

Я запутался в разнице между областью подготовки и рабочим деревом. И я объясню, что я верю, чтобы быть правдой.

«файл README изменен в рабочем каталоге, но еще не подготовлен»: мы не отслеживаем этот файл. Тем не менее, Git понимает, что он был изменен. С последнего снимка.

«Файл lib / simplegit.rb изменен и подготовлен»: после изменения мы подготовили файл. Все, что осталось - это коммит.

"Rakefile был изменен, подготовлен и затем изменен снова, поэтому в нем есть изменения, которые являются как промежуточными, так и неизменными.": Как и в предыдущем файле, мы подготовили измененный файл. Что дальше?

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

«Файл README изменен в рабочем каталоге, но еще не подготовлен»: мы не отслеживаем этот файл. Тем не менее, Git понимает, что он был изменен. С последнего снимка.

Нет, это неправильно. Сложная часть с областью размещения в том, что она обычно невидима. Это ведет людей по неверному пути, пытаясь понять, как это работает.

Во-первых, давайте рассмотрим терминологию Git. На данный момент есть три объекта, представляющих интерес: текущая фиксация , промежуточная область , которая на самом деле имеет три имени, и рабочее дерево . Три области для промежуточной области: index , staging-area и cache , и эти три имени отражают низкое качество исходного выбора Линуса Торвальда ( «индекс») или огромная важность невидимой площадки или того и другого. (Я думаю, что оба.) Давайте посмотрим глубже на каждого из них:

  • Текущий коммит, который мы также можем назвать по имени HEAD (во всех столицах 1 ), это, конечно, коммит - это снимок всех файлов, которые были в область подготовки, когда вы (или кто-либо еще) бежал git commit. Этот снимок является постоянным (в основном) и доступным только для чтения (полностью). Его настоящее имя не HEAD - это просто символическое имя, по которому мы можем его найти прямо сейчас, а скорее какой-то большой уродливый идентификатор хеша. Идентификатор хэша выглядит случайным, но на самом деле это криптографическая контрольная сумма всего содержимого коммита. Именно поэтому почему фиксация не может быть изменена - изменение чего-либо приведет к изменению контрольной суммы, что приведет к другому коммиту.

    Файлы, хранящиеся в 2 фиксации, также доступны только для чтения. Они хранятся в специальной, только для Git, сжатой форме. Это конкретное сжатие обладает приятным свойством: если содержимое файла одинаково для одного и того же коммита, оно фиксирует все share базового сжатого файла-образа. Это означает, что вы можете фиксировать большой файл миллионы раз, если хотите, и не использовать больше места, чем один раз.

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

    (Индекс также кэширует - отсюда и название «кеш») информацию о рабочем дереве, чтобы ускорить работу Git. Эти два факта: индекс хранит все файлы, готовые для перехода в следующий коммит, и что он кеширует информацию о рабочем дереве, что делает git commit настолько безумно быстрым по сравнению с другими подобными системами контроля версий.)

  • Рабочее дерево - самое простое из трех, но в некотором смысле Git меньше всего заботится о нем. Это то место, где вы работаете над своими файлами. Эти файлы в обычном формате, который понимают остальные ваши компьютерные программы. Они наиболее важны для you , но наименее важны для Git: репозиторий --bare имеет рабочее дерево no , но Git все еще может функционировать (в более ограниченном Конечно).

Рабочее дерево - единственная из этих трех вещей, которую вы можете видеть легко и непосредственно. Просто используйте любую команду, которая перечисляет файлы или просматривает файлы: они там, наглядно. К счастью, коммиты также легко увидеть, проверив их.

Когда тыИзначально проверьте какой-то конкретный коммит - например, через git checkout master или git checkout develop - Git заполняет и ваш индекс / промежуточную область и ваше рабочее дерево из этого коммита. Он устанавливает HEAD как символическое имя для правильного идентификатора хеша. Таким образом, в индексе уже есть все те же файлы, которые есть в коммите HEAD, а в рабочем дереве все те же файлы, что и в индексе.

Если вы измените файл в рабочем дереве, а затем запустите на нем git add, Git скопирует версию этого файла в рабочем дереве в область index / staging. Теперь версия фиксации HEAD и версия индекса различаются, но версия индекса и версия рабочего дерева согласуются друг с другом.

Если вы изменяете файл в рабочем дереве, но не запускаете git add на нем, версии HEAD и index соглашаются, но версия индекса не согласуется с версией рабочего дерева .

Если вы изменяете файл в рабочем дереве, то (1) используйте git add, чтобы скопировать его в индексную / промежуточную область, и (2) измените его снова , теперь все три версии этого файла отличаются. Здесь вы увидите статус MM.

То, что делает git status, в действительности запускает две разницы. Первый сравнивает HEAD с индексом. Все, что здесь отличается, «ставится на коммит». Вторая разница сравнивает индекс с рабочим деревом. Что бы здесь ни отличалось, «не ставится на коммит». Это почти это - мы почти закончили!

Наконец, давайте посмотрим на термин отслеживается применительно к файлам. В Git файл отслеживается тогда и только тогда, когда он находится в области index / staging-area. Это действительно так просто! Сложная задача - определить, находится ли файл на самом деле в индексе, поскольку обычно он там невидим.

Команда git status сравнивает индекс: сначала она сравнивает HEAD против index. Предположим, что какой-то файл находится в HEAD и index и имеет одинаковое содержимое в обоих. Тогда вы не увидите это здесь. Точно так же вы не увидите его здесь, если оно совпадает с индексом и рабочим деревом. Поэтому, если файл в индексе , но соответствует как HEAD, так и версиям рабочего дерева, он невидим.

Предположим, что какой-то файл не в индексе. Если он находится в HEAD, git status сообщит вам, что между HEAD и индексом файл был удален - D в первом столбце короткого вывода. Таким образом, в этом случае вы можете сказать: файл удалился из индекса и больше не отслеживается. Это не будет в следующем коммите.

Предположим, что некоторый файл не в HEAD, но - в индексе. В этом случае git status сообщит вам, что между HEAD и индексом файл получил добавленный - A в первом столбце короткого вывода. Таким образом, в этом случае вы можете сказать, что файл теперь отслеживается и будет в следующем коммите.

Сложный случай возникает, когда файл не отслеживается и игнорируется , потому что теперь, если файл не в коммите HEAD (и по определению его нет в index - мы только что сказали, что он не отслежен), первая колонка ничего вам не скажет: она не относится ни к одной из этих двух сущностей, поэтому Git здесь ничего не говорит. Во втором столбце может указываться, что индекс и рабочее дерево не совпадают, если файл существует в рабочем дереве, но поскольку вы сказали Git, что неотслеживаемый файл рабочего дерева следует игнорировать, git status здесь тоже не упомяну.

Наконец, стоит упомянуть несколько вещей:

  • Вы можете просматривать индекс. Запустите git ls-files --stage, чтобы увидеть быстрый обзор того, что на самом деле находится в области подготовки. Это нецелесообразно в большом проекте именно потому, что в промежуточной области хранится копия каждого файла, то есть каждого файла, который будет зафиксирован. Это могут быть десятки тысяч файлов. Гораздо полезнее увидеть разницу между коммитом HEAD и индексной / промежуточной областью, поэтому именно это и делает git status (в первом столбце вывода --short).

  • Вы также можете просматривать содержимое коммита напрямую. Запустите git ls-tree -r HEAD, чтобы увидеть все зафиксированные файлы. Вывод аналогичен git ls-files --stage. (Он добавляет имя типа объекта Git и убирает промежуточный номер и использует древовидную структуру, а не уплощенное дерево индекса.) Как и в случае git ls-files --stage, это в основном полезно для отладки Git или написания необычных новых команд, а не для обычных работа.

Ключевым моментом здесь является то, что git status суммирует состояние трех представляющих интерес объектов, сравнивая HEAD с индексом, а затем сравнивая индекс с рабочим деревом. Два столбца показывают разницу между между ними, сокращенную до буквенного кода и имени файла. Даже при том, что следующий коммит будет снимком каждого файла, который находится в области индекса / промежуточной области в то время, более полезно рассказать вам, что отличается в этом снимке по сравнению с текущим снимком, или потенциальный снимок, который вы могли бы сделать, скопировав файлы рабочего дерева в индекс.


1 В Windows и MacOS, где при открытии файла с именем readme.txt открывается существующий файл с именем README.TXT (и наоборот), вы можете использовать строчные буквы, но в Git есть несколько мест, где он трудно кодирует все прописные строки HEAD, так что лучше придерживаться этого. Если вам не нравится печатать так много, символ @ является синонимом HEAD.

2 Технически, фиксация хранит хэш-идентификатор объекта tree . Объект дерева хранит имя каждого файла, режим (100644 или 100755) и идентификатор содержимого хэша, а также имена и идентификаторы хэша для поддеревьев при необходимости. Следовательно, содержимое файла на самом деле не внутри коммита, а скорее как blob объектов, прямо рядом с коммитом и объектами дерева. Это механизм, с помощью которого коммиты - и индекс! - делятся объектами больших двоичных объектов, поэтому, сколько бы у вас ни было снимков большого файла, у вас действительно есть только одна копия в базе данных репозитория.

0 голосов
/ 06 июля 2018

Вы можете прочитать о том, что буквы означают здесь:

https://www.git -scm.com / docs / git-status # _short_format

If "область подготовки"," добавлено "или" не объединено "вам не знакомо, возможно, вам нужно углубить свое понимание мерзавца.Или, может быть, просто прекратите использовать флаг -s, который на самом деле проще понять.

Git pro git действительно git, но вы не можете выбрать то, что хотите прочитать.Прочитайте все, в правильном порядке.https://git -scm.com / книга / а / v2

...