10. Branching

A branch represents an independent line of development. Branches serve as an abstraction for the edit/stage/commit process. You can think of them as a way to request a brand new working directory, staging area, and project history. New commits are recorded in the history for the current branch, which results in a fork in the history of the project.

The git branch command lets you create, list, rename, and delete branches. It doesn’t let you switch between branches or put a forked history back together again. For this reason, git branch is tightly integrated with the git checkout and git merge commands.

  • Каждая ветка представляет собой линейный список коммитов, где каждый следующий коммит указывает на предыдущий.

  • Концепция ветки в Git определяется исключительно цепочкой входящих в неё коммитов.

  • Каждая ветка имеет голову списка, коммит по имени HEAD - последний добавленный в неё элемент

  • После переключения на ветку мы переключается на её HEAD.

  • Переключаясь на конкретный коммит git checkout commit мы сдвигаем HEAD на этот коммит.

git branch <branch>     # Create a new branch called <branch>
git branch                  # показать текущую ветку
git branch -                # переключиться на предыдущую ветку

git branch -a               # list of all branches
git branch -r               # list of remote branches
git branch -v               # список веток с последним коммитом в каждой
git branch -vv              ## show branches with remote tracking

git branch -d <branch>      # delete branch (safe - do not delete if it has unmerged changes.)
git branch -D <branch>      # force delete branch
git push origin --delete <branch> # delete remote branch

git branch [--merged|--no-merged] # список слитых/не слитых веток
git branch [-u|--set-upstream-to] <remote>/<branch>

git push origin --delete branch-name

git checkout new-feature    # переключение на новую ветку
git checkout -b <new-branch> <existing-branch> # создание новой ветки на основе старой ветки

git branch --track <new-branch> <remote-branch> # create a new tracking branch based on a remote branch:

Detached HEAD state

При выполнении некоторых команд, если мы не указываем имя файла, и не указываем имя локальной ветки, а указываем тег, дистанционную (remote) ветку, SHA-1 хеш коммита или что-то вроде master~3, то мы получаем безымянную ветку, называемую «Detached HEAD» (оторванная голова). Это очень полезная штука, если нам надо осмотреться в истории коммитов.

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

Если после такого коммита вы переключитесь в ветку master, то коммит, совершённый из состояния «Detached HEAD», потеряется и попросту будет уничтожен очередной сборкой мусора только потому, что нет ни одного объекта, который бы на него ссылался: ни ветки, ни тега. В том случае, если вы хотите сохранить этот коммит на будущее, вы можете создать на основе него новую ветку командой git checkout -b new.

В том случае, если вы хотите сохранить этот коммит на будущее, вы можете создать на основе него новую ветку командой git checkout -b new.

Merging

Команда git merge сливает две ветки между собой. Результатом этой команды становится особенный merge commit. Его отличие от остальных коммитов в том, что этот коммит не содержит изменений, но ссылается сразу на двух родителей.

Команда git merge выполняется из той ветки, в которую мы сливаем изменения, а аргументом передается имя той ветки, которую мы сливаем.

git merge-base branch master # поиск коммита - предка двух веток для мержа

Команда git merge может выполняться в двух режимах в зависимости от истории коммитов:

  • Fast-forward. A fast-forward merge can occur when there is a linear path from the current branch tip to the target branch. Instead of “actually” merging the branches, all Git has to do to integrate the histories is move (i.e., “fast forward”) the current branch tip up to the target branch tip

  • 3-way merge. However, a fast-forward merge is not possible if the branches have diverged. 3-way merges use a dedicated commit to tie together the two histories.

Last updated