Скотт Чакон - Pro Git
- Название:Pro Git
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Чакон - Pro Git краткое содержание
В книге рассматриваются следующие темы: основы Git;
ветвление в Git;
Git на сервере;
распределённый Git;
GitHub;
инструменты Git;
настройка Git;
Git и другие системы контроля версий.
Pro Git - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Если вы указали опцию --mixed, выполнение reset остановится на этом шаге. Такое поведение также используется по умолчанию, поэтому если вы не указали совсем никаких опций (в нашем случае git reset HEAD~), выполнение команды также остановится на этом шаге.
Снова взгляните на диаграмму и постарайтесь разобраться, что произошло: отменен не только ваш последний commit, но также и добавление в индекс всех файлов. Вы откатились назад до момента выполнения команд git add и git commit.
Шаг 3: Обновление Рабочего Каталога (--hard)
Третье, что сделает reset – это приведение вашего Рабочего Каталога к тому же виду, что и Индекс. Если вы используете опцию --hard, то выполнение команды будет продолжено до этого шага.
Давайте разберемся, что сейчас случилось. Вы отменили ваш последний коммит, результаты выполнения команд git add и git commit, а также всеизменения, которые вы сделали в рабочем каталоге.
Важно отметить, что только указание этого флага (--hard) делает команду reset опасной, это один из немногих случаев, когда Git действительно удаляет данные. Все остальные вызовы reset легко отменить, но при указании опции --hard команда принудительно перезаписывает файлы в Рабочем Каталоге. В данном конкретном случае, версия v3нашего файла всё еще остается в коммите внутри базы данных Git и мы можем вернуть ее, просматривая наш reflog, но если вы не коммитили эту версию, Git перезапишет файл и ее уже нельзя будет восстановить.
Резюме
Команда reset в заранее определенном порядке перезаписывает три дерева Git, останавливаясь тогда, когда вы ей скажете:
1. Перемещает ветку, на которую указывает HEAD (останавливается на этом, если указана опция --soft)
2. Делает Индекс таким же как и HEAD (останавливается на этом, если не указана опция --hard)
3. Делает Рабочий Каталог таким же как и Индекс.
Reset с указанием пути
Основной форме команды reset (без опций --soft и --hard) вы также можете передавать путь, с которым она будет оперировать. В этом случае, reset пропустит первый шаг, а на остальных будет работать только с указанным файлом или набором файлов. Первый шаг пропускается, так как HEAD является указателем и не может ссылаться частично на один коммит, а частично на другой. Но Индекс и Рабочий Каталог могут быть изменены частично, поэтому reset выполняет шаги 2 и 3.
Итак, предположим вы выполнили команду git reset file.txt. Эта форма записи (так как вы не указали ни SHA-1 коммита, ни ветку, ни опций --soft или --hard) является сокращением для git reset --mixed HEAD file.txt, которая:
1. Перемещает ветку, на которую указывает HEAD (будет пропущено)
2. Делает Индекс таким же как и HEAD (остановится здесь)
То есть, фактически, она копирует файл file.txt из HEAD в Индекс.
Это создает эффект отмены индексации файла. Если вы посмотрите на диаграммы этой команды и команды git add, то увидите, что их действия прямо противоположные.
Именно поэтому в выводе git status предлагается использовать такую команду для отмены индексации файла. (Смотрите подробности в Отмена подготовки файла.)
Мы легко можем заставить Git “брать данные не из HEAD”, указав коммит, из которого нужно взять версию этого файла. Для этого мы должны выполнить следующее git reset eb43bf file.txt.
Можно считать, что, фактически, мы в Рабочем Каталоге вернули содержимое файла к версии v1, выполнили для него git add, а затем вернули содержимое обратно к версии v3(в действительности все эти шаги не выполняются). Если сейчас мы выполним git commit, то будут сохранены изменения, которые возвращают файл к версии v1, но при этом файл в Рабочем Каталоге никогда не возвращался к такой версии.
Заметим, что как и команде git add, reset можно указывать опцию --patch для отмены индексации части содержимого. Таким способом вы можете избирательно отменять индексацию или откатывать изменения.
Слияние коммитов
Давайте посмотрим, как, используя вышеизложенное, сделать кое-что интересное – слияние коммитов.
Допустим, у вас есть последовательность коммитов с сообщениями вида “упс.”, “В работе” и “позабыл этот файл”. Вы можете использовать reset для того, чтобы просто и быстро слить их в один. (В Объединение коммитов представлен другой способ сделать то же самое, но в данном примере проще воспользоваться reset.)
Предположим, у вас есть проект, в котором первый коммит содержит один файл, второй коммит добавляет новый файл и изменяет первый, а третий коммит снова изменяет первый файл. Второй коммит был сделан в процессе работы и вы хотите слить его со следующим.
Вы можете выполнить git reset --soft HEAD~2, чтобы вернуть ветку HEAD на какой-то из предыдущих коммитов (на первый коммит, который вы хотите оставить):
Затем просто снова выполните git commit:
Теперь вы можете видеть, что ваша “достижимая” история (история, которую вы впоследствии отправите на сервер), сейчас выглядит так – у вас есть первый коммит с файлом file-a.txt версии v1, и второй, который изменяет файл file-a.txt до версии v3и добавляет file-b.txt. Коммита, который содержал файл версии v2не осталось в истории.
Сравнение с checkout
Наконец, вы можете задаться вопросом, в чем же состоит отличие между checkout и reset. Как и reset, команда checkout управляет тремя деревьями Git, и также ее поведение зависит от того указали ли вы путь до файла или нет.
Без указания пути
Команда git checkout [branch] очень похожа на git reset --hard [branch], в процессе их выполнения все три дерева изменяются так, чтобы выглядеть как [branch]. Но между этими командами есть два важных отличия.
Во-первых, в отличие от reset --hard, команда checkout бережно относится к рабочему каталогу, и проверяет, что она не трогает файлы, в которых есть изменения. В действительности, эта команда поступает немного умнее – она пытается выполнить в Рабочем Каталоге простые слияния так, чтобы все файлы, которые вы не изменяли, были обновлены. С другой стороны, команда reset --hard просто заменяет всё целиком, не выполняя проверок.
Читать дальшеИнтервал:
Закладка: