Pull to refresh
7
0
Andriell @Andriell

Программист

Send message
Вот пример yadi.sk/d/Ef3Lwqjg3Qcdug Там все как в том примере о котором я говорю.
Не забывайте перезаписывать папку .git и файл 1.txt на те, что в архиве перед тем, как попробовать очередной вариант мержа или ребейза.
То есть вы хотите сказать, что нет разницы между git checkout A; git merge B и git checkout B; git merge A?

Нет, я хочу сказать не это. Есть разница что куда мержить. Я хочу сказать что в обоих случаях при мерже код не сломается. В отличии от ребейза.

Этот пример никак не доказывает, что это происходит чаще, чем обратное.

Тогда приведите хоть один такой пример. Я вас уже третий раз прошу это сделать. Вы же, наверное, понимаете, что мердж не меняет последовательности коммитов, а ребейз делает это и поэтому от него код может сломаться. Как же вы можите утверждать при этом что мердж и мердж коммиты ломают код так же часто как и ребейзы? Ребейз это вообще говоря не типичная операция git'а и злоупотреблять ей не стоит.
Вас не смущает, что это бессмысленная последовательность? После git rebase B у вас в A уже есть все коммиты из B, зачем делать git merge B?

Даже если этот мердж не делать, то код все равно сломается. Это ничего не меняет.

… а почему?

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

Да, может. Но это происходит не чаще, чем при мерже.

Я вам только что привел пример как мердж не ломает код, а ребейз ломает.
Тривиально же: был публичный класс A. В одной ветке добавили новый класс B: A. В другой ветке класс A переименовали в C. Конфликта при мерже не будет (откуда бы?). Но код компилироваться не будет.

При ребейзе код сломается точно так же. Я не причин не использовать merge commit, а все ребейзить.

Я, кстати, не нашел у вас примера, как может сломаться код (исключительно) при ребейзе.

Имеем вот такую схему
| * 4cea0a2 (B) B2
| * 42e644d B1
* | 4901c2c A2
|/
* ba68671 A1
* 95d2b42 A1


Делаем вот так

git checkout A
git rebace B
git merge B

Получаем цепочку коммитов A1-A1-B1-B2-A2, но в коде есть ошибки. На одной строке оказалось две строчки кода. Если бы мы сделали мердж, то добавился бы мердж коммит и ошибок бы не было.

Если сделать вот так

git checkout B
git rebace A
git checkout A
git merge B


то получится другая цепочка коммитов A1-A1-A2-B1-B2 и в ней не будет такой ошибки в коде.

Кстати говоря, я тоже не вижу у вас примеров, когда ребейзы бы работали правильно, а мердж отработал бы неправильно. Хотя выше уже просил привести такой пример. И вы постоянно говорите о том, что в merge commit могут быть ошибки. А я говорю, что они тогда и в ребейзе были бы.

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

Да, я знаю об этом. Имелось в виду что отличие в том, что merge commit либо проходит автоматически и не ломает код, либо переходит в ручной режим. А ребейз может пройти автоматически и сломать код при этом.
Гит ничего не знает про семантические конфликты. Поэтому автоматический мерж-коммит, сделанный гитом, прекрасно может давать неработающий код.

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

Сколько мерж-коммитов будет в feature/x?
А это именно предлагаемая вами схема.
Один. Разве в этом есть что-то плохое?
Это ничем не отличается от «ошибся и запушил ошибку в фичеветку». Как, собственно, и все ваши рассуждения дальше.

Разница в том, что другие программисты работают в других ветках и если один из программистов запушит недописанный код в свою ветку задачи, этот код другим программистам никак не помешает. Они смогут делать и push/pull запросы, когда захотят и не будут мешать друг другу. А если они будут работать в одной ветке и начнут делать push и pull, то у них как раз начнут появляться лишние merge commit’ы, конфликты и т.п.

А это вы, простите, откуда взяли? Я нигде не говорил, как должны работать другие.

