Git мануал на русском

2nd Edition (2014)

Download Ebook


The entire Pro Git book, written by Scott Chacon and Ben Straub and published by Apress, is available here. All content is licensed under the Creative Commons Attribution Non Commercial Share Alike 3.0 license. Print versions of the book are available on Amazon.com.

The version found here has been updated with corrections and additions from hundreds of contributors. If you see an error or have a suggestion, patches and issues are welcome in its GitHub repository.

  1. 1. Введение

    1. 1.1
      О системе контроля версий
    2. 1.2
      Краткая история Git
    3. 1.3
      Что такое Git?
    4. 1.4
      Командная строка
    5. 1.5
      Установка Git
    6. 1.6
      Первоначальная настройка Git
    7. 1.7
      Как получить помощь?
    8. 1.8
      Заключение
  2. 2. Основы Git

    1. 2.1
      Создание Git-репозитория
    2. 2.2
      Запись изменений в репозиторий
    3. 2.3
      Просмотр истории коммитов
    4. 2.4
      Операции отмены
    5. 2.5
      Работа с удалёнными репозиториями
    6. 2.6
      Работа с тегами
    7. 2.7
      Псевдонимы в Git
    8. 2.8
      Заключение
  3. 3. Ветвление в Git

    1. 3.1
      О ветвлении в двух словах
    2. 3.2
      Основы ветвления и слияния
    3. 3.3
      Управление ветками
    4. 3.4
      Работа с ветками
    5. 3.5
      Удалённые ветки
    6. 3.6
      Перебазирование
    7. 3.7
      Заключение
  4. 4. Git на сервере

    1. 4.1
      Протоколы
    2. 4.2
      Установка Git на сервер
    3. 4.3
      Генерация открытого SSH ключа
    4. 4.4
      Настраиваем сервер
    5. 4.5
      Git-демон
    6. 4.6
      Умный HTTP
    7. 4.7
      GitWeb
    8. 4.8
      GitLab
    9. 4.9
      Git-хостинг
    10. 4.10
      Заключение
  5. 5. Распределённый Git

    1. 5.1
      Распределённый рабочий процесс
    2. 5.2
      Участие в проекте
    3. 5.3
      Сопровождение проекта
    4. 5.4
      Заключение
  6. 6. GitHub

    1. 6.1
      Настройка и конфигурация учетной записи
    2. 6.2
      Внесение собственного вклада в проекты
    3. 6.3
      Сопровождение проекта
    4. 6.4
      Управление организацией
    5. 6.5
      Создание сценариев GitHub
    6. 6.6
      Заключение
  7. 7. Инструменты Git

    1. 7.1
      Выбор ревизии
    2. 7.2
      Интерактивное индексирование
    3. 7.3
      Припрятывание и очистка
    4. 7.4
      Подпись
    5. 7.5
      Поиск
    6. 7.6
      Перезапись истории
    7. 7.7
      Раскрытие тайн reset
    8. 7.8
      Продвинутое слияние
    9. 7.9
      Rerere
    10. 7.10
      Обнаружение ошибок с помощью Git
    11. 7.11
      Подмодули
    12. 7.12
      Создание пакетов
    13. 7.13
      Замена
    14. 7.14
      Хранилище учётных данных
    15. 7.15
      Заключение
  8. 8. Настройка Git

    1. 8.1
      Конфигурация Git
    2. 8.2
      Атрибуты Git
    3. 8.3
      Хуки в Git
    4. 8.4
      Пример принудительной политики Git
    5. 8.5
      Заключение
  9. 9. Git и другие системы контроля версий

    1. 9.1
      Git как клиент
    2. 9.2
      Переход на Git
    3. 9.3
      Заключение
  10. 10. Git изнутри

    1. 10.1
      Сантехника и Фарфор
    2. 10.2
      Объекты Git
    3. 10.3
      Ссылки в Git
    4. 10.4
      Pack-файлы
    5. 10.5
      Спецификации ссылок
    6. 10.6
      Протоколы передачи данных
    7. 10.7
      Обслуживание репозитория и восстановление данных
    8. 10.8
      Переменные окружения
    9. 10.9
      Заключение
  11. A1. Приложение A: Git в других окружениях

    1. A1.1
      Графические интерфейсы
    2. A1.2
      Git в Visual Studio
    3. A1.3
      Git в Visual Studio Code
    4. A1.4
      Git в Eclipse
    5. A1.5
      Git в IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
    6. A1.6
      Git в Sublime Text
    7. A1.7
      Git в Bash
    8. A1.8
      Git в Zsh
    9. A1.9
      Git в PowerShell
    10. A1.10
      Заключение
  12. A2. Приложение B: Встраивание Git в ваши приложения

    1. A2.1
      Git из командной строки
    2. A2.2
      Libgit2
    3. A2.3
      JGit
    4. A2.4
      go-git
    5. A2.5
      Dulwich
  13. A3. Приложение C: Команды Git

    1. A3.1
      Настройка и конфигурация
    2. A3.2
      Клонирование и создание репозиториев
    3. A3.3
      Основные команды
    4. A3.4
      Ветвление и слияния
    5. A3.5
      Совместная работа и обновление проектов
    6. A3.6
      Осмотр и сравнение
    7. A3.7
      Отладка
    8. A3.8
      Внесение исправлений
    9. A3.9
      Работа с помощью электронной почты
    10. A3.10
      Внешние системы
    11. A3.11
      Администрирование
    12. A3.12
      Низкоуровневые команды

scroll-to-top

1st Edition (2009)

The entire Pro Git book, written by Scott Chacon and Ben Straub and published by Apress, is available here. All content is licensed under the Creative Commons Attribution Non Commercial Share Alike 3.0 license. Print versions of the book are available on Amazon.com.

The version found here has been updated with corrections and additions from hundreds of contributors. If you see an error or have a suggestion, patches and issues are welcome in its GitHub repository.

  1. . Введение

    1. .1
      О контроле версий
    2. .2
      Краткая история Git
    3. .3
      Основы Git
    4. .4
      Установка Git
    5. .5
      Первоначальная настройка Git
    6. .6
      Как получить помощь?
    7. .7
      Итоги
  2. . Основы Git

    1. .1
      Создание Git-репозитория
    2. .2
      Запись изменений в репозиторий
    3. .3
      Просмотр истории коммитов
    4. .4
      Отмена изменений
    5. .5
      Работа с удалёнными репозиториями
    6. .6
      Работа с метками
    7. .7
      Полезные советы
    8. .8
      Итоги
  3. . Ветвление в Git

    1. .1
      Что такое ветка?
    2. .2
      Основы ветвления и слияния
    3. .3
      Управление ветками
    4. .4
      Приёмы работы с ветками
    5. .5
      Удалённые ветки
    6. .6
      Перемещение
    7. .7
      Итоги
  4. . Git на сервере

    1. .1
      Протоколы
    2. .2
      Настройка Git на сервере
    3. .3
      Создание открытого SSH-ключа
    4. .4
      Настраиваем сервер
    5. .5
      Открытый доступ
    6. .6
      GitWeb
    7. .7
      Gitosis
    8. .8
      Gitolite
    9. .9
      Git-демон
    10. .10
      Git-хостинг
    11. .11
      Итоги
  5. . Распределённый Git

    1. .1
      Распределённые рабочие процессы
    2. .2
      Содействие проекту
    3. .3
      Сопровождение проекта
    4. .4
      Итоги
  6. . Инструменты Git

    1. .1
      Выбор ревизии
    2. .2
      Интерактивное индексирование
    3. .3
      Прятанье
    4. .4
      Перезапись истории
    5. .5
      Отладка с помощью Git
    6. .6
      Подмодули
    7. .7
      Слияние поддеревьев
    8. .8
      Итоги
  7. . Настройка Git

    1. .1
      Конфигурирование Git
    2. .2
      Git-атрибуты
    3. .3
      Перехватчики в Git
    4. .4
      Пример навязывания политики с помощью Git
    5. .5
      Итоги
  8. . Git и другие системы контроля версий

    1. .1
      Git и Subversion
    2. .2
      Миграция на Git
    3. .3
      Итоги
  9. . Git изнутри

    1. .1
      Сантехника и фарфор
    2. .2
      Объекты в Git
    3. .3
      Ссылки в Git
    4. .4
      Pack-файлы
    5. .5
      Спецификации ссылок
    6. .6
      Протоколы передачи
    7. .7
      Обслуживание и восстановление данных
    8. .8
      Итоги

scroll-to-top

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

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

Основы

Git — это набор консольных утилит, которые отслеживают и фиксируют изменения в файлах (чаще всего речь идет об исходном коде программ, но вы можете использовать его для любых файлов на ваш вкус). Изначально Git был создан Линусом Торвальдсом при разработке ядра Linux. Однако инструмент так понравился разработчикам, что в последствии, он получил широкое распространение и его стали использовать в других проектах. С его помощью вы можете сравнивать, анализировать, редактировать, сливать изменения и возвращаться назад к последнему сохранению. Этот процесс называется контролем версий.

Для чего он нужен? Ну во-первых, чтобы отследить изменения, произошедшие с проектом, со временем. Проще говоря, мы можем посмотреть как менялись файлы программы, на всех этапах разработки и при необходимости вернуться назад и что-то отредактировать. Часто бывают ситуации, когда, во вполне себе работающий код, вам нужно внести определенные правки или улучшить какой-то функционал, по желанию заказчика. Однако после внедрения нововведений, вы с ужасом понимаете, что все сломалось. У вас начинается судорожно дергаться глаз, а в воздухе повисает немой вопрос: “Что делать?” Без системы контроля версий, вам надо было бы долго напряженно просматривать код, чтобы понять как было до того, как все перестало работать. С Гитом же, все что нужно сделать — это откатиться на коммит назад.

Во-вторых он чрезвычайно полезен при одновременной работе нескольких специалистов, над одним проектом. Без Гита случится коллапс, когда разработчики, скопировав весь код из главной папки и сделав с ним задуманное, попытаются одновременно вернуть весь код обратно.
Git является распределенным, то есть не зависит от одного центрального сервера, на котором хранятся файлы. Вместо этого он работает полностью локально, сохраняя данные в директориях на жестком диске, которые называются репозиторием. Тем не менее, вы можете хранить копию репозитория онлайн, это сильно облегчает работу над одним проектом для нескольких людей. Для этого используются сайты вроде github и bitbucket.

Установка

Установить git на свою машину очень просто:

  • Linux — нужно просто открыть терминал и установить приложение при помощи пакетного менеджера вашего дистрибутива. Для Ubuntu команда будет выглядеть следующим образом:
    sudo apt-get install git
  • Windows — мы рекомендуем git for windows, так как он содержит и клиент с графическим интерфейсом, и эмулятор bash.
  • OS X — проще всего воспользоваться homebrew. После его установки запустите в терминале:
    brew install git

Если вы новичок, клиент с графическим интерфейсом(например GitHub Desktop и Sourcetree) будет полезен, но, тем не менее, знать команды очень важно.

Настройка

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

git config --global user.name "My Name"
git config --global user.email myEmail@example.com

Теперь каждое наше действие будет отмечено именем и почтой. Таким образом, пользователи всегда будут в курсе, кто отвечает за какие изменения — это вносит порядок.
Git хранит весь пакет конфигураций в файле .gitconfig, находящемся в вашем локальном каталоге. Чтобы сделать эти настройки глобальными, то есть применимыми ко всем проектам, необходимо добавить флаг –global. Если вы этого не сделаете, они будут распространяться только на текущий репозиторий.
Для того, чтобы посмотреть все настройки системы, используйте команду:

git config --list

Для удобства и легкости зрительного восприятия, некоторые группы команд в Гит можно выделить цветом, для этого нужно прописать в консоли:

git config --global color.ui true
git config --global color.status auto
git config --global color.branch auto

Если вы не до конца настроили систему для работы, в начале своего пути — не беда. Git всегда подскажет разработчику, если тот запутался, например:

  1. Команда git —help — выводит общую документацию по git
  2. Если введем git log —help — он предоставит нам документацию по какой-то определенной команде (в данном случае это — log)
  3. Если вы вдруг сделали опечатку — система подскажет вам нужную команду
  4. После выполнения любой команды — отчитается о том, что вы натворили
  5. Также Гит прогнозирует дальнейшие варианты развития событий и всегда направит разработчика, не знающего, куда двигаться дальше

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

Создание нового репозитория

Как мы отметили ранее, git хранит свои файлы и историю прямо в папке проекта. Чтобы создать новый репозиторий, нам нужно открыть терминал, зайти в папку нашего проекта и выполнить команду init. Это включит приложение в этой конкретной папке и создаст скрытую директорию .git, где будет храниться история репозитория и настройки.
Создайте на рабочем столе папку под названием git_exercise. Для этого в окне терминала введите:

$ mkdir Desktop/git_exercise/
$ cd Desktop/git_exercise/
$ git init

Командная строка должна вернуть что-то вроде:

Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/

Это значит, что наш репозиторий был успешно создан, но пока что пуст. Теперь создайте текстовый файл под названием hello.txt и сохраните его в директории git_exercise.

Определение состояния

status — это еще одна важнейшая команда, которая показывает информацию о текущем состоянии репозитория: актуальна ли информация на нём, нет ли чего-то нового, что поменялось, и так далее. Запуск git status на нашем свежесозданном репозитории должен выдать:

$ git status
On branch master
Initial commit
Untracked files:
(use "git add ..." to include in what will be committed)
hello.txt

Сообщение говорит о том, что файл hello.txt неотслеживаемый. Это значит, что файл новый и система еще не знает, нужно ли следить за изменениями в файле или его можно просто игнорировать. Для того, чтобы начать отслеживать новый файл, нужно его специальным образом объявить.

Подготовка файлов

В git есть концепция области подготовленных файлов. Можно представить ее как холст, на который наносят изменения, которые нужны в коммите. Сперва он пустой, но затем мы добавляем на него файлы (или части файлов, или даже одиночные строчки) командой add и, наконец, коммитим все нужное в репозиторий (создаем слепок нужного нам состояния) командой commit.
В нашем случае у нас только один файл, так что добавим его:

$ git add hello.txt

Если нам нужно добавить все, что находится в директории, мы можем использовать

$ git add -A

Проверим статус снова, на этот раз мы должны получить другой ответ:

$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached ..." to unstage)
new file: hello.txt

Файл готов к коммиту. Сообщение о состоянии также говорит нам о том, какие изменения относительно файла были проведены в области подготовки — в данном случае это новый файл, но файлы могут быть модифицированы или удалены.

Фиксация изменений

Как сделать коммит

Представим, что нам нужно добавить пару новых блоков в html-разметку (index.html) и стилизовать их в файле style.css. Для сохранения изменений, их необходимо закоммитить. Но сначала, мы должны обозначить эти файлы для Гита, при помощи команды git add, добавляющей (или подготавливающей) их к коммиту. Добавлять их можно по отдельности:

git add index.html
git add css/style.css

или вместе — всё сразу:

git add .

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

git reset:
git reset css/style.css

Теперь создадим непосредственно сам коммит

git commit -m 'Add some code'

Флажок -m задаст commit message — комментарий разработчика. Он необходим для описания закоммиченных изменений. И здесь работает золотое правило всех комментариев в коде: «Максимально ясно, просто и содержательно обозначь написанное!»

Как посмотреть коммиты

Для просмотра все выполненных фиксаций можно воспользоваться историей коммитов. Она содержит сведения о каждом проведенном коммите проекта. Запросить ее можно при помощи команды:

git log

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

git show hash_commit

Ну а если вдруг нам нужно переделать commit message и внести туда новый комментарий, можно написать следующую конструкцию:

git commit --amend -m 'Новый комментарий'

В данном случае сообщение последнего коммита перезапишется. Но злоупотреблять этим не стоит, поскольку эта операция опасная и лучше ее делать до отправки коммита на сервер.

Удаленные репозитории

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

1. Что такое удаленный репозиторий

Репозиторий, хранящийся в облаке, на стороннем сервисе, специально созданном для работы с git имеет ряд преимуществ. Во-первых — это своего рода резервная копия вашего проекта, предоставляющая возможность безболезненной работы в команде. А еще в таком репозитории можно пользоваться дополнительными возможностями хостинга. К примеру -визуализацией истории или возможностью разрабатывать вашу программу непосредственно в веб-интерфейсе.
Клонирование
Клонирование — это когда вы копируете удаленный репозиторий к себе на локальный ПК. Это то, с чего обычно начинается любой проект. При этом вы переносите себе все файлы и папки проекта, а также всю его историю с момента его создания. Чтобы склонировать проект, сперва, необходимо узнать где он расположен и скопировать ссылку на него. В нашем руководстве мы будем использовать адрес https://github.com/tutorialzine/awesome-project, но вам посоветуем, попробовать создать свой репозиторий в GitHub, BitBucket или любом другом сервисе:

git clone https://github.com/tutorialzine/awesome-project

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

git clone https://github.com/tutorialzine/awesome-project new-folder

2. Подключение к удаленному репозиторию

Чтобы загрузить что-нибудь в удаленный репозиторий, сначала нужно к нему подключиться. Регистрация и установка может занять время, но все подобные сервисы предоставляют хорошую документацию.
Чтобы связать наш локальный репозиторий с репозиторием на GitHub, выполним следующую команду в терминале. Обратите внимание, что нужно обязательно изменить URI репозитория на свой.

# This is only an example. Replace the URI with your own repository address.
$ git remote add origin https://github.com/tutorialzine/awesome-project.git

Проект может иметь несколько удаленных репозиториев одновременно. Чтобы их различать, мы дадим им разные имена. Обычно главный репозиторий называется origin.

3. Отправка изменений на сервер

Сейчас самое время переслать наш локальный коммит на сервер. Этот процесс происходит каждый раз, когда мы хотим обновить данные в удаленном репозитории.
Команда, предназначенная для этого — push. Она принимает два параметра: имя удаленного репозитория (мы назвали наш origin) и ветку, в которую необходимо внести изменения (master — это ветка по умолчанию для всех репозиториев).

$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 212 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/tutorialzine/awesome-project.git
* [new branch] master -> master

Эта команда немного похожа на git fetch, с той лишь разницей, что при помощи fetch мы импортируем коммиты в локальную ветку, а применив push, мы экспортируем их из локальной в удаленную. Если вам необходимо настроить удаленную ветку используйте git remote. Однако пушить надо осторожно, ведь рассматриваемая команда перезаписывает безвозвратно все изменения. В большинстве случаев, ее используют, чтобы опубликовать выгружаемые локальные изменения в центральный репозиторий. А еще ее применяют для того, чтобы поделиться, внесенными в локальный репозиторий, нововведениями, с коллегами или другими удаленными участниками разработки проекта. Подытожив сказанное, можно назвать git push — командой выгрузки, а git pull и git fetch — командами загрузки или скачивания. После того как вы успешно запушили измененные данные, их необходимо внедрить или интегрировать, при помощи команды слияния git merge.
В зависимости от сервиса, который вы используете, вам может потребоваться аутентифицироваться, чтобы изменения отправились. Если все сделано правильно, то когда вы посмотрите в удаленный репозиторий при помощи браузера, вы увидите файл hello.txt

4. Запрос изменений с сервера

Если вы сделали изменения в вашем удаленном репозитории, другие пользователи могут скачать изменения при помощи команды pull.

$ git pull origin master
From https://github.com/tutorialzine/awesome-project
* branch master -> FETCH_HEAD
Already up-to-date.

Так как новых коммитов с тех пор, как мы склонировали себе проект, не было, никаких изменений доступных для скачивания нет.

Как удалить локальный репозиторий

Вам не понравился один из ваших локальных Git-репозиториев и вы хотите стереть его со своей машины. Для этого вам всего лишь надо удалить скрытую папку «.git» в корневом каталоге репозитория. Сделать это можно 3 способами:

  1. Проще всего вручную удалить эту папку «.git» в корневом каталоге «Git Local Warehouse».
  2. Также удалить, не устраивающий вас, репозиторий можно на github. Открываете нужный вам объект и переходите в пункт меню Настройки. Там, прокрутив ползунок вниз, вы попадете в зону опасности, где один из пунктов будет называться «удаление этого хранилища».
  3. Последний метод удаления локального хранилища через командную строку, для этого в терминале необходимо ввести следующую команду:
cd repository-path/
rm -r .git

Ветвление

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

  • Уже рабочая, стабильная версия кода сохраняется.
  • Различные новые функции могут разрабатываться параллельно разными программистами.
  • Разработчики могут работать с собственными ветками без риска, что кодовая база поменяется из-за чужих изменений.
  • В случае сомнений, различные реализации одной и той же идеи могут быть разработаны в разных ветках и затем сравниваться.

1. Создание новой ветки

Основная ветка в каждом репозитории называется master. Чтобы создать еще одну ветку, используем команду branch <name>

$ git branch amazing_new_feature

Это создаст новую ветку, пока что точную копию ветки master.

2. Переключение между ветками

Сейчас, если мы запустим branch, мы увидим две доступные опции:

$ git branch
amazing_new_feature
* master

master — это активная ветка, она помечена звездочкой. Но мы хотим работать с нашей “новой потрясающей фичей”, так что нам понадобится переключиться на другую ветку. Для этого воспользуемся командой checkout, она принимает один параметр — имя ветки, на которую необходимо переключиться.

$ git checkout amazing_new_feature

В Git ветка — это отдельная линия разработки. Git checkout позволяет нам переключаться как между удаленными, так и меду локальными ветками. Это один из способов получить доступ к работе коллеги или соавтора, обеспечивающий более высокую продуктивность совместной работы. Однако тут надо помнить, что пока вы не закомитили изменения, вы не сможете переключиться на другую ветку. В такой ситуации нужно либо сделать коммит, либо отложить его, при помощи команды git stash, добавляющей текущие незакоммиченные изменения в стек изменений и сбрасывающей рабочую копию до HEAD’а репозитория.

3. Слияние веток

Наша “потрясающая новая фича” будет еще одним текстовым файлом под названием feature.txt. Мы создадим его, добавим и закоммитим:

$ git add feature.txt
$ git commit -m "New feature complete.”

Изменения завершены, теперь мы можем переключиться обратно на ветку master.

$ git checkout master

Теперь, если мы откроем наш проект в файловом менеджере, мы не увидим файла feature.txt, потому что мы переключились обратно на ветку master, в которой такого файла не существует. Чтобы он появился, нужно воспользоваться merge для объединения веток (применения изменений из ветки amazing_new_feature к основной версии проекта).

$ git merge amazing_new_feature

Теперь ветка master актуальна. Ветка amazing_new_feature больше не нужна, и ее можно удалить.

$ git branch -d awesome_new_feature

Если хотите создать копию удаленного репозитория — используйте git clone. Однако если вам нужна только определенная его ветка, а не все хранилище — после git clone выполните следующую команду в соответствующем репозитории:

git checkout -b <имя ветки> origin/<имя ветки>

После этого, новая ветка создается на машине автоматически.

Бывают ситуации, когда после слива каких-то изменений из рабочей ветки в исходную версию проекта, ее, по правилам хорошего тона, необходимо удалить, чтобы она более не мешалась в вашем коде. Но как это сделать?
Для локально расположенных веток существует команда:

git branch -d local_branch_name

где флажок -d являющийся опцией команды git branch — это сокращенная версия ключевого слова —delete, предназначенного для удаления ветки, а local_branch_name – название ненужной нам ветки.
Однако тут есть нюанс: удалить текущую ветку, в которую вы, в данный момент просматриваете — нельзя. Если же вы все-таки попытаетесь это сделать, система отругает вас и выдаст ошибку с таким содержанием:

Error: Cannot delete branch local_branch_name checked out at название_директории

Так что при удалении ветвей, обязательно переключитесь на другой branch.

Дополнительно

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

1. Отслеживание изменений, сделанных в коммитах

У каждого коммита есть свой уникальный идентификатор в виде строки цифр и букв. Чтобы просмотреть список всех коммитов и их идентификаторов, можно использовать команду log:

Вывод git log

$ git log
commit ba25c0ff30e1b2f0259157b42b9f8f5d174d80d7
Author: Tutorialzine
Date: Mon May 30 17:15:28 2016 +0300
New feature complete
commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date: Mon May 30 16:30:04 2016 +0300
Added content to hello.txt
commit 09bd8cc171d7084e78e4d118a2346b7487dca059
Author: Tutorialzine
Date: Sat May 28 17:52:14 2016 +0300
Initial commit


Как вы можете заметить, идентификаторы довольно длинные, но для работы с ними не обязательно копировать их целиком — первых нескольких символов будет вполне достаточно. Чтобы посмотреть, что нового появилось в коммите, мы можем воспользоваться командой show [commit]
Вывод git show

$ git show b10cc123
commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date: Mon May 30 16:30:04 2016 +0300
Added content to hello.txt
diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+Nice weather today, isn't it?


Чтобы увидеть разницу между двумя коммитами, используется команда diff (с указанием промежутка между коммитами):
Вывод git diff

$ git diff 09bd8cc..ba25c0ff
diff --git a/feature.txt b/feature.txt
new file mode 100644
index 0000000..e69de29
diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -0,0 +1 @@
+Nice weather today, isn't it?


Мы сравнили первый коммит с последним, чтобы увидеть все изменения, которые были когда-либо сделаны. Обычно проще использовать git difftool, так как эта команда запускает графический клиент, в котором наглядно сопоставляет все изменения.

2. Возвращение файла к предыдущему состоянию

Гит позволяет вернуть выбранный файл к состоянию на момент определенного коммита. Это делается уже знакомой нам командой checkout, которую мы ранее использовали для переключения между ветками. Но она также может быть использована для переключения между коммитами (это довольно распространенная ситуация для Гита — использование одной команды для различных, на первый взгляд, слабо связанных задач).
В следующем примере мы возьмем файл hello.txt и откатим все изменения, совершенные над ним к первому коммиту. Чтобы сделать это, мы подставим в команду идентификатор нужного коммита, а также путь до файла:

$ git checkout 09bd8cc1 hello.txt

3. Исправление коммита

Если вы опечатались в комментарии или забыли добавить файл и заметили это сразу после того, как закоммитили изменения, вы легко можете это поправить при помощи commit —amend. Эта команда добавит все из последнего коммита в область подготовленных файлов и попытается сделать новый коммит. Это дает вам возможность поправить комментарий или добавить недостающие файлы в область подготовленных файлов.
Для более сложных исправлений, например, не в последнем коммите или если вы успели отправить изменения на сервер, нужно использовать revert. Эта команда создаст коммит, отменяющий изменения, совершенные в коммите с заданным идентификатором.
Самый последний коммит может быть доступен по алиасу HEAD:

$ git revert HEAD

Для остальных будем использовать идентификаторы:

$ git revert b10cc123

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

4. Разрешение конфликтов при слиянии

Помимо сценария, описанного в предыдущем пункте, конфликты регулярно возникают при слиянии ветвей или при отправке чужого кода. Иногда конфликты исправляются автоматически, но обычно с этим приходится разбираться вручную — решать, какой код остается, а какой нужно удалить.
Давайте посмотрим на примеры, где мы попытаемся слить две ветки под названием john_branch и tim_branch. И Тим, и Джон правят один и тот же файл: функцию, которая отображает элементы массива.
Джон использует цикл:

// Use a for loop to console.log contents.
for(var i=0; i<arr.length; i++) {
console.log(arr[i]);
}

Тим предпочитает forEach:

// Use forEach to console.log contents.
arr.forEach(function(item) {
console.log(item);
});

Они оба коммитят свой код в соответствующую ветку. Теперь, если они попытаются слить две ветки, они получат сообщение об ошибке:

$ git merge tim_branch
Auto-merging print_array.js
CONFLICT (content): Merge conflict in print_array.js
Automatic merge failed; fix conflicts and then commit the result.

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

Вывод

<<<<<<< HEAD // Use a for loop to console.log contents. for(var i=0; i<arr.length; i++) { console.log(arr[i]); } ======= // Use forEach to console.log contents. arr.forEach(function(item) { console.log(item); }); >>>>>>> Tim's commit.


Над разделителем ======= мы видим последний (HEAD) коммит, а под ним — конфликтующий. Таким образом, мы можем увидеть, чем они отличаются и решать, какая версия лучше. Или вовсе написать новую. В этой ситуации мы так и поступим, перепишем все, удалив разделители, и дадим git понять, что закончили.

// Not using for loop or forEach.
// Use Array.toString() to console.log contents.
console.log(arr.toString());

Когда все готово, нужно закоммитить изменения, чтобы закончить процесс:

$ git add -A
$ git commit -m "Array printing conflict resolved."

Как вы можете заметить, процесс довольно утомительный и может быть очень сложным в больших проектах. Многие разработчики предпочитают использовать для разрешения конфликтов клиенты с графическим интерфейсом. (Для запуска нужно набрать git mergetool).

5. Настройка .gitignore

В большинстве проектов есть файлы или целые директории, в которые мы не хотим (и, скорее всего, не захотим) коммитить. Мы можем удостовериться, что они случайно не попадут в git add -A при помощи файла .gitignore

  1. Создайте вручную файл под названием .gitignore и сохраните его в директорию проекта.
  2. Внутри файла перечислите названия файлов/папок, которые нужно игнорировать, каждый с новой строки.
  3. Файл .gitignore должен быть добавлен, закоммичен и отправлен на сервер, как любой другой файл в проекте.

Вот хорошие примеры файлов, которые нужно игнорировать:

  • Логи
  • Артефакты систем сборки
  • Папки node_modules в проектах node.js
  • Папки, созданные IDE, например, Netbeans или IntelliJ
  • Разнообразные заметки разработчика.

Файл .gitignore, исключающий все перечисленное выше, будет выглядеть так:

*.log
build/
node_modules/
.idea/
my_notes.txt

Символ слэша в конце некоторых линий означает директорию (и тот факт, что мы рекурсивно игнорируем все ее содержимое). Звездочка, как обычно, означает шаблон.

Git bash и git.io

Руководствуясь часто встречающимися, при изучении системы, вопросами новичков, разберем еще несколько непонятных словосочетаний.

  • Git Bash(Bourne Again Shell) — это приложение, являющееся эмулятором командной строки и предоставляющее, операционной системе, некоторые распространенные утилиты bash и собственно саму систему Git. Это терминал, используемый для взаимодействия с персональным компьютером, посредством письменных команд.
  • URL-адреса хранилищ на Гитхабе могут быть довольно длинными, из-за больших имен репозиториев и файлов. Работать с такими ссылками очень не удобно. Поэтому сайт github.io создал git.io — неплохой сервис по преобразованию этих длинных и беспорядочных URL-адресов в более короткие и понятные. Сайт был создан в 2011 году и вплоть до недавнего времени отлично справлялся со своими обязанностями. Однако в начале этого года компания Гитхаб, из-за участившихся попыток хакеров использовать сайт в злонамеренных целях, остановила работу сервиса, а чем известила пользователей в своем блоге. Разработчики популярного ресурса рекомендуют пользоваться другими URL-cutter’ами, пока работа сервиса не будет налажена.

Заключение.

Вот и все! Наше руководство окончено. Мы очень старались собрать всю самую важную информацию и изложить ее как можно более сжато и кратко.
Git довольно сложен, и в нем есть еще много функций и трюков. Если вы хотите с ними познакомиться, вот некоторые ресурсы, которые мы рекомендуем:

  • Официальная документация, включающая книгу и видеоуроки – тут.
  • “Getting git right” – Коллекция руководств и статей от Atlassian – тут.
  • Список клиентов с графическим интерфейсом – тут.
  • Онлайн утилита для генерации .gitignore файлов – тут.

Оригинал статьи доступен на сайте http://tutorialzine.com

Другие статьи по теме

10 полезных Git команд, которые облегчат работу

Шпаргалка по Git, в которой представлены основные команды

Узнайте о системе управления версиями, Git и о том, как она работает с GitHub.

About version control and Git

A version control system, or VCS, tracks the history of changes as people and teams collaborate on projects together. As developers make changes to the project, any earlier version of the project can be recovered at any time.

Developers can review project history to find out:

  • Which changes were made?
  • Who made the changes?
  • When were the changes made?
  • Why were changes needed?

VCSs give each contributor a unified and consistent view of a project, surfacing work that’s already in progress. Seeing a transparent history of changes, who made them, and how they contribute to the development of a project helps team members stay aligned while working independently.

In a distributed version control system, every developer has a full copy of the project and project history. Unlike once popular centralized version control systems, DVCSs don’t need a constant connection to a central repository. Git is the most popular distributed version control system. Git is commonly used for both open source and commercial software development, with significant benefits for individuals, teams and businesses.

  • Git lets developers see the entire timeline of their changes, decisions, and progression of any project in one place. From the moment they access the history of a project, the developer has all the context they need to understand it and start contributing.

  • Developers work in every time zone. With a DVCS like Git, collaboration can happen any time while maintaining source code integrity. Using branches, developers can safely propose changes to production code.

  • Businesses using Git can break down communication barriers between teams and keep them focused on doing their best work. Plus, Git makes it possible to align experts across a business to collaborate on major projects.

About repositories

A repository, or Git project, encompasses the entire collection of files and folders associated with a project, along with each file’s revision history. The file history appears as snapshots in time called commits. The commits can be organized into multiple lines of development called branches. Because Git is a DVCS, repositories are self-contained units and anyone who has a copy of the repository can access the entire codebase and its history. Using the command line or other ease-of-use interfaces, a Git repository also allows for: interaction with the history, cloning the repository, creating branches, committing, merging, comparing changes across versions of code, and more.

Through platforms like GitHub, Git also provides more opportunities for project transparency and collaboration. Public repositories help teams work together to build the best possible final product.

How GitHub works

GitHub hosts Git repositories and provides developers with tools to ship better code through command line features, issues (threaded discussions), pull requests, code review, or the use of a collection of free and for-purchase apps in the GitHub Marketplace. With collaboration layers like the GitHub flow, a community of 100 million developers, and an ecosystem with hundreds of integrations, GitHub changes the way software is built.

GitHub builds collaboration directly into the development process. Work is organized into repositories where developers can outline requirements or direction and set expectations for team members. Then, using the GitHub flow, developers simply create a branch to work on updates, commit changes to save them, open a pull request to propose and discuss changes, and merge pull requests once everyone is on the same page. For more information, see «GitHub flow.»

For GitHub plans and costs, see GitHub Pricing. For information on how GitHub Enterprise compares to other options, see Comparing GitHub to other DevOps solutions.

GitHub and the command line

Basic Git commands

To use Git, developers use specific commands to copy, create, change, and combine code. These commands can be executed directly from the command line or by using an application like GitHub Desktop. Here are some common commands for using Git:

  • git init initializes a brand new Git repository and begins tracking an existing directory. It adds a hidden subfolder within the existing directory that houses the internal data structure required for version control.

  • git clone creates a local copy of a project that already exists remotely. The clone includes all the project’s files, history, and branches.

  • git add stages a change. Git tracks changes to a developer’s codebase, but it’s necessary to stage and take a snapshot of the changes to include them in the project’s history. This command performs staging, the first part of that two-step process. Any changes that are staged will become a part of the next snapshot and a part of the project’s history. Staging and committing separately gives developers complete control over the history of their project without changing how they code and work.

  • git commit saves the snapshot to the project history and completes the change-tracking process. In short, a commit functions like taking a photo. Anything that’s been staged with git add will become a part of the snapshot with git commit.

  • git status shows the status of changes as untracked, modified, or staged.

  • git branch shows the branches being worked on locally.

  • git merge merges lines of development together. This command is typically used to combine changes made on two distinct branches. For example, a developer would merge when they want to combine changes from a feature branch into the main branch for deployment.

  • git pull updates the local line of development with updates from its remote counterpart. Developers use this command if a teammate has made commits to a branch on a remote, and they would like to reflect those changes in their local environment.

  • git push updates the remote repository with any commits made locally to a branch.

For more information, see the full reference guide to Git commands.

Example: Contribute to an existing repository

# download a repository on GitHub to our machine
# Replace `owner/repo` with the owner and name of the repository to clone
git clone https://github.com/owner/repo.git

# change into the `repo` directory
cd repo

# create a new branch to store any new changes
git branch my-branch

# switch to that branch (line of development)
git checkout my-branch

# make changes, for example, edit `file1.md` and `file2.md` using the text editor

# stage the changed files
git add file1.md file2.md

# take a snapshot of the staging area (anything that's been added)
git commit -m "my snapshot"

# push changes to github
git push --set-upstream origin my-branch

Example: Start a new repository and publish it to GitHub

First, you will need to create a new repository on GitHub. For more information, see «Hello World.» Do not initialize the repository with a README, .gitignore or License file. This empty repository will await your code.

# create a new directory, and initialize it with git-specific functions
git init my-repo

# change into the `my-repo` directory
cd my-repo

# create the first file in the project
touch README.md

# git isn't aware of the file, stage it
git add README.md

# take a snapshot of the staging area
git commit -m "add README to initial commit"

# provide the path for the repository you created on github
git remote add origin https://github.com/YOUR-USERNAME/YOUR-REPOSITORY-NAME.git

# push changes to github
git push --set-upstream origin main

Example: contribute to an existing branch on GitHub

This example assumes that you already have a project called repo on the machine and that a new branch has been pushed to GitHub since the last time changes were made locally.

# change into the `repo` directory
cd repo

# update all remote tracking branches, and the currently checked out branch
git pull

# change into the existing branch called `feature-a`
git checkout feature-a

# make changes, for example, edit `file1.md` using the text editor

# stage the changed file
git add file1.md

# take a snapshot of the staging area
git commit -m "edit file1"

# push changes to github
git push

Models for collaborative development

There are two primary ways people collaborate on GitHub:

  1. Shared repository
  2. Fork and pull

With a shared repository, individuals and teams are explicitly designated as contributors with read, write, or administrator access. This simple permission structure, combined with features like protected branches, helps teams progress quickly when they adopt GitHub.

For an open source project, or for projects to which anyone can contribute, managing individual permissions can be challenging, but a fork and pull model allows anyone who can view the project to contribute. A fork is a copy of a project under a developer’s personal account. Every developer has full control of their fork and is free to implement a fix or a new feature. Work completed in forks is either kept separate, or is surfaced back to the original project via a pull request. There, maintainers can review the suggested changes before they’re merged. For more information, see «Contributing to projects.»

Время на прочтение
17 мин

Количество просмотров 137K

Оглавление

Предисловие
1. Настройка git
….1.1 Конфигурационные файлы
….1.2 Настройки по умолчанию
….1.3 Псевдонимы (aliases)
2. Основы git
….2.1 Создание репозитория
….2.2 Состояние файлов
….2.3 Работа с индексом
….2.4 Работа с коммитами
….2.5 Просмотр истории
….2.6 Работа с удалённым репозиторием
3. Ветвление в git
….3.1 Базовые операций
….3.2 Слияние веток
….3.3 Rerere
4. Указатели в git
….4.1 Перемещение указателей
5. Рекомендуемая литература

Предисловие

Git — самая популярная распределённая система контроля версиями.[1][2]

Основное предназначение Git – это сохранение снимков последовательно улучшающихся состояний вашего проекта (Pro git, 2019).

Эта статья для тех, кто имеет по крайней мере базовые знания и навык работы с git и желает расширить свои знания.

Здесь рассматриваются только технические аспекты git’а, для более подробного погружения в философию git’а и его внутреннюю реализацию, советую прочитать несколько полезных книг (см. Рекомендуемая литература).

1. Настройка git

Прежде чем начинать работу с git необходимо его настроить под себя!

1.1 Конфигурационные файлы

  • /etc/gitconfig — Общие настройки для всех пользователей и репозиториев
  • ~/.gitconfig или ~/.config/git/config — Настройки конкретного пользователя
  • .git/config — Настройки для конкретного репозитория

Есть специальная команда

git config [<опции>]

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

В зависимости какой параметр вы передадите команде git config (—system, —global, —local), настройки будут записываются в один из этих файлов. Каждый из этих “уровней” (системный, глобальный, локальный) переопределяет значения предыдущего уровня!

Что бы посмотреть в каком файле, какие настройки установлены используйте git config —list —show-origin.

Игнорирование файлов
В git вы сами решаете какие файлы и в какой коммит попадут, но возможно вы бы хотели, что бы определённые файлы никогда не попали в индекс и в коммит, да и вообще не отображались в списке не отлеживаемых. Для этого вы можете создать специальный файл (.gitignore) в вашем репозитории и записать туда шаблон игнорируемых файлов. Если вы не хотите создавать такой файл в каждом репозитории вы можете определить его глобально с помощью core.excludesfile (см. Полезные настройки). Вы также можете скачать готовый .gitignore file для языка программирования на котором вы работаете.
Для настройки .gitignore используйте регулярные выражения bash.

1.2 Настройки по умолчанию

Есть куча настроек git’а как для сервера так и для клиента, здесь будут рассмотрены только основные настройки клиента.

Используйте

git config name value

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

git config --global core.editor nano

установит редактор по умолчанию nano.

Вы можете посмотреть значение существующего параметра с помощью git config —get [name] где name это параметр, значение которого вы хотите получить.

Полезные настройки:

  • user.name — Имя, которое будет использоваться при создании коммита
  • user.email — Email, который будет использоваться при создании коммита
  • core.excludesfile — Файл, шаблон которого будет использоваться для игнорирования определённых файлов глобально
  • core.editor — Редактор по умолчанию
  • commit.template — Файл, содержимое которого будет использоваться для сообщения коммита по умолчанию (См. Работа с коммитами).
  • help.autocorrect — При установке значения 1, git будет выполнять неправильно написанные команды.
  • credential.helper [mode] — Устанавливает режим хранения учётных данных. [cache] — учётные данные сохраняются на определённый период, пароли не сохраняются (—timeout [seconds] количество секунд после которого данные удаляются, по умолчанию 15 мин). [store] — учётные данные сохраняются на неограниченное время в открытом виде (—file [file] указывает путь для хранения данных, по умолчанию ~/.git-credentials).

1.3 Псевдонимы (aliases)

Если вы не хотите печатать каждую команду для Git целиком, вы легко можете настроить псевдонимы. Для создания псевдонима используйте:

git config alias.SHORT_NAME COMMAND

где SHORT_NAME это имя для сокращения, а COMMAND команда(ы) которую нужно сократить. Пример:

git config --global alias.last 'log -1 HEAD'

после выполнения этой команды вы можете просматривать информацию о последнем коммите на текущей ветке выполнив git last.

Я советую вам использовать следующие сокращения (вы также можете определить любые свои):

  • st = status
  • ch = checkout
  • br = branch
  • mg = merge
  • cm = commit
  • reb = rebase
  • lg = «git log —pretty=format:’%h — %ar: %s’»

Для просмотра настроек конфигурации используйте: git config —list.

2. Основы git

Здесь перечислены только обязательные и полезные (на мой взгляд) параметры, ибо перечисление всех неуместно. Для этого используйте git command -help или —help, где command — название команды справку о который вы хотите получить.

2.1 Создание репозитория

  • git init [<опции>] — Создаёт git репозитории и директорию .git в текущей директории (или в директории указанной после —separate-git-dir <каталог-git>, в этом случае директория .git будет находится в другом месте);
  • git clone [<опции>] [—] <репозиторий> [<каталог>] [-o, —origin <имя>] [-b, —branch <ветка>] [—single-branch] [—no-tags] [—separate-git-dir <каталог-git>] [-c, —config <ключ=значение>] — Клонирует репозитории с названием origin (или с тем которое вы укажите -o <имя>), находясь на той ветке, на которую указывает HEAD (или на той которую вы укажите -b <ветка>). Также вы можете клонировать только необходимую ветку HEAD (или ту которую укажите в -b <ветка>) указав —single-branch. По умолчанию клонируются все метки, но указав —no-tags вы можете не клонировать их. После выполнения команды создаётся директория .git в текущей директории (или в директории указанной после —separate-git-dir <каталог-git>, в этом случае директория .git будет находится в другом месте);

2.2 Состояние файлов

Для просмотра состояния файлов в вашем репозитории используйте:

git status [<опции>]

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

Жизненный цикл файловimage
Как видно на картинке файлы могут быть не отслеживаемые (Untracked) и отслеживаемые. Отслеживаемые файлы могут находится в 3 состояниях: Не изменено (Unmodified), изменено (Modified), подготовленное (Staged).
Если вы добавляете (с помощью git add) «Не отслеживаемый» файл, то он переходит в состояние «Подготовлено».
Если вы изменяете файл в состояния «Не изменено», то он переходит в состояние «Изменено». Если вы сохраняете изменённый файл (то есть находящийся в состоянии «Изменено») он переходит в состояние «Подготовлено». Если вы делаете коммит файла (то есть находящийся в состоянии «Подготовлено») он переходит в состояние «Не изменено».
Если версии файла в HEAD и рабочей директории отличаются, то файл будет находится в состояний «Изменено», иначе (если версия в HEAD и в рабочем каталоге одинакова») файл будет находится в состояний «Не изменено».
Если версия файла в HEAD отличается от рабочего каталога, но не отличается от версии в индексе, то файл будет в состоянии «Подготовлено».

Этот цикл можно представить следующим образом:
Unmodified -> Modified -> Staged -> Unmodified
То есть вы изменяете файл сохраняете его в индексе и делаете коммит и потом все сначала.

2.3 Работа с индексом

Надеюсь вы поняли, как выглядит жизненный цикл git репозитория. Теперь разберём как вы можете управлять индексом и файлами в вашем git репозитории.

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

Что бы просмотреть индекс, используйте git status.

Что бы добавить файлы в индекс используйте

git add [<опции>]

Полезные параметры команды git add:

  • -f, —force — добавить также игнорируемые файлы
  • -u, —update — обновить отслеживаемые файлы

Что бы удалить файлы из индекса вы можете использовать 2 команды git reset и git restore.
git-restore — восстановит файлы рабочего дерева.
git-reset — сбрасывает текущий HEAD до указанного состояния.
По сути вы можете добиться одного и того же с помощью обеих команд.

Что бы удалить из индекса некоторые файлы используйте:

git restore --staged <file>

таким образом вы восстановите ваш индекс (или точнее удалите конкретные файлы из индекса), будто бы git add после последнего коммита не выполнялся для них. С помощью этой команды вы можете восстановить и рабочую директорию, что бы она выглядела так, будто бы после коммита не выполнялось никаких изменений. Вот только эта команда имеет немного странное поведение — если вы добавили в индекс новую версию вашего файла вы не можете изменить вашу рабочую директорию, пока индекс отличается от HEAD. Поэтому вам сначала нужно восстановить ваш индекс и только потом рабочую директорию. К сожалению сделать это одной командой не возможно так как при передаче обеих аргументов (git restore -SW) не происходит ничего. И точно также при передаче -W тоже ничего не произойдет если файл в индексе и HEAD разный. Наверное, это сделали для защиты что бы вы случайно не изменили вашу рабочую директорию. Но в таком случае почему аргумент -W передаётся по умолчанию? В общем мне не понятно зачем было так сделано и для чего вообще была добавлена эта команда. По мне так reset справляется с этой задачей намного лучше, да и еще и имеет более богатый функционал так как может перемещать индекс и рабочую директорию не только на последний коммит но и на любой другой.

Но собственно разработчики рекомендуют для сброса индекса использовать именно git restore -S . Вместо git reset HEAD .

С помощью git status вы можете посмотреть какие файлы изменились но если вы также хотите узнать что именно изменилось в файлах то воспользуйтесь командой:

git diff [<options>]

таким образом выполнив команду без аргументов вы можете сравнить ваш индекс с рабочей директорией. Если вы уже добавил в индекс файлы, то используйте git diff —cached что бы посмотреть различия между последним коммитом (или тем который вы укажите) и рабочей директории. Вы также можете посмотреть различия между двумя коммитами или ветками передав их как аргумент. Пример: git diff 00656c 3d5119 покажет различия между коммитом 00656c и 3d5119.

2.4 Работа с коммитами

Теперь, когда ваш индекс находится в нужном состояний, пора сделать коммит ваших изменений. Запомните, что все файлы для которых вы не выполнили git add после момента редактирования — не войдут в этот коммит. На деле файлы в нём будут, но только их старая версия (если таковая имеется).

Для того что бы сделать коммит ваших изменений используйте:

git commit [<опции>]

Полезные опции команды git commit:

  • -F, —file [file] — Записать сообщение коммита из указанного файла
  • —author [author] — Подменить автора коммита
  • —date [date] — Подменить дату коммита
  • -m, —mesage [message] — Сообщение коммита
  • -a, —all — Закоммитеть все изменения в файлах
  • -i, —include [files…] — Добавить в индекс указанные файлы для следующего коммита
  • -o, —only [files…] — Закоммитеть только указанные файлы
  • —amend — Перезаписать предыдущий коммит

Вы можете определить сообщение для коммита по умолчанию с помощью commit.template. Эта директива в конфигурационном файле отвечает за файл содержимое которого будет использоваться для коммита по умолчанию. Пример: git config —global commit.template ~/.gitmessage.txt.

Вы также можете изменить, удалить, объединить любой коммит.
Как вы уже могли заметить вы можете быстро перезаписать последний коммит с помощью git commit —amend.
Для изменения коммитом в вашей истории используйте

git rebase -i <commit>

где commit это верхний коммит в вашей цепочке с которого вы бы хотели что либо изменить.

После выполнения git rebase -i в интерактивном меню выберите что вы хотите сделать.

  • pick <коммит> = использовать коммит
  • reword <коммит> = использовать коммит, но изменить сообщение коммита
  • edit <коммит> = использовать коммит, но остановиться для исправления
  • squash <коммит> = использовать коммит, но объединить с предыдущим коммитом
  • fixup <коммит> = как «squash», но пропустить сообщение коммита
  • exec <команда> = выполнить команду (остаток строки) с помощью командной оболочки
  • break = остановиться здесь (продолжить с помощью «git rebase —continue»)
  • drop <коммит> = удалить коммит
  • label <метка> = дать имя текущему HEAD
  • reset <метка> = сбросить HEAD к указанной метке

Для изменения сообщения определённого коммита.
Необходимо изменить pick на edit над коммитом который вы хотите изменить.
Пример: вы хотите изменить сообщение коммита 750f5ae.

pick 2748cb4 first commit
edit 750f5ae second commit
pick 716eb99 third commit

После сохранения скрипта вы вернётесь в командную строку и git скажет что необходимо делать дальше:

Остановлено на 750f5ae … second commit
You can amend the commit now, with

git commit —amend

Once you are satisfied with your changes, run

git rebase —continue

Как указанно выше необходимо выполнить git commit —amend для того что бы изменить сообщение коммита. После чего выполнить git rebase —continue. Если вы выбрали несколько коммитов для изменения названия то данные операций необходимо будет проделать над каждым коммитом.

Для удаления коммита
Необходимо удалить строку с коммитом.
Пример: вы хотите удалить коммит 750f5ae
Нужно изменить скрипт с такого:
pick 2748cb4 third commit
pick 750f5ae second commit
pick 716eb99 first commit
на такой:
pick 2748cb4 first commit
pick 716eb99 third commit

Для объединения коммитов
Необходимо изменить pick на squash над коммитами которые вы хотите объединить.
Пример: вы хотите объединить коммиты 750f5ae и 716eb99.
Необходимо изменить скрипт с такого:
pick 2748cb4 third commit
pick 750f5ae second commit
pick 716eb99 first commit
На такой
pick 2748cb4 third commit
squash 750f5ae second commit
squash 716eb99 first commit

Заметьте что в интерактивном скрипте коммиты изображены в обратном порядке нежели в git log. С помощью squash вы объедините коммит 750f5ae с 716eb99, а 750f5ae с 2748cb4. В итоге получая один коммит содержащий изменения всех трёх.

2.5 Просмотр истории

С помощью команды

git log [<опции>] [<диапазон-редакций>]

вы можете просматривать историю коммитов вашего репозитория. Есть также куча параметров для сортировки и поиска определённого коммита.

Полезные параметры команды git log:

  • -p — Показывает разницу для каждого коммита.
  • —stat — Показывает статистику измененных файлов для каждого коммита.
  • —graph — Отображает ASCII граф с ветвлениями и историей слияний.

Тагже можно отсортировать коммиты по времени, количеству и тд.

  • -(n) Показывает только последние n коммитов.
  • —since, —after — Показывает коммиты, сделанные после указанной даты.
  • —until, —before — Показывает коммиты, сделанные до указанной даты.
  • —author — Показывает только те коммиты, в которых запись author совпадает с указанной строкой.
  • —committer — Показывает только те коммиты, в которых запись committer совпадает с указанной строкой.
  • —grep — Показывает только коммиты, сообщение которых содержит указанную строку.
  • -S — Показывает только коммиты, в которых изменение в коде повлекло за собой добавление или удаление указанной строки.

Вот несколько примеров:
git log —since=3.weeks — Покажет коммиты за последние 2 недели
git log —since=«2019-01-14» — Покажет коммиты сделанные 2019-01-14
git log —since=«2 years 1 day ago» — Покажет коммиты сделанные 2 года и один день назад.

Также вы можете настроить свои формат вывода коммитов с помощью

git log --format:["format"]

Варианты форматирования для git log —format.

  • %H — Хеш коммита
  • %h — Сокращенный хеш коммита
  • %T — Хеш дерева
  • %t — Сокращенный хеш дерева
  • %P — Хеш родителей
  • %p — Сокращенный хеш родителей
  • %an — Имя автора — %ae — Электронная почта автора
  • %ad — Дата автора (формат даты можно задать опцией —date=option)
  • %ar — Относительная дата автора
  • %cn — Имя коммитера
  • %ce — Электронная почта коммитера
  • %cd — Дата коммитера
  • %cr — Относительная дата коммитера
  • %s — Содержание

Пример:

git log --pretty=format:"%h - %ar : %s"

покажет список коммитов состоящий из хэша времени и сообщения коммита.

2.6 Работа с удалённым репозиторием

Так как git это распределённая СКВ вы можете работать не только с локальными но и с внешними репозиториеми.

Удалённые репозитории представляют собой версии вашего проекта, сохранённые на внешнем сервере.

Для работы с внешними репозиториями используйте:

git remote [<options>]

Если вы с клонировали репозитории через http URL то у вас уже имеется ссылка на внешний. В другом случае вы можете добавить её с помощью

git remote add [<options>] <name> <adres>

Вы можете тут же извлечь внешние ветки с помощью -f, —fetch (вы получите имена и состояние веток внешнего репозитория). Вы можете настроить репозитории только на отправку или получение данных с помощью —mirror[=(push|fetch)]. Для получения меток укажите —tags.

Для просмотра подключённых внешних репозиториев используйте git remote без аргументов или git remote -v для просмотра адресов на отправку и получение данных от репозитория.

Для отслеживания веток используйте git branch -u <rep/br> где rep это название репозитория, br название внешней ветки, а branch название локальной ветки. Либо git branch —set-upstream local_br origin/br для того что бы указать какая именно локальная ветка будет отслеживать внешнюю ветку.

Когда ваша ветка отслеживает внешнюю вы можете узнать какая ветка (локальная или внешняя) отстаёт или опережает и на сколько коммитов. К примеру если после коммита вы не выполняли git push то ваша ветка будет опережать внешнюю на 1 коммит. Вы можете узнать об этом выполнив git branch -vv, но прежде выполните git fetch [remote-name] (—all для получения обновления со всех репозиториев) что бы получить актуальные данные из внешнего репозитория. Для отмены отслеживания ветки используйте git branch —unset-upstream [<local_branch>].

Для загрузки данных с внешнего репозитория используйте git pull [rep] [branch]. Если ваши ветки отслеживают внешние, то можете не указывать их при выполнение git pull. По умолчанию вы получите данные со всех отслеживаемых веток.

Для загрузки веток на новую ветку используйте git checkout -b <new_branch_name> <rep/branch>.

Для отправки данных на сервер используйте

git push [<rep>] [<br>]

где rep это название внешнего репозитория, а br локальная ветка которую вы хотите отправить. Также вы можете использовать такую запись git push origin master:dev. Таким образом вы выгрузите вашу локальную ветку master на origin (но там она будет называется dev). Вы не сможете отправить данные во внешний репозитории если у вас нет на это прав. Также вы не сможете отправить данные на внешнюю ветку если она опережает вашу (в общем то отправить вы можете используя -f, —forse в этом случае вы перепишите историю на внешнем репозитории). Вы можете не указывать название ветки если ваша ветка отслеживает внешнюю.

Для удаления внешних веток используйте

git push origin --delete branch_name

Для получения подробной информации о внешнем репозитории (адреса для отправки и получения, на что указывает HEAD, внешние ветки, локальные ветки настроенные для git pull и локальные ссылки настроенные для git push)

git remote show <remote_name>

Для переименования названия внешнего репозитория используйте

git remote rename <last_name> <new_name>

Для удаления ссылки на внешний репозитории используйте

git remote rm <name>

3. Ветвление в git

Ветвление это мощные инструмент и одна из главных фич git’а поскольку позволяет вам быстро создавать и переключатся между различным ветками вашего репозитория. Главная концепция ветвления состоит в том что вы можете откланяться от основной линии разработки и продолжать работу независимо от нее, не вмешиваясь в основную линию. Ветка всегда указывает на последний коммит в ней, а HEAD указывает на текущую ветку (см. Указатели в git).

3.1 Базовые операций

Для создания ветки используйте

git branch <branch_name> [<start_commit>]

Здесь branch_name это название для новой ветки, а start_commit это коммит на который будет указывать ветка (то есть последний коммит в ней). По умолчанию ветка будет находится на последнем коммите родительской ветки.

Опции git branch:

  • -r | -a [—merged | —no-merged] — Список отслеживаемых внешних веток -r. Список и отслеживаемых и локальных веток -a. Список слитых веток —merged. Список не слитых веток —no-merged.
  • -l, -f <имя-ветки> [<точка-начала>] — Список имён веток -l. Принудительное создание, перемещение или удаление ветки -f. Создание новой ветки <имя ветки>.
  • -r (-d | -D) — Выполнить действие на отслеживаемой внешней ветке -r. Удалить слитую ветку -d. Принудительное удаление (даже не слитой ветки) -D.
  • -m | -M [<Старая ветка>] <Новая ветка> — Переместить/переименовать ветки и ее журнал ссылок (-m). Переместить/переименовать ветку, даже если целевое имя уже существует -M.
  • (-с | -С) [<старая-ветка>] <новая-ветка> — Скопировать ветку и её журнал ссылок -c. Скопировать ветку, даже если целевое имя уже существует -C.
  • -v, -vv — Список веток с последним коммитом на ветке -v. Список и состояние отслеживаемых веток с последним коммитом на них.

Больше информации смотрите в git branch -h | —help.

Для переключения на ветку используйте git checkout . Также вы можете создать ветку выполнив git checkout -b <ветка>.

3.2 Слияние веток

Для слияния 2 веток git репозитория используйте git merge .

Полезные параметры для git merge:

  • —squash — Создать один коммит вместо выполнения слияния. Если у вас есть конфликт на ветках, то после его устранения у вас на ветке прибавится 2 коммита (коммит с сливаемой ветки + коммит слияния), но указав этот аргумент у вас прибавится только один коммит (коммит слияния).
  • —ff-only — Не выполнять слияние если имеется конфликт. Пусть кто ни будь другой разрешает конфликты :D
  • -X [strategy] — Использовать выбранную стратегию слияния.
  • —abort — Отменить выполнение слияния.

Процесс слияния.
Если вы не выполняли на родительской ветке новых коммитов то слияние сводится к быстрой перемотке «fast-forward», будто бы вы не создавали новую ветку, а все изменения происходили прям тут (на родительской ветке).

Если вы выполняли коммиты на обеих ветках, но при этом не создали конфликт, то слияния пройдёт в «recursive strategy», то есть вам просто нужно будет создать коммит слияния что бы применить изменения (используйте опцию —squash что бы не создавать лишний коммит).
Если вы выполняли коммиты на обоих ветках, которые внесли разные изменения в одну и ту же часть одного и того же файла, то вам придётся устранить конфликт и зафиксировать слияние коммитом.

При разрешении конфликта вам необходимо выбрать какую часть изменений из двух веток вы хотите оставить. При открытии конфликтующего файла, в нём будет содержатся следующее:
<<<<<<< HEAD
Тут будет версия изменения последнего коммита текущей ветки
======
Тут будет версия изменений последнего коммита сливаемой ветки
>>>>>>> Тут название ветки с которой сливаем

Разрешив конфликт вы должны завершить слияния выполнив коммит.

Во время конфликта вы можете посмотреть какие различия в каких файлах имеются.
git diff —ours — Разница до слияния и после
git diff —theirs — Разница сливаемой ветки до слияния и после
git diff —base — Разница с обеими ветками до слияния и после

Если вы не хотите разрешать слияние то используйте различные стратегии слияния, выбрав либо «нашу» версию (то есть ту которая находится на текущей ветке) либо выбрать «их» версию находящуюся на сливаемой ветке при этом не исправляя конфликт. Выполните git merge —Xours или git merge —Xtheirs соответственно.

3.3 Rerere

Rerere — «reuse recorded resolution” — “повторное использование сохраненных разрешений конфликтов». Механизм rerere способен запомнить каким образом вы разрешали некую часть конфликта в прошлом и провести автоматическое исправление конфликта при возникновении его в следующий раз.

Что бы включить rerere выполните

git config --global rerere.enabled true

Таrже вы можите включить rerere создав каталог .git/rr-cache в нужном репозитории.

Используйте git rerere status для того что бы посмотреть для каких файлов rerere сохранил снимки состояния до начала слияния.

Используйте git rerere diff для просмотра текущего состояния конфликта.

Если во время слияния написано: Resolved ‘nameFile’ using previous resolution. Значит rerere уже устранил конфликт используя кэш.

Для отмены автоматического устранения конфликта используйте git checkout —conflict=merge таким образом вы отмените авто устранение конфликта и вернёте файл(ы) в состояние конфликта для ручного устранения.

4. Указатели в git

в git есть такие указатели как HEAD branch. По сути всё очень просто HEAD указывает на текущую ветку, а ветка указывает на последний коммит в ней. Но для понимания лучше представлять что HEAD указывает на последний коммит.

4.1 Перемещение указателей

В книге Pro git приводится очень хороший пример того как вы можете управлять вашим репозиторием поэтому я тоже буду придерживается его. Представите что Git управляет содержимым трех различных деревьев. Здесь под “деревом” понимается “набор файлов”.
В своих обычных операциях Git управляет тремя деревьями:

  • HEAD — Снимок последнего коммита, родитель следующего
  • Индекс — Снимок следующего намеченного коммита
  • Рабочий Каталог — Песочница

Собственно git предоставляет инструменты для манипулировании всеми тремя деревьями. Далее будет рассмотрена команда git reset, позволяющая работать с тремя деревьями вашего репозитория.

Используя различные опций этой команды вы можете:

  • —soft — Cбросить только HEAD
  • —mixed — Cбросить HEAD и индекс
  • —hard — Cбросить HEAD, индекс и рабочий каталог

Под сбросить понимается переместить на указанный коммит. По умолчанию выполняется —mixed.

Примеру 1. Вы сделали 3 лишних коммита каждый из которых приносит маленькие изменения и вы хотите сделать из них один, таким образом вы можете с помощью git reset —soft переместить указатель HEAD при этом оставив индекс и рабочий каталог нетронутым и сделать коммит. В итоге в вашей истории будет выглядеть так, что все изменения произошли в одном коммите.

Пример 2. Вы добавили в индекс лишние файлы и хотите их от туда убрать. Для этого вы можете использовать git reset HEAD <files…>. Или вы хотите что бы в коммите файлы выглядели как пару коммитов назад. Как я уже говорил ранее вы можете сбросить индекс на любой коммит в отличий от git restore который сбрасывает только до последнего коммита. Только с опцией mixed вы можете применить действие к указанному файлу!

Пример 3. Вы начали работать над новой фичей на вашем проекте, но вдруг работодатель говорит что она более не нужна и вы в порыве злости выполняете git reset —hard возвращая ваш индекс, файлы и HEAD к тому моменту когда вы ещё не начали работать над фичей. А на следующей день вам говорят, что фичу всё таки стоит запилить. Но что же делать? Как же переместится вперёд ведь вы откатили все 3 дерева и теперь в истории с помощью git log их не найти. А выход есть — это журнал ссылок git reflog. С помощью этой команды вы можете посмотреть куда указывал HEAD и переместится не только вниз по истории коммитов но и вверх. Этот журнал является локальным для каждого пользователя.

В общем думаю вы сможете придумать намного больше примеров чем я. В заключение скажу, что с помощью git reset можно творить магию…

5. Рекомендуемая литература

  1. Pro git — Scott Chacon
  2. Git для профессионального программиста — С. Чакон, Б, Штрауб
  3. Git Essentials — F. Santacroce
  4. Git: Version Control for Everyone (2013) — R. Somasundaram
  5. Version Control with Git: Powerful tools and techniques for collaborative software development (2009) — J. Loeliger, M. McCullough
  6. Practical Git and GitHub (2016) — D. Cruz
  7. Git in Practice (2016) — M. McQuaid
  8. Git Best Practices Guide (2014) — E. Pidoux
  9. Learn Enough Git to Be Dangerous (2016) — M. Hartl
  10. Learn Version Control with Git: A step-by-step course for the complete beginner (2014) — T. Günther
  11. Git: Learn Version Control with Git: A step-by-step Ultimate beginners Guide (2017) — D. Hutten
  12. Pragmatic Guide to Git (2010) — S. Travis
  13. Волшебство Git (2016) — Б. Лин
  14. A Hacker’s Guide to Git (2014) — J. Wynn
  15. Practical Git and GitHub (2016) — D. Cruz
  16. Deploying to OpenShift(2018) — G. Dumpleton
  17. Git for Teams (2015) — Emma Jane Hogbin Westby

Понравилась статья? Поделить с друзьями:
  • Морозильник бирюса 145 с инструкция по применению
  • Рексолин авс удобрение инструкция по применению
  • Панаметрикс рт878 руководство по эксплуатации
  • Мануалы на мерседес w140
  • Bosch sd4p1b инструкция по эксплуатации на русском языке посудомоечная машина