Ребята, есть тут одно очень интересное физическое объяснение работы с ветками в гите. Попытаюсь рассказать через несколько постулатов этой забавной теории.
1. Итак, с точки зрения переменной в коде не существует никакого гита, веток и коммитов. Есть только текущая кодовая база и соседи всяческие — переменные, классы, функции и прочее. Окружающая наблюдаемая реальность, так сказать. Каждый коммит в данном случае — изменение окружающего мира во времени.
2. Благодаря тому, что связь коммитов очень напоминает связный список, по истории можно двигаться строго вперед. И история выходит технически неизменяемая.
3. Два коммита, у которых один и тот же родительский коммит, оказываются в параллельных вселенных, где история пошла по-разному.
Стоит заметить очевидное, что ветки и имена веток — это всего лишь удобные динамические метки каких-то конкретных коммитов. Технически они добавляют немного удобства, чтобы можно было не запоминать хеш-сумму коммитов и именовать эти самые «параллельные вселенные» каким-то удобным словом.
4. Итак, у нас существуют параллельные вселенные и наша текущая файловая система умеет отображать содержимое одной из вселенных. С помощью команд гита можно увидеть всю историю той или иной вселенной и увидеть взаимосвязь между ними. С точки зрения переменной в файлике в одной из веток, нет никаких других веток, нет никакого «мастера». Есть только сквозная история от «git init
» до текущего момента.
И дальше самое интересное. Что такое «git rebase
»? Это такая попытка повторить исторические события одной вселенной в другой. Ну, вот родился некий мальчик Адольф в 1889 году и как-то взаимодействовал с объектами из его вселенной и времени. Если мы сделаем «git rebase --onto v2018 v1889 v1918
» то фактически мы попытаемся воспроизвести все события с 1889 года во вселенной 2018 года. Что, естественно приведет к конфликтам, которые нужно как-то решить. Ну, вот в 1889 году была у него мать Клара. В 2018 году той Клары, понятное дело, нет. И чтобы наш Адольф в 2018-м родился, необходимо выбрать другую мать, которая его родит. Или, согласно коммитам ветки v1889...v1918
наша переменная «Адольф» учавствовала в Первой мировой войне. И это тоже прийдется как-то решать программисту, инициировавшему ребейз на ветку 2018-го.
Фактически «git rebase
» — это попытка воспроизвести все коммиты старой ветки в новой реальности. И относиться к каждому коммиту нужно так, как будто бы это совершенно новые коммиты, которые делаются по образу и подобию старых. Некоторые коммиты будут просто лишены смысла — для этого есть «git rebase --skip
», некоторые коммиты будут выглядеть чуть менее, чем полностью другими. Не стесняйтесь использовать «git rebase --interactive
», чтобы переставить коммиты местами, если это необходимо, выбросить лишнее и сплющить несколько коммитов в один, если так будет казаться, что это новая целостная история, а не просто под копирку воспроизведенная старая. Все существа текущей реальности не должны даже подозревать, что существуют какие-то другие вселенные. Если кто-то найдет у себя под домом аномалию вроде «<<<<<<<
» и «>>>>>>>
», то это может стать причиной кучи бед в этой вселенной.
Что такое «git merge
»? А это, друзья, путешествия между параллельными вселенными. Когда результаты одной вселенной единовременно оказываются в другой. И, обратите внимание, это возможно только если между этими вселенными нет конфликтов. Если существует конфликт, скажем, в одной вселенной папы Адольфа не существовало и, следовательно, Адольф и не родился, а в другой его картина висела в спецхранилище американского правительства, то смержить одну ветку в другую система просто не позволит и путешествия между мирами не произойдет. Получится, так сказать, банальный мерж-конфликт.
И мне почему-то кажется, как-то так параллельные вселенные и работают. Да, чуть не забыл, все совпадения имен с историческими личностями и событиями случайны.