diff

Поделись знанием:
Перейти к: навигация, поиск

В вычислительной технике diff — утилита сравнения файлов, выводящая разницу между двумя файлами. Эта программа выводит построчно изменения, сделанные в файле (для текстовых файлов). Современные реализации поддерживают также двоичные файлы. Вывод утилиты называется «diff», или, что более распространено, патч, так как он может быть применён с программой patch. Вывод других утилит сравнения файлов также часто называется «diff».





История

Утилита diff была разработана в начале 1970-х годов для операционной системы Unix, которая была плодом работы AT&T Bell Labs, в Мюррей Хилл (Нью-Джерси). Финальная версия, распространяемая с 5-й версией Unix в 1974, была полностью написана Дугласом Макилроем.

Алгоритм

Работа diff основана на нахождении наибольшей общей подпоследовательности (англ. longest common subsequence, проблема LCS). Например, имеются две последовательности элементов:

       a b c d f g h j q z
       a b c d e f g i j k r x y z

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

       a b c d f g j z

После получения наибольшей общей последовательности остаётся только небольшой шаг до получения похожего на diff вывода:

       e   h i   k   q r x y 
       +   - +   +   - + + +

Использование

diff вызывается из командной строки с именами двух файлов в качестве аргументов: diff original new. Вывод команды представляет собой изменения, которые нужно произвести в исходном файле original, чтобы получить новый файл new. Если original и new — директории, то diff автоматически будет применён к каждому файлу, который существует в обеих директориях. Все примеры в этой статье используют следующие два файла, original и new:

original:

Эта часть документа
оставалась неизменной
от версии к версии. Если
в ней нет изменений, она
не должна отображаться.
Иначе это не способствует
выводу оптимального 
объёма произведённых
изменений.

Этот абзац содержит
устаревший текст.
Он будет удалён
в ближайшем будущем.

В этом документе
необходима провести
проверку правописания.
С другой стороны, ошибка
в слове - не конец света.
Остальная часть абзаца
не требует изменений.
Новый текст можно
добавлять в конец документа.

new:

Это важное замечание!
Поэтому оно должно
быть расположено
в начале этого
документа!

Эта часть документа
оставалась неизменной
от версии к версии. Если
в ней нет изменений, она
не должна отображаться.
Иначе это не способствует
выводу оптимального 
объёма информации.
 
В этом документе
необходимо провести
проверку правописания.
С другой стороны, ошибка
в слове - не конец света.
Остальная часть абзаца
не требует изменений.
Новый текст можно
добавлять в конец документа.

Этот абзац содержит
важные дополнения
для данного документа.

Команда diff original new производит следующий нормальный дифф-вывод:

 0a1,6
 > Это важное замечание!
 > Поэтому оно должно
 > быть расположено
 > в начале этого
 > документа!
 > 
 8,14c14
 < объёма произведённых
 < изменений.
 < 
 < Этот абзац содержит
 < устаревший текст.
 < Он будет удалён
 < в ближайшем будущем.
 ---
 > объёма информации.
 17c17
 < необходима провести
 ---
 > необходимо провести
 24a25,28
 > 
 > Этот абзац содержит
 > важные дополнения
 > для данного документа.

В этом традиционном формате вывода a означает добавлено (от англ. add), dудалено, сизменено. Перед буквами a, d или c стоят номера строк исходного файла, после них — номера строк конечного файла. Каждая строка, которая была добавлена, удалена или изменена, предваряется угловыми скобками.

По умолчанию, общие для исходного и конечного файлов номера строк не указываются. Строки, которые перемещены, показываются как добавленные на своём новом месте и удалённые из своего прошлого расположения.[1]

Варианты

Большинство реализаций diff остаются внешне неизменными с 1975 года. Модификации включают в себя улучшения основного алгоритма, добавление новых ключей команды, новые форматы вывода. Базовый алгоритм изложен в книгах An O(ND) Difference Algorithm and its Variations Юджина В. Майерса,[2] и в A File Comparison Program Вебба Миллера и Майерса.[3] Алгоритм был независимо открыт и описан в Algorithms for Approximate String Matching Е. Укконеном[4] Первые версии программы diff были разработаны для сравнения строк текстовых файлов, использующих символ новой строки как разделитель строк. В 1980-х поддержка двоичных файлов привела к изменениям в схеме работы и реализации программы.

Edit script

Edit script можно сгенерировать современными версиями diff с помощью опции -e. Результат для нашего примера будет выглядеть так:

24a

Этот абзац содержит
важные дополнения
для данного документа.
.
17c
необходимо провести
.
8,14c
объёма информации.
.
0a
Это важное замечание!
Поэтому оно должно
быть расположено
в начале этого
документа!

.

Чтобы использовать полученный скрипт для преобразования файла original к состоянию файла new, нам нужно добавить в конец скрипта две строки: одна содержит команду w (write), другая - q (quit). Например так printf "w\nq\n" >> mydiff. Здесь мы дали diff-файлу имя mydiff. Преобразование произойдёт когда мы дадим команду ed -s original < mydiff.

Контекстный формат

В BSD версии 2.8 (выпущенной в июле 1981 года) появился контекстный формат (-c) и возможность рекурсивного обхода дерева каталогов файловой системы (-r).

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

Число незатронутых строк до и после изменённого фрагмента может задаваться пользователем и быть даже нулем, но обычно по умолчанию равно трем строкам. Если контекст незатронутых строк во фрагменте пересекается с соседним фрагментом, то diff избежит копирования незатронутых строк и объединит смежные фрагменты в один.

Вывод команды diff -c original new:

*** /path/to/original ''timestamp''
--- /path/to/new      ''timestamp''
***************
*** 1,3 ****
--- 1,9 ----
+ Это важное замечание!
+ Поэтому оно должно
+ быть расположено
+ в начале этого
+ документа!
+ 
  Эта часть документа
  оставалась неизменной
  от версии к версии. Если
***************
*** 5,20 ****
  не должна отображаться.
  Иначе это не способствует
  выводу оптимального 
! объёма произведённых
! изменений.
! 
! Этот абзац содержит
! устаревший текст.
! Он будет удалён
! в ближайшем будущем.
  
  В этом документе
! необходима провести
  проверку правописания.
  С другой стороны, ошибка
  в слове - не конец света.
--- 11,20 ----
  не должна отображаться.
  Иначе это не способствует
  выводу оптимального 
! объёма информации.
  
  В этом документе
! необходимо провести
  проверку правописания.
  С другой стороны, ошибка
  в слове - не конец света.
***************
*** 22,24 ****
--- 22,28 ----
  не требует изменений.
  Новый текст можно
  добавлять в конец документа.
+ 
+ Этот абзац содержит
+ важные дополнения
+ для данного документа.

Универсальный формат

Универсальный формат (или unidiff) включает в себя технические улучшения, сделанные в контекстном формате, но разницу между старым и новым текстом выдает в более компактом виде. Универсальный формат обычно вызывается использованием «-u» опции командной строки. Этот вывод часто используется как patch для программ. Многие проекты специально просят присылать им «diffs» в универсальном формате, делая, тем самым, универсальный формат самым распространенным для обмена между разработчиками программного обеспечения.

Универсальные контекстные diff’ы впервые были разработаны Wayne Davison в августе 1990 (unidiff появляется в главе 14 comp.sources.misc). Столлман добавил поддержку универсального формата в GNU Project's diff утилиту одним месяцем позже и эта функциональность дебютировала в GNU diff 1.15, выпущенная в январе 1991. GNU diff has since generalized the context format to allow arbitrary formatting of diffs.

Файл в универсальном формате начинается с тех же самых двух строк, что и контекстный формат, за исключением того, что оригинальный файл начинается с «---», а новый файл начинается с «+++». Следом за ними следует один или больше измененных фрагментов, которые содержат построчные изменения в файлах. Строки без изменений начинаются с пробела, добавленные строки начинаются со знака плюс, удаленные строки начинаются со знака минус.

Фрагмент начинается с информации о диапазоне и сразу за ним следуют добавленные строки, удаленные строки и любое количество контекстных строк. Информация о диапазоне окружена двойными знаками @ и объединена в одну строку, в отличие от двух строк в (контекстном формате). Информация о диапазоне имеет следующий формат:

@@ -l,s +l,s @@ optional section heading

Информация о диапазоне состоит из двух частей. Часть для оригинального файла начинается с минуса, а часть для нового файла начинается с плюса. Каждая часть в формате l, s, где l — номер строки, с которой начинаем, а s — количество строк, которые были изменены в текущем фрагменте для каждого из файлов, соответственно (то есть, в первом случае, это сумма выведенных строк, начинающихся с пробела и с минуса, во втором — строк, начинающихся с пробела и с плюса). Во многих версиях GNU diff в каждом диапазоне запятая и замыкающая s могут быть опущены. В этом случае s по умолчанию равна 1. Обратите внимание, что единственное полезное значение только у l — номер строки первого диапазона, остальные значения могут быть вычислены из diff’а.

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

Фрагмент диапазона может быть предварен заголовком секции или функции, частью которой является фрагмент. Это обычно полезно для чтения самого фрагмента. Когда создается diff с использованием GNU, diff заголовок определяется регулярным выражением[5]

Если строка была изменена, она показывается и как удаленная, и как добавленная. Так как удаленная и добавленная строки находятся в смежных фрагментах, то эти строки показываются рядом друг с другом[6]. Например:

-check this dokument. On
+check this document. On

Команда diff -u original new создаст следующий вывод:

--- /path/to/original	''timestamp''
+++ /path/to/new	''timestamp''
@@ -1,3 +1,9 @@
+Это важное замечание!
+Поэтому оно должно
+быть расположено
+в начале этого
+документа!
+
 Эта часть документа
 оставалась неизменной
 от версии к версии. Если
@@ -5,16 +11,10 @@
 не должна отображаться.
 Иначе это не способствует
 выводу оптимального 
-объёма произведённых
-изменений.
-
-Этот абзац содержит
-устаревший текст.
-Он будет удалён
-в ближайшем будущем.
+объёма информации.
 
 В этом документе
-необходима провести
+необходимо провести
 проверку правописания.
 С другой стороны, ошибка
 в слове - не конец света.
@@ -22,3 +22,7 @@
 не требует изменений.
 Новый текст можно
 добавлять в конец документа.
+
+Этот абзац содержит
+важные дополнения
+для данного документа.

Обратите внимание, чтобы нормально отделить имена файлов от временных меток используется табуляция. Это незаметно на экране и может быть утеряно при копировании/вставке из консоли.

Есть несколько изменений и расширений для diff форматов, которые используют и понимают различные программы. Например, некоторые системы управления версиями, такие как Subversion, указывают номер версии, «рабочую копию» или любой другой комментарий в дополнение к временной метке в заголовке diff’a.

Некоторые программы позволяют создавать diff’ы для нескольких разных файлов и сливают их в один, используя заголовок для каждого измененного файла, который может выглядеть примерно так:

Index: path/to/file.cpp

Специальный вид файлов, которые не заканчиваются новой строкой, не поддерживается. Ни unidiff утилита, ни POSIX diff стандарт не определяют способ обработки таких файлов (более того, файлы такого типа не являются «текстовыми» в определении POSIX[7]).

Программа patch ничего не знает о реализации специального вывода команды diff.

См. также

Напишите отзыв о статье "Diff"

Примечания

  1. David MacKenzie, Paul Eggert, and Richard Stallman. [www.gnu.org/software/diffutils/manual/ Comparing and Merging Files with GNU Diff and Patch]. — 1997. — ISBN ISBN 0-9541617-5-0.
  2. E. Myers (1986). «[citeseer.ist.psu.edu/myers86ond.html An O(ND) Difference Algorithm and Its Variations]». Algorithmica 1 (2): 251–266.
  3. Webb Miller and Eugene W. Myers (1985). «A File Comparison Program». Software — Practice and Experience 15 (11): 1025–1040.
  4. E. Ukkonen (1985). «Algorithms for Approximate String Matching». Information and Control 64: 100–118.
  5. [www.gnu.org/software/diffutils/manual/html_node/Sections.html 2.2.3 Showing Which Sections Differences Are in], GNU diffutils manual
  6. [www.artima.com/weblogs/viewpost.jsp?thread=164293 Unified Diff Format] by Guido van Rossum, Июнь 14, 2006
  7. pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_205 Section 3.205

Ссылки

  • [www.gnu.org/software/diffutils/ Пакет GNU diffutils] включает в себя diff. Распространяется под GNU General Public License.
  • [gnuwin32.sourceforge.net/packages/diffutils.htm diffutils для Win32] — часть GnuWin32
  • [dokxpi.github.io/Quick/ Онлайновый интерфейс к diff] (рус.)
  • [www.mathertel.de/Diff/ Алгоритм diff на C#] — Исходный код алгоритма diff и его вариантов на C#

Отрывок, характеризующий Diff

Болконский узнал князя Репнина, которого он встречал в петербургском свете. Рядом с ним стоял другой, 19 летний мальчик, тоже раненый кавалергардский офицер.
Бонапарте, подъехав галопом, остановил лошадь.
– Кто старший? – сказал он, увидав пленных.
Назвали полковника, князя Репнина.
– Вы командир кавалергардского полка императора Александра? – спросил Наполеон.
– Я командовал эскадроном, – отвечал Репнин.
– Ваш полк честно исполнил долг свой, – сказал Наполеон.
– Похвала великого полководца есть лучшая награда cолдату, – сказал Репнин.
– С удовольствием отдаю ее вам, – сказал Наполеон. – Кто этот молодой человек подле вас?
Князь Репнин назвал поручика Сухтелена.
Посмотрев на него, Наполеон сказал, улыбаясь:
– II est venu bien jeune se frotter a nous. [Молод же явился он состязаться с нами.]
– Молодость не мешает быть храбрым, – проговорил обрывающимся голосом Сухтелен.
– Прекрасный ответ, – сказал Наполеон. – Молодой человек, вы далеко пойдете!
Князь Андрей, для полноты трофея пленников выставленный также вперед, на глаза императору, не мог не привлечь его внимания. Наполеон, видимо, вспомнил, что он видел его на поле и, обращаясь к нему, употребил то самое наименование молодого человека – jeune homme, под которым Болконский в первый раз отразился в его памяти.
– Et vous, jeune homme? Ну, а вы, молодой человек? – обратился он к нему, – как вы себя чувствуете, mon brave?
Несмотря на то, что за пять минут перед этим князь Андрей мог сказать несколько слов солдатам, переносившим его, он теперь, прямо устремив свои глаза на Наполеона, молчал… Ему так ничтожны казались в эту минуту все интересы, занимавшие Наполеона, так мелочен казался ему сам герой его, с этим мелким тщеславием и радостью победы, в сравнении с тем высоким, справедливым и добрым небом, которое он видел и понял, – что он не мог отвечать ему.
Да и всё казалось так бесполезно и ничтожно в сравнении с тем строгим и величественным строем мысли, который вызывали в нем ослабление сил от истекшей крови, страдание и близкое ожидание смерти. Глядя в глаза Наполеону, князь Андрей думал о ничтожности величия, о ничтожности жизни, которой никто не мог понять значения, и о еще большем ничтожестве смерти, смысл которой никто не мог понять и объяснить из живущих.
Император, не дождавшись ответа, отвернулся и, отъезжая, обратился к одному из начальников:
– Пусть позаботятся об этих господах и свезут их в мой бивуак; пускай мой доктор Ларрей осмотрит их раны. До свидания, князь Репнин, – и он, тронув лошадь, галопом поехал дальше.
На лице его было сиянье самодовольства и счастия.
Солдаты, принесшие князя Андрея и снявшие с него попавшийся им золотой образок, навешенный на брата княжною Марьею, увидав ласковость, с которою обращался император с пленными, поспешили возвратить образок.
Князь Андрей не видал, кто и как надел его опять, но на груди его сверх мундира вдруг очутился образок на мелкой золотой цепочке.
«Хорошо бы это было, – подумал князь Андрей, взглянув на этот образок, который с таким чувством и благоговением навесила на него сестра, – хорошо бы это было, ежели бы всё было так ясно и просто, как оно кажется княжне Марье. Как хорошо бы было знать, где искать помощи в этой жизни и чего ждать после нее, там, за гробом! Как бы счастлив и спокоен я был, ежели бы мог сказать теперь: Господи, помилуй меня!… Но кому я скажу это! Или сила – неопределенная, непостижимая, к которой я не только не могу обращаться, но которой не могу выразить словами, – великое всё или ничего, – говорил он сам себе, – или это тот Бог, который вот здесь зашит, в этой ладонке, княжной Марьей? Ничего, ничего нет верного, кроме ничтожества всего того, что мне понятно, и величия чего то непонятного, но важнейшего!»
Носилки тронулись. При каждом толчке он опять чувствовал невыносимую боль; лихорадочное состояние усилилось, и он начинал бредить. Те мечтания об отце, жене, сестре и будущем сыне и нежность, которую он испытывал в ночь накануне сражения, фигура маленького, ничтожного Наполеона и над всем этим высокое небо, составляли главное основание его горячечных представлений.
Тихая жизнь и спокойное семейное счастие в Лысых Горах представлялись ему. Он уже наслаждался этим счастием, когда вдруг являлся маленький Напoлеон с своим безучастным, ограниченным и счастливым от несчастия других взглядом, и начинались сомнения, муки, и только небо обещало успокоение. К утру все мечтания смешались и слились в хаос и мрак беспамятства и забвения, которые гораздо вероятнее, по мнению самого Ларрея, доктора Наполеона, должны были разрешиться смертью, чем выздоровлением.
– C'est un sujet nerveux et bilieux, – сказал Ларрей, – il n'en rechappera pas. [Это человек нервный и желчный, он не выздоровеет.]
Князь Андрей, в числе других безнадежных раненых, был сдан на попечение жителей.


В начале 1806 года Николай Ростов вернулся в отпуск. Денисов ехал тоже домой в Воронеж, и Ростов уговорил его ехать с собой до Москвы и остановиться у них в доме. На предпоследней станции, встретив товарища, Денисов выпил с ним три бутылки вина и подъезжая к Москве, несмотря на ухабы дороги, не просыпался, лежа на дне перекладных саней, подле Ростова, который, по мере приближения к Москве, приходил все более и более в нетерпение.
«Скоро ли? Скоро ли? О, эти несносные улицы, лавки, калачи, фонари, извозчики!» думал Ростов, когда уже они записали свои отпуски на заставе и въехали в Москву.
– Денисов, приехали! Спит! – говорил он, всем телом подаваясь вперед, как будто он этим положением надеялся ускорить движение саней. Денисов не откликался.
– Вот он угол перекресток, где Захар извозчик стоит; вот он и Захар, и всё та же лошадь. Вот и лавочка, где пряники покупали. Скоро ли? Ну!
– К какому дому то? – спросил ямщик.
– Да вон на конце, к большому, как ты не видишь! Это наш дом, – говорил Ростов, – ведь это наш дом! Денисов! Денисов! Сейчас приедем.
Денисов поднял голову, откашлялся и ничего не ответил.
– Дмитрий, – обратился Ростов к лакею на облучке. – Ведь это у нас огонь?
– Так точно с и у папеньки в кабинете светится.
– Еще не ложились? А? как ты думаешь? Смотри же не забудь, тотчас достань мне новую венгерку, – прибавил Ростов, ощупывая новые усы. – Ну же пошел, – кричал он ямщику. – Да проснись же, Вася, – обращался он к Денисову, который опять опустил голову. – Да ну же, пошел, три целковых на водку, пошел! – закричал Ростов, когда уже сани были за три дома от подъезда. Ему казалось, что лошади не двигаются. Наконец сани взяли вправо к подъезду; над головой своей Ростов увидал знакомый карниз с отбитой штукатуркой, крыльцо, тротуарный столб. Он на ходу выскочил из саней и побежал в сени. Дом также стоял неподвижно, нерадушно, как будто ему дела не было до того, кто приехал в него. В сенях никого не было. «Боже мой! все ли благополучно?» подумал Ростов, с замиранием сердца останавливаясь на минуту и тотчас пускаясь бежать дальше по сеням и знакомым, покривившимся ступеням. Всё та же дверная ручка замка, за нечистоту которой сердилась графиня, также слабо отворялась. В передней горела одна сальная свеча.
Старик Михайла спал на ларе. Прокофий, выездной лакей, тот, который был так силен, что за задок поднимал карету, сидел и вязал из покромок лапти. Он взглянул на отворившуюся дверь, и равнодушное, сонное выражение его вдруг преобразилось в восторженно испуганное.
– Батюшки, светы! Граф молодой! – вскрикнул он, узнав молодого барина. – Что ж это? Голубчик мой! – И Прокофий, трясясь от волненья, бросился к двери в гостиную, вероятно для того, чтобы объявить, но видно опять раздумал, вернулся назад и припал к плечу молодого барина.
– Здоровы? – спросил Ростов, выдергивая у него свою руку.
– Слава Богу! Всё слава Богу! сейчас только покушали! Дай на себя посмотреть, ваше сиятельство!
– Всё совсем благополучно?
– Слава Богу, слава Богу!
Ростов, забыв совершенно о Денисове, не желая никому дать предупредить себя, скинул шубу и на цыпочках побежал в темную, большую залу. Всё то же, те же ломберные столы, та же люстра в чехле; но кто то уж видел молодого барина, и не успел он добежать до гостиной, как что то стремительно, как буря, вылетело из боковой двери и обняло и стало целовать его. Еще другое, третье такое же существо выскочило из другой, третьей двери; еще объятия, еще поцелуи, еще крики, слезы радости. Он не мог разобрать, где и кто папа, кто Наташа, кто Петя. Все кричали, говорили и целовали его в одно и то же время. Только матери не было в числе их – это он помнил.
– А я то, не знал… Николушка… друг мой!
– Вот он… наш то… Друг мой, Коля… Переменился! Нет свечей! Чаю!
– Да меня то поцелуй!
– Душенька… а меня то.
Соня, Наташа, Петя, Анна Михайловна, Вера, старый граф, обнимали его; и люди и горничные, наполнив комнаты, приговаривали и ахали.
Петя повис на его ногах. – А меня то! – кричал он. Наташа, после того, как она, пригнув его к себе, расцеловала всё его лицо, отскочила от него и держась за полу его венгерки, прыгала как коза всё на одном месте и пронзительно визжала.
Со всех сторон были блестящие слезами радости, любящие глаза, со всех сторон были губы, искавшие поцелуя.
Соня красная, как кумач, тоже держалась за его руку и вся сияла в блаженном взгляде, устремленном в его глаза, которых она ждала. Соне минуло уже 16 лет, и она была очень красива, особенно в эту минуту счастливого, восторженного оживления. Она смотрела на него, не спуская глаз, улыбаясь и задерживая дыхание. Он благодарно взглянул на нее; но всё еще ждал и искал кого то. Старая графиня еще не выходила. И вот послышались шаги в дверях. Шаги такие быстрые, что это не могли быть шаги его матери.
Но это была она в новом, незнакомом еще ему, сшитом без него платье. Все оставили его, и он побежал к ней. Когда они сошлись, она упала на его грудь рыдая. Она не могла поднять лица и только прижимала его к холодным снуркам его венгерки. Денисов, никем не замеченный, войдя в комнату, стоял тут же и, глядя на них, тер себе глаза.
– Василий Денисов, друг вашего сына, – сказал он, рекомендуясь графу, вопросительно смотревшему на него.
– Милости прошу. Знаю, знаю, – сказал граф, целуя и обнимая Денисова. – Николушка писал… Наташа, Вера, вот он Денисов.
Те же счастливые, восторженные лица обратились на мохнатую фигуру Денисова и окружили его.
– Голубчик, Денисов! – визгнула Наташа, не помнившая себя от восторга, подскочила к нему, обняла и поцеловала его. Все смутились поступком Наташи. Денисов тоже покраснел, но улыбнулся и взяв руку Наташи, поцеловал ее.
Денисова отвели в приготовленную для него комнату, а Ростовы все собрались в диванную около Николушки.
Старая графиня, не выпуская его руки, которую она всякую минуту целовала, сидела с ним рядом; остальные, столпившись вокруг них, ловили каждое его движенье, слово, взгляд, и не спускали с него восторженно влюбленных глаз. Брат и сестры спорили и перехватывали места друг у друга поближе к нему, и дрались за то, кому принести ему чай, платок, трубку.
Ростов был очень счастлив любовью, которую ему выказывали; но первая минута его встречи была так блаженна, что теперешнего его счастия ему казалось мало, и он всё ждал чего то еще, и еще, и еще.
На другое утро приезжие спали с дороги до 10 го часа.
В предшествующей комнате валялись сабли, сумки, ташки, раскрытые чемоданы, грязные сапоги. Вычищенные две пары со шпорами были только что поставлены у стенки. Слуги приносили умывальники, горячую воду для бритья и вычищенные платья. Пахло табаком и мужчинами.
– Гей, Г'ишка, т'убку! – крикнул хриплый голос Васьки Денисова. – Ростов, вставай!
Ростов, протирая слипавшиеся глаза, поднял спутанную голову с жаркой подушки.
– А что поздно? – Поздно, 10 й час, – отвечал Наташин голос, и в соседней комнате послышалось шуршанье крахмаленных платьев, шопот и смех девичьих голосов, и в чуть растворенную дверь мелькнуло что то голубое, ленты, черные волоса и веселые лица. Это была Наташа с Соней и Петей, которые пришли наведаться, не встал ли.
– Николенька, вставай! – опять послышался голос Наташи у двери.
– Сейчас!
В это время Петя, в первой комнате, увидав и схватив сабли, и испытывая тот восторг, который испытывают мальчики, при виде воинственного старшего брата, и забыв, что сестрам неприлично видеть раздетых мужчин, отворил дверь.
– Это твоя сабля? – кричал он. Девочки отскочили. Денисов с испуганными глазами спрятал свои мохнатые ноги в одеяло, оглядываясь за помощью на товарища. Дверь пропустила Петю и опять затворилась. За дверью послышался смех.
– Николенька, выходи в халате, – проговорил голос Наташи.
– Это твоя сабля? – спросил Петя, – или это ваша? – с подобострастным уважением обратился он к усатому, черному Денисову.
Ростов поспешно обулся, надел халат и вышел. Наташа надела один сапог с шпорой и влезала в другой. Соня кружилась и только что хотела раздуть платье и присесть, когда он вышел. Обе были в одинаковых, новеньких, голубых платьях – свежие, румяные, веселые. Соня убежала, а Наташа, взяв брата под руку, повела его в диванную, и у них начался разговор. Они не успевали спрашивать друг друга и отвечать на вопросы о тысячах мелочей, которые могли интересовать только их одних. Наташа смеялась при всяком слове, которое он говорил и которое она говорила, не потому, чтобы было смешно то, что они говорили, но потому, что ей было весело и она не в силах была удерживать своей радости, выражавшейся смехом.