Что такое branch name

Гит-словарик для начинающих программистов

Мёржим бранчи и коммитим реквесты

Мы часто упоминаем Git — способ организации хранения и контроля версий файлов в рабочем проекте. Сегодня расскажем о странных словах: «бранч», «коммит», «пулл-реквест» и об остальных понятиях в гите.

О чём речь

Гит — это такой способ хранения файлов и их версий. Гит позволяет смотреть историю изменений файлов, кто какие дополнения и когда вносил, как развивался проект, кто что в него добавлял и почему.

Главная особенность гита — он помнит всё, что вы в него внесли, и может показать, какие именно строчки вы правили несколько лет назад, когда чинили ошибку авторизации, например.

На базе гита есть сервис «Гитхаб». Работает так:

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

Это если вкратце. Теперь будут подробности.

Что такое репозиторий (git repository)

Гит-репозиторий — это облачное хранение вашего проекта на сервере (например, на сервере Гитхаба, но можно и на другом).

У каждого программиста может быть сколько угодно репозиториев, по одному на каждый проект. А можно вести все проекты в одном репозитории, но тогда это превратится в мешанину. Но каждый имеет право на мешанину.

В репозитории могут храниться:

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Что такое бранч (git branch)

Бранч — это ветка или копия проекта, в которую можно вносить любые изменения и они не повлияют на основной проект.

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

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

Но представьте такую ситуацию: мы только что запустили сайт для заказчика и он срочно хочет добавить интерактивный раздел со скидками. Можно сделать так: править рабочие файлы проекта «по живому», чтобы сразу видеть результат. А можно сделать из мастера отдельную ветку news и работать уже в ней (и это очень похоже на форк). В этом случае мы получим полную копию проекта, в которую можно вносить любые правки и они никак не повлияют на запущенный сайт. Мы в этой ветке пилим всё, что нужно клиенту, показываем ему результат на секретном сайте, а потом объединяем её с мастером. Это называется «смёржить бранчи».

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Что такое клонирование (git clone)

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

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

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

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Что значит «смёржить» (git merge)

Смёржить (от англ. merge — объединять, совмещать) — это когда мы отправляем всё, что сделали в одной ветке, в другую. Весь новый код, исправления ошибок, дополнительные функции — всё это отправится в новую ветку. Если же мы что-то удалим в коде, то при объединении этот фрагмент тоже удалится из основной ветки.

Получается, что схема работает так:

Что такое коммит (git commit)

Программировать только в облаке неудобно — проще скачать себе на компьютер весь проект и писать код на своей машине. Но чтобы правки увидели остальные, их нужно отправить обратно в репозиторий. Это и есть коммит.

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

Например, вы изменили файл главной страницы index.html и добавили его в список файлов текущего коммита. Теперь его можно отправить на сервер, а можно ещё поправить сразу style.css и внести в этот же коммит. Системе всё равно, сколько файлов обрабатывать, поэтому как и что коммитить — решает программист.

Единственное требование к коммитам — указывать, что именно вы поменяли в проекте, человеческим языком. Хорошим тоном и правильным подходом считается писать, что именно вы изменили: «Добавил цвет и стили основной кнопки», «Убрали метод вызова старого API», «Сделали рефакторинг функции SetOutOfDate()». Это описание будут читать другие разработчики.

Коммитить можно хоть после правки каждой строчки — весь вопрос в том, насколько нужна такая детализация в проекте. Но иногда и изменения из одной строчки можно закоммитить, если оно действительно важное.

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Что такое пуш и пулл (git push, git pull)

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

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

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

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Чем коммит отличается от пуша

Коммит — это когда вы фиксируете изменения в проекте, как бы подводите итог своей работе.

Пуш — это когда вы отправляете сделанную работу туда, где хранится копия вашего кода.

Получается, последовательность действий такая:

Что дальше

Чтобы все эти бранчи и реквесты стали понятнее, в следующий раз сделаем вот что: заведём учебный проект на Гитхабе и будем работать с ним так, как делают настоящие программисты.

Источник

branch code

Смотреть что такое «branch code» в других словарях:

Branch code — An ISO term. A code which may identify a specific branch, legal entity, or department of a financial institution. See also BIC code … International financial encyclopaedia

Branch number — A number to identify a branch. This is not the branch number as SWIFT defines it. See also Branch code and BIC code … International financial encyclopaedia

Branch predication — is a strategy in computer architecture design for mitigating the costs usually associated with conditional branches, particularly branches to short sections of code. It does this by allowing each instruction to conditionally either perform an… … Wikipedia

Code coverage — is a measure used in software testing. It describes the degree to which the source code of a program has been tested. It is a form of testing that inspects the code directly and is therefore a form of white box testing.[1] Code coverage was among … Wikipedia

Code Co-op — Developer(s) Reliable Software Initial release 1996; 14 years ago (1996) Stable rele … Wikipedia

Branch Prediction — [dt. »Verzweigungsvorhersage«, »Sprungvorhersage«] die, eine von Intel erstmals im Pentium Prozessor eingesetzte Technik zur Erhöhung der Arbeitsgeschwindigkeit. Branch Prediction setzt auf der Prefetch Technik (Prefetch) auf, bei welcher der… … Universal-Lexikon

Branch misprediction — occurs when a central processing unit (CPU) mispredicts the next instruction to process in branch prediction, which is aimed at speeding up execution. During the execution of certain programs there are places where the program execution flow can… … Wikipedia

code — [kəʊd ǁ koʊd] noun 1. [countable] LAW a complete set of written rules or laws: • Each state in the US has a different criminal and civil code. ˈbuilding code [countable] LAW a set of rules that states what features a new building, bridge etc… … Financial and business terms

Code of the Clans — … Wikipedia

Источник

branch no.

Смотреть что такое «branch no.» в других словарях:

Branch — ist der Name folgender Personen: Ben Branch (1924–1987), US amerikanischer Unternehmer, Tenor Saxophonist und Bandleader Billy Branch (* 1951), US amerikanischer Mundharmonika Spieler Cliff Branch (* 1948), US amerikanischer Footballspieler Craig … Deutsch Wikipedia

branch — branch; branch·less; branch·let; ca·du·ci·branch; di·branch; dis·branch; em·branch·ment; fo·lio·branch; hemi·branch; hol·o·branch; in·ter·branch; mal·e·branch·ism; mal·e·branch·ist; mar·si·po·branch; pe·ren·ni·branch; pleu·ro·branch; podo·branch; … English syllables

Branch — Branch, n.; pl. . [OE. braunche, F. branche, fr. LL. branca claw of a bird or beast of prey; cf. Armor. brank branch, bough.] 1. (Bot.) A shoot or secondary stem growing from the main stem, or from a principal limb or bough of a tree or … The Collaborative International Dictionary of English

Branch — Saltar a navegación, búsqueda Branch, que en inglés significa rama, puede hacer referencia a: Lugares En Canadá: La localidad de Branch, en la provincia de Terranova y Labrador. En Estados Unidos: La localidad de Branch, en el estado de Arkansas … Wikipedia Español

branch — [branch, bränch] n. [ME branche < OFr brance < LL branca, a claw, paw] 1. any woody extension growing from the trunk or main stem, or from a main limb, of a tree or shrub 2. anything physically resembling a branch, as a tine of a deer s… … English World dictionary

branch — n: a part of a complex body: as a: one of the three main divisions of the U.S. or a state government see also executive, judiciary, legislature b: a division of a business or or … Law dictionary

Branch — Branch, a. Diverging from, or tributary to, a main stock, line, way, theme, etc.; as, a branch vein; a branch road or line; a branch topic; a branch store. [1913 Webster] … The Collaborative International Dictionary of English