Выше вы говорили, что если другие программисты в вашей команде будут работать с merge commit, то сами вы не сможете работать нормально. Ведь merge commit'ы чем-то мешают. Мне кажется я понял в чем дело. Дело в том, что вы постоянно делаете ребейзы и путаетесь в каком направлении их делать. Поэтому некоторые ребейзы вызывают ошибки, как у меня в примере выше. И вам надо перемещать отдельные коммиты что бы их не было. Если делать обычный мердж, то такого не происходит вообще. Строки не меняются местами на одной строке не оказывается две разные строки кода.
Внимание, вопрос: чем ситуация «каждый сидит в feature/x и мержится с origin/feature/x» хуже ситуации «каждый сидит в feature/x-devname и мержится с origin/feature/x»?

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

Совершенно не обязательно. Могло не быть конфликта (с точки зрения гита), а код сломался. Есть много способов этого достичь.

Приведите пример, когда такое происходит, когда каждый программист работает в ветке задачи, и не происходит при том способе, который описываете вы.

которые не хотят писать нормальные коммит-сообщения?

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

Когда вы делаете merge, указатель «другой» ветки не двигается на мерж-коммит (и это очень правильно). Собственно, поэтому утверждение «ветка заканчивается мерж-коммитом» неверно не иногда, а практически всегда.

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

Я не понял, чего вы хотите и почему вот такая схема вас не устраивает. По-моему, все так как надо.

* 90d6bbe (A) Merge branch 'B' into A
|\
| * 4cea0a2 (B) B2
| * 42e644d B1
* | 4901c2c A2
|/
* ba68671 A1
* 95d2b42 A1


Вы все время пишите, что хотите чего-то, а получается все не так как вы хотите. При этом вы описываете нормальное поведение Git, а чего вы хотите вообще не понятно. Делайте так как написано в этой статье и у вас все будет получаться. По-моему, вы как раз из той категории людей которая прочитала книгу Pro Git, но не поняла, что с этим делать.
Если вам и правда так сильно не нравятся merge commit’ы, то вы могли бы сделать вот так.

git checkout A
git pull
git rebace B
git merge B


И тогда бы у вас все коммиты выстроились бы в одну линию.
A1-A1-B1-B2-A2
Будто бы они были сделаны в одной ветке. (При этому в одном из файлов коммиты у меня заребейзились не правильно.)
Если вам нужно что бы было
A1-A1-A2-B1-B2
То нужно сделать вот так

git checkout A
git pull
git checkout B
git pull
git rebace A
git checkout A
git merge B


Работая по такой схеме вы видимо вообще сможите обойтись без merge commt’ов. Но это ни, чем не лучше.

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

Имхо, вы просто не разобрались с тем как работает git занимаетесь каким-то непотребством, и у вас поэтому что-то не получается, вы хотите, чтобы остальные работали как-то определенно, иначе у вас что-то не будет получаться еще больше и т.п.
Например, pull --ff-only и pull --rebase вместо обычного pull. Радикально уменьшает число мерж-коммитов при совместной работе в одной ветке.

Работать нескольким программистам в одной ветке как-то не правильно. Ни в одной из предложенных мною схем такого не происходит. Ветки как раз и были созданы для того, что бы программисты могли работать совместно и не мешать друг другу.
… а в этом коммите был мерж. В этот момент все и взрывается.

Такое может быть только если этот мерж имел конфликт и этот конфликт не правильно разрешили в ручную. Если делать git rebase, то все было бы точно так же. В этой ситуации там тоже возник бы конфликт, и его нужно было бы решать вручную, и его могли бы не правильно решить. Если конфликт разрешили не правильно и ошибка в мердж коммите, то нужно действовать точно так же как я описал выше. Это ничего не меняет.
Вам не надо, мне надо.

Вам не мешают, мне мешают.

По-моему вы сами себе жизнь усложняете. Представим ситуацию когда вы работаете в одной команде с теми кто делает мерж через git merge, а не через git rebace; git merge. Такие парни вам будут мешать (хотя я по прежнему не понимаю чем), а вы им ни чуть. Вам придется хейтить их и убеждать, что нужно делать так, как вы иначе вы сами не сможете нормально работать.

Вы вот знаете (именно из головы, без справочника), как увидеть список коммитов только в вашей ветке, если в нее был сделан мерж? Т.е., A -> A1 -> A2 -> A3 -> (merge) -> A4 -> B?

А зачем? Это же тоже коммит и он должен быть в истории. К тому же в конце ветки они говорят о том, что этим коммитом ветка завершилась. По моему очень наглядно и полезно.
Почему это «лучше не делать»? Вам никогда не надо разбираться, какое изменение все сломало или починило? Переносить фиксы между версиями?

Да, иногда если сразу не понятно по коду из-за чего что-то сломалось, то мне приходилось искать тот коммит который что-то сломал. Для этого вначале делается тест с помощью которого можно найти ту самую поломку. Или тест не делатся, а поломка проверяется в ручную. Потом код откатывается на прошлое состояние в котором все работало запускается тест. Дальше методом деления отрезка пополам находится тот коммит который все испортил. Смотрим что было в этом коммите. Дальше это фиксится с помощью нового коммита. Все просто. Переносить фиксы между версиями не надо. merge commit-ы абсолютно ничем не мешают. Фиксы не теряются, по новой их применять не надо. Вообще обычно до поисков конкретного коммита не доходит дело, обычно и так понятно в чем причина поломки.
Про git commit, ёМоё… там было написано. git init и git clone добавил для хронологии.
Ты говоришь что нужен git reset. Неужели тебе так часто приходиться что-то отменять? Переключиться на предыдущее состояние можно при помощи git checkout
… пока вам не надо ветку разбирать, ребейзить, черрипикать и так далее.
Это наверное лучше вообще не делать.
Но можно радикально уменьшить их число.
Что ты предлагаешь для этого сделать?
Пойнт-то как раз в том, что надо понимать, откуда и зачем берутся мерж-коммиты, как их получить и как их избежать.
Вообще ничего плохого в merge commit нету. При работе в команде их не избежать. Но ты мне напомнил про одну важную вещь о которой стоит написать более явно.
Если ты работаешь в команде один, и делаешь задачи последовательно, то такое у тебя получается постоянно. У меня такое бывает очень редко.
Дело не в том как часто это происходит а в том, что это можно было и не описывать в этой статье, для понимания что такое git merge первой схемы было достаточно.
Если описать все что есть в git, то получиться еще одна книга Pro Git, в которой очень много информации и вопрос, а что с этим со всем делать остается открытым после ее прочтения.
Вот именно что отдельным разделом. Если следовать вашей логике, то в официальной документации тоже есть ошибки раз они в той же главе не написали что может быть и по другом. А что по мне, так именно в этой статье рассматривать другие варианты воде fast-forward merge было не обязательно.
Ошибки нету. В официальной документации написано про merge commit так же как и у меня. Другое дело, что есть исключительная ситуация в которой можно обойтись и без merge commit. Вы так хотите что бы эта ситуация была описана в этой статье. Давайте ее опишем.
Это в общем-то тоже не мердж, а перемещение… Которое, наверное, лучше не делать без острой на то необходимости.
У тебя так получилось потому, что ты не сделал коммиты в мастер ветке между тем как начал от нее новую ветку и тем как смержил ее обратно. Гиту было нечего мержить и потому он просто перенес коммиты в мастер ветку. По сути дела это даже не мердж веток, а перенос коммитов.
Такое может происходить часто только если ты работаешь в команде один и выполняешь задачи последовательно по одной за раз. В таком случаи вообще нет особого смысла создавать ветки под задачи, можно просто делать коммиты в мастер ветку.
Он вроде как обязателен
https://git-scm.com/docs/git-merge
Там написано
...and record the result in a new commit along with the names of the two parent commits and a log message from the user describing the changes…

Ты наверное что-то путаешь и думаешь что merge commit создается только если были конфликты.
Merge commit можно в логе увидеть. Затем выполнить
git cat-file -p <hach>

И увидеть, что у этого коммита два parent и одно tree
1

Information

Rating
Does not participate
Location
Воронеж, Воронежская обл., Россия
Date of birth
Registered
Activity