Branch — Branch, v. i. [imp. & p. p. ; p. pr. & vb. n. .] 1. To shoot or spread in branches; to separate into branches; to ramify. [1913 Webster] 2. To divide into separate parts or subdivision. [1913 Webster] , to form … The Collaborative International Dictionary of English

Branch — Branch, AR U.S. city in Arkansas Population (2000): 357 Housing Units (2000): 155 Land area (2000): 3.565727 sq. miles (9.235191 sq. km) Water area (2000): 0.001730 sq. miles (0.004480 sq. km) Total area (2000): 3.567457 sq. miles (9.239671 sq.… … StarDict’s U.S. Gazetteer Places

Branch, AR — U.S. city in Arkansas Population (2000): 357 Housing Units (2000): 155 Land area (2000): 3.565727 sq. miles (9.235191 sq. km) Water area (2000): 0.001730 sq. miles (0.004480 sq. km) Total area (2000): 3.567457 sq. miles (9.239671 sq. km) FIPS… … StarDict’s U.S. Gazetteer Places

Branch — Branch, v. t. 1. To divide as into branches; to make subordinate division in. [1913 Webster] 2. To adorn with needlework representing branches, flowers, or twigs. [1913 Webster] The train whereof loose far behind her strayed, Branched with gold… … The Collaborative International Dictionary of English

Источник

Ежедневная работа с Git

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

Конечно, я попытаюсь рассказать обо всём по-порядку, начиная с основ. Поэтому, эта статья будет крайне полезна тем, кто только начинает или хочет разобраться с git. Более опытные читатели, возможно, найдут для себя что-то новое, укажут на ошибки или поделятся советом.

Вместо плана

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

Окружение

Если вы открываете консоль, пишите git и получаете вот это:

Перестаём бояться экспериментировать

Строго говоря, даже неудачный git push можно исправить.

Поэтому, спокойно можете клонировать любой репозиторий и начать изучение.

Строим репозитории

В первую очередь нужно понять что такое git-репозиторий? Ответ очень прост: это набор файлов. Папка `.git`. Важно понимать, что это только набор файлов и ничего больше. Раз 20 наблюдал проблему у коллег с авторизацией в github/gitlab. Думая, что это часть git-системы, они пытались искать проблему в конфигруации git, вызывать какие-то git-команды.

В частности, при клонировании вот так:

урл «превращается» в

Т.е. используется SSH и проблемы нужно искать в нём. Как правило, это неправильно настроенный или не найденный ssh-ключ. Гуглить надо в сторону «SSH Auth Key git» или, если совсем по взрослому, проверить, что же происходит:

Какие протоколы поддерживаются поможет справка (раздел GIT URLS):

Сделаем себе один (будет нашим главным тестовым репозиторием):

Итог: у нас есть 3 репозитория. Там ничего нет, зато они готовы к работе.

Начало GIT

Скандалы! Интриги! Расследования!

Как это всё работает?
Как это всё можно понять и запомнить?

Для этого нужно заглянуть под капот. Рассмотрим всё в общих чертах.

Git. Почти под капотом

Git сохраняет в commit содержимое всех файлов (делает слепки содержимого каждого файла и сохраняет в objects). Если файл не менялся, то будет использован старый object. Таким образом, в commit в виде новых объектов попадут только изменённые файлы, что позволит хорошо экономить место на диске и даст возможность быстро переключиться на любой commit.

Это позволяет понять, почему работают вот такие вот забавные штуки:

Да, не стоит хранить «тяжёлые» файлы, бинарники и прочее без явной необходимости. Они там останутся навсегда и будут в каждом клоне репозитория.

Каждый коммит может иметь несколько коммитов-предков и несколько дочерних-коммитов:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

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

Каждое слияние двух и более коммитов в один — это merge (объединение двух и более наборов изменений).
Каждое разветвление — это появление нескольких вариантов изменений.

Кстати, тут хочется отметить, что нельзя сделать тэг на файл/папку, на часть проекта и т.д. Состояние восстанавливается только целиком. Поэтому, рекомендуется держать проекты в отдельном репозитории, а не складывать Project1, Project2 и т.д. просто в корень.

Теперь к веткам. Выше я написал:

В Git нет веток* (с небольшой оговоркой)

Получается, что так и есть: у нас есть много коммитов, которые образуют граф. Выбираем любой путь от parent-commit к любому child-commit и получаем состояние проекта на этот коммит. Чтобы коммит «запомнить» можно создать на него именованный указатель.
Такой именованный указатель и есть ветка (branch). Так же и с тэгом (tag). `HEAD` работает по такому же принципу — показывает, где мы есть сейчас. Новые коммиты являются продолжением текущей ветки (туда же куда и смотрит HEAD).

Указатели можно свободно перемещать на любой коммит, если это не tag. Tag для того и сделан, чтобы раз и навсегда запомнить коммит и никуда не двигаться. Но его можно удалить.
Вот, пожалуй, и всё, что нужно знать из теории на первое время при работе с git. Остальные вещи должны показаться теперь более понятными.

Терминология

index — область зафиксированных изменений, т.е. всё то, что вы подготовили к сохранению в репозиторий.
commit — изменения, отправленные в репозиторий.
HEAD — указатель на commit, в котором мы находимся.
master — имя ветки по-умолчанию, это тоже указатель на определённый коммит
origin — имя удалённого репозитория по умолчанию (можно дать другое)
checkout — взять из репозитория какое-либо его состояние.

Простые правки

Если вы сделали что-то не так, запутались, не знаете, что происходит — эти две команды вам помогут.

Вернёмся к нашим репозиториям, которые создали раньше. Далее обозначу, что один разработчик работает в dev1$, а второй в dev2$.

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

Второй разработчик может получить эти изменения, сделав pull:

Добавим ещё пару изменений:

Посмотрим, что же мы сделали (запускаем gitk):

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Выделил первый коммит. Переходя по-порядку, снизу вверх, мы можем посмотреть как изменялся репозиторий:

До сих пор мы добавляли коммиты в конец (там где master). Но мы можем добавить ещё один вариант README.md. Причём делать мы это можем из любой точки. Вот, например, последний коммит нам не нравится и мы пробуем другой вариант. Создадим в предыдущей точке указатель-ветку. Для этого через git log или gitk узнаем commit id. Затем, создадим ветку и переключимся на неё:

Выглядит это так:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

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

Быстрая перемотка

Наверняка, вы уже встречали слова fast-forward, rebase, merge вместе. Настало время разобраться с этими понятиями. Я использую rebase, кто-то только merge. Тем «rebase vs merge» очень много. Авторы часто пытаются убедить, что их метод лучше и удобнее. Мы пойдём другим путём: поймём, что же это такое и как оно работает. Тогда сразу станет ясно, какой вариант использовать в каком случае.

Пока, в пределах одного репозитория, сделаем ветвление: создадим файл, положим в репозиторий, из новой точки создадим два варианта файла и попробуем объединить всё в master:

Создадим файл collider.init.sh с таким содержанием:

Добавим, закоммитим и начнём разработку в новой ветке:

Обратите внимание, что в имени ветки не запрещено использовать символ ‘/’, однако, надо быть осторожным, т.к. в файловой системе создаётся папка с именем до ‘/’. Если ветка с таким названием как и папка существует — будет конфликт на уровне файловой системы. Если уже есть ветка dev, то нельзя создать dev/test.
A если есть dev/test, то можно создавать dev/whatever, но нельзя просто dev.

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

Разработка закончена и теперь надо отдать все изменения в master (там ведь старый коллайдер, который ничего не может). Объединение двух коммитов, как и говорилось выше — это merge. Но давайте подумаем, чем отличается ветка master от collider/start и как получить их объединение (сумму)? Например, можно взять общие коммиты этих веток, затем прибавить коммиты, относящиеся только к master, а затем прибавить коммиты, относящиеся только к collider/start. А что у нас? Общие коммиты — есть, только коммиты master — нет, только collider/start — есть. Т.е. объединение этих веток — это master + коммиты от collider/start. Но collider/start — это master + коммиты ветки collider/start! Тоже самое! Т.е. делать ничего не надо! Объединение веток — это и есть collider/start!
Ещё раз, только на буквах, надеюсь, что будет проще для восприятия:
master = C1 + C2 +C3
collider/start = master + C4 = C1 + C2 +C3 + C4
master + collider/start = Общие_коммиты(master, collider/start) + Только_у(master) + Только_у(collider/start) = (C1 + C2 +C3) + (NULL) + (C4) = C1 + C2 +C3 + C4

Как быстро узнать, что fast-forward возможен? Для этого достаточно посмотреть в gitk на две ветки, которые нужно объединить и ответить на один вопрос: существует ли прямой путь от ветки А к B, если двигаться только вверх (от нижней к верхней). Если да — то будет fast-forward.
В теории понятно, пробуем на практике, забираем изменения в master:

Результат (указатель просто передвинулся вперёд):
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Объединение

Теперь забираем изменения из collider/terminate. Но, тот, кто дочитал до сюда (дочитал ведь, да?!) заметит, что прямого пути нет и так красиво мы уже не отделаемся. Попробуем git попросить fast-forward:

Что и следовало ожидать. Делаем просто merge:

Я даже рад, что у нас возник конфликт. Обычно, в этом момент некоторые теряются, лезут гуглить и спрашивают, что делать.
Для начала:

Конфликт возникает при попытке объединить два и более коммита, в которых в одной и той же строчке были сделаны изменения. И теперь git не знает что делать: то ли взять первый вариант, то ли второй, то ли старый оставить, то ли всё убрать.

Как всегда, две самые нужные команды нам спешат помочь:

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Мы находимся в master, туда же указывает HEAD, туда же и добавляются наши коммиты.
Файл выглядит так:

Из-за того что изменения были в одних и тех же местах конфликтов получилось много. Поэтому, я брал везде первый вариант, а второй копировал сразу после первого, но с gui это сделать довольно просто. Вот результат — вверху варианты файла, внизу — объединение (простите за качество):
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Сохраняем результат, закрываем окно, коммитим, смотрим результат:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Мы создали новый коммит, который является объединением двух других. Fast-forward не произошёл, потому, что не было прямого пути для этого, история стала выглядеть чуть-чуть запутаннее. Иногда, merge действительно нужен, но излишне запутанная история тоже ни к чему.
Вот пример реального проекта:

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch nameЧто такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch nameЧто такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Конечно, такое никуда не годится! «Но разработка идёт параллельно и никакого fast-forward не будет» скажете вы? Выход есть!

Перестройка

Что же делать, чтобы история оставалась красивой и прямой? Можно взять нашу ветку и перестроить её на другую ветку! Т.е. указать ветке новое начало и воспроизвести все коммиты один за одним. Этот процесс и называется rebase. Наши коммиты станут продолжением той ветки, на которую мы их перестроим. Тогда история будет простой и линейной. И можно будет сделать fast-forward.
Другими словами: мы повторяем историю изменений с одной ветки на другой, как будто бы мы действительно брали другую ветку и заново проделывали эти же самые изменения.

Для начала отменим последние изменения. Проще всего вернуть указатель master назад, на предыдущее состояние. Создавая merge-commit, мы передвинули именно master, поэтому именно его нужно вернуть назад, желательно (а в отдельных случаях важно) на тот же самый commit, где он был.
Как результат, наш merge-commit останется без какого-либо указателя и не будет принадлежать ни к одной ветке.

Используя gitk или консоль перемещаем наш указатель. Поскольку, ветка collider/start уже указывает на наш коммит, нам не нужно искать его id, а мы можем использовать имя ветки (это будет одно и тоже):

Когда с коммита или с нескольких коммитов пропадает указатель (ветка), то коммит остаётся сам по себе. Git про него забывает, не показывает его в логах, в ветках и т.д. Но физически, коммит никуда не пропал. Он живёт себе в репозитории как невостребованная ячейка памяти без указателя и ждёт своего часа, когда git garbage collector её почистит.
Иногда бывает нужно вернуть коммит, который по ошибке был удалён. На помощь придёт git reflog. Он покажет всю историю, по каким коммитам вы ходили (как передвигался указатель HEAD). Используя вывод, можно найти id пропавшего коммита, сделать его checkout или создать на коммит указатель (ветку или тэг).
Выглядит это примерно так (история короткая, поместилась вся):

Посмотрим, что получилось:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Для того, чтобы перестроить одну ветку на другую, нужно найти их общее начало, потом взять коммиты перестраиваемой ветки и, в таком же порядке, применить их на основную (base) ветку. Очень наглядная картинка (feature перестраивается на master):
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Важное замечание: после «перестройки» это уже будут новые коммиты. А старые никуда не пропали и не сдвинулись.

В теории разобрались, пробуем на практике. Переключаемся в collider/terminate и перестраиваем на тот коммит, куда указывает master (или collider/start, кому как удобнее). Команда дословно «взять текущую ветку и перестроить её на указанный коммит или ветку»:

Откроется редактор в котором будет приблизительно следующее:

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

На данном этапе мы удаляли, редактировали, объединяли правки, а на выходе получили красивую линейную историю изменений:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Перерыв

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

Передача и приём изменений

git remote

Как отмечалось выше, origin — это имя репозитория по умолчанию. Имена нужны, т.к. репозиториев может быть несколько и их нужно как-то различать. Например, у меня была копия репозитория на флешке и я добавил репозиторий flash. Таким образом я мог работать с двумя репозиториями одновременно: origin и flash.

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

В справке по git remote достаточно хорошо всё описано. Как и ожидается, там есть команды: add, rm, rename, show.
show покажет основные настройки репозитория:

Чтобы добавить существующий репозиторий используем add :

git fetch

Команда говорит сама за себя: получить изменения.
Стоит отметить, что локально никаких изменений не будет. Git не тронет рабочую копию, не тронет ветки и т.д.
Будут скачены новые коммиты, обновлены только удалённые (remote) ветки и тэги. Это полезно потому, что перед обновлением своего репозитория можно посмотреть все изменения, которые «пришли» к вам.

Ниже есть описание команды push, но сейчас нам нужно передать изменения в origin, чтобы наглядно показать как работает fetch:

Теперь от имени dev2 посмотрим, что есть и получим все изменения:

Выглядит это так:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Обратите внимание, что мы находимся в master.
Что можно сделать:
git checkout origin/master — переключиться на удалённый master, чтобы «пощупать» его. При этом нельзя эту ветку редактировать, но можно создать свою локальную и работать с ней.
git merge origin/master — объединить новые изменения со своими. Т.к. у нас локальных изменений не было, то merge превратится в fast-forward:

git pull

В 95% случаев, вам не нужно менять это поведение.

git push

На все вопросы может ответить расширенный вариант использования команды:
git push origin :
Примеры:

Включаемся в проект

К этому моменту уже более-менее понятно, как работает push, pull. Более смутно представляется в чём разница между merge и rebase. Совсем непонятно зачем это нужно и как применять.
Когда кого-нибудь спрашивают:
— Зачем нужна система контроля версий?
Чаще всего в ответе можно услышать:
— Эта система помогает хранить все изменения в проекте, чтобы ничего не потерялось и всегда можно было «откатиться назад».

А теперь задайте себе вопрос: «как часто приходится откатываться назад?» Часто ли вам нужно хранить больше, чем последнее состояние проекта? Честный ответ будет: «очень редко». Я этот вопрос поднимаю, чтобы выделить гораздо более важную роль системы контроля версий в проекте:

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

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

Используете %VCS_NAME%? Удобно? Не ограничивает процесс разработки и легко адаптируется под требования? Быстро? Значит эта %VCS_NAME% подходит для вашего проекта лучше всего. Пожалуй, вам не нужно ничего менять.

Типичные сценарии при работе над проектом

Чтобы добиться такого процесса, нужно чётко определиться где и что будет хранится. Т.к. ветки легковесные (т.е. не тратят ресурсов, места и т.д.) под все задачи можно создать отдельные ветки. Это является хорошей практикой. Такой подход даёт возможность легко оперировать наборами изменений, включать их в различные ветки или полностью исключать неудачные варианты.

Исправление багов

Создадим ветку dev и рассмотрим типичный сценарий исправления багов.

И второй разработчик «забирает» новую ветку к себе:

Пусть 2 разработчика ведут работу каждый над своим багом и делают несколько коммитов (пусть вас не смущает, что я таким некрасивым способом генерирую множество случайных коммитов):

Когда работа закончена, передаём изменения в репозиторий. Dev1:

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

Посмотрим на результат:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Теперь, всё как положено: наши изменения в dev и готовы быть переданы в origin.
Передаём:

Нам откроется редактор и даст возможность исправить нашу историю, например, поменять порядок коммитов или объединить несколько. Об этом писалось выше. Я оставлю как есть:

После того как все конфликты решены, история будет линейной и логичной. Для наглядности я поменял комментарии (интерактивный rebase даёт эту возможность):
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Теперь наша ветка продолжает origin/dev и мы можешь отдать наши изменения: актуальные, адаптированные под новые коммиты:

Далее история повторяется. Для удобства или в случае работы над несколькими багами, как говорилось выше, удобно перед началом работы создать отдельные ветки из dev или origin/dev.

Feature branch

Бывает так, что нужно сделать какой-то большой кусок работы, который не должен попадать в основную версию пока не будет закончен. Над такими ветками могут работать несколько разработчиков. Очень серьёзный и объёмный баг может рассматриваться с точки зрения процесса работы в git как фича — отдельная ветка, над которой работают несколько человек. Сам же процесс точно такой же как и при обычном исправлении багов. Только работа идёт не с dev, а с feature/name веткой.
Вообще, такие ветки могут быть коротко-живущими (1-2 неделя) и долго-живущими (месяц и более). Разумеется, чем дольше живёт ветка, тем чаще её нужно обновлять, «подтягивая» в неё изменения из основной ветки. Чем больше ветка, тем, вероятно, больше будет накладных расходов по её сопровождению.

Начнём с коротко-живущих (short-live feature branches)

Обычно ветка создаётся с самого последнего кода, в нашем случае с ветки dev:

Теперь работу на feature1 можно вести в ветке feature/feature1. Спустя некоторое время в нашей ветке будет много коммитов, и работа над feature1 будет закончена. При этом в dev тоже будет много изменений. И наша задача отдать наши изменения в dev.
Выглядеть это будет приблизительно так:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Ситуация напоминает предыдущую: две ветки, одну нужно объединить с другой и передать в репозиторий. Единственное отличие, это две публичные (удалённые) ветки, а не локальные. Это требует небольшой коммуникации. Когда работа закончена, один разработчик должен предупредить другого, что он собирается «слить» изменения в dev и, например, удалить ветку. Таким образом передавать в эту ветку что-либо будет бессмысленно.
А дальше алгоритм почти такой как и был:

Картинка, feature1 стала частью dev, то что на и нужно было:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Делаем push и чистим за собой ненужное:

Долго-живущие ветки (long-live feature branches)

Сложность долго-живущих веток в их поддержке и актуализации. Если делать всё как описано выше то, вероятно быть беде: время идёт, основная ветка меняется, проект меняется, а ваша фича основана на очень старом варианте. Когда настанет время выпустить фичу, она будет настолько выбиваться из проекта, что объединение может быть очень тяжёлым или, даже, невозможным. Именно поэтому, ветку нужно обновлять. Раз dev уходит вперёд, то мы будем просто время от времени перестраивать нашу ветку на dev.

Всё бы хорошо, но только нельзя просто так взять и перестроить публичную ветку: ветка после ребэйза — это уже новый набор коммитов, совершенно другая история. Она не продолжает то, что уже было. Git не примет такие изменения: два разных пути, нет fast-forward’а. Чтобы переписать историю разработчикам нужно договориться.
Кто-то будет переписывать историю и принудительно выкладывать новый вариант, а в этот момент остальные не должны передавать свои изменения в текущую ветку, т.к. она будет перезаписана и всё пропадёт. Когда первый разработчик закончит, все остальные перенесут свои коммиты, которые они успеют сделать во время переписи уже на новую ветку. Кто говорил, что нельзя ребэйзить публичные ветки?

Приступим к практике:

Второй разработчик подключается к работе всё стандартно:

Добавим ещё несколько коммитов в основную ветку dev и история будет такая:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

Настало время актуализировать feature/long, но при этом разработка должна продолжиться отдельно. Пусть перестраивать будет dev1. Тогда он предупреждает dev2 об этом и начинает:

В это время dev2 продолжает работать, но знает, что ему нельзя делать push, т.к. нужной ветки ещё нет (а текущая будет удалена).
Первый заканчивает rebase и история будет такой:
Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Ветка перестроена, а origin/feature/long остался там, где и был. Цели мы достигли, теперь нужно поделиться со всеми:

Git лишний раз напоминает, что что-то не так. Но теперь, мы точно знаем, что мы делаем, и знаем, что так надо:

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

Посмотрим, как эти изменения отразились на окружающих и на dev2 в частности:

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name

N, чтобы указать на предыдущий N-ый коммит.
HEAD

1 — это предыдущий, а HEAD

2 — это предпредыдущий. HEAD

5 — 5 коммитов назад. Удобно, чтобы не запоминать id.

Посмотрим, как теперь нам перестроить только один коммит:

1

Если бы нам надо было перетянуть 4 коммита, то было бы feature/long

Что такое branch name. Смотреть фото Что такое branch name. Смотреть картинку Что такое branch name. Картинка про Что такое branch name. Фото Что такое branch name
Осталось продолжить работу.

Hotfixes

Hotfixы нужны, т.к. бывают очень критичные баги, которые нужно исправить как можно быстрее. При этом нельзя передать вместе с hotfix-ом последний код, т.к. он не оттестирован и на полное тестирование нет времени. Нужно только это исправление, максимально быстро и оттестированное. Чтобы это сделать, достаточно взять последний релиз, который был отправлен на продакшен. Это тот, где у вас остался tag или master. Тэги играют очень важную роль, помогая понять что именно было собрано и куда это попало.
Тэги делаются командой

Всякие полезности

Git позволяет настраивать aliasы для различных команд. Это бывает очень удобно и сокращает время набора команд. Приводить здесь примеры не буду, в Интернете их полно, просто поищите.

Перед тем, как отдавать свои изменения их можно перестроить на самих себя, чтобы привести историю в порядок.
Например, в логах может быть такое:

Перестроим сами себя, но начиная с 6 коммитов назад:

Теперь в интерактивном режиме можно объединить (squash) первые два коммита в один и последние четыре. Тогда история будет выглядеть так:

Такое намного приятнее передавать в общим репозиторий.

Выводы

Причемания и апдейты

gcc рекомендовал посмотреть на Git Extensions.
borNfree подсказал ещё один GUI клиент Source Tree.
zloylos поделился ссылкой на визуализатор для git
olancheg предложил посмотреть на ещё один туториал для новичков.

PS. Что тут обычно пишут, когда первый пост на хабре? Прошу не судить строго, писал как мог.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *