git rebase и git push: без быстрой перемотки вперед, зачем использовать? - PullRequest
68 голосов
/ 18 февраля 2009

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

К сожалению, каждый раз, когда я делаю «git rebase», а затем пытаюсь нажать, это приводит к сообщению «не ускоренная перемотка» и прерывание нажатия. Единственный способ нажать здесь - это использовать --force. Означает ли это, что я должен использовать «git merge» вместо ребазинга, если моя ветка стала общедоступной, а другие работают над ней?

Ответы [ 2 ]

100 голосов
/ 18 февраля 2009

Несколько замечаний о том, как работает git (не технический):

Когда вы перебазируете, git берет соответствующие коммиты и «рекомендует» их поверх чистой истории. Это должно предотвратить отображение истории:

Description: tree -> mywork -> merge -> mywork -> merge -> mywork -> merge
Commit SHA1: aaaa -> bbbb   -> cccc  -> dddd   -> eeee  -> ffff   -> gggg

После ребазирования это может выглядеть примерно так (или аналогично):

Description: tree -> rebase
Commit SHA1: aaaa -> hhhh

Проблема в том, что новый коммит, который вы пытаетесь вытолкнуть, НЕ является потомком коммита на кончике ветви, в которую вы толкаете.

Теперь вы знаете, что та же информация есть в коммитах, но git несет ответственность, не просто перезаписывая эти коммиты там (bbbb-gggg в примере выше).


Модель общего репо

Если вы используете общий репозиторий, то подобные вещи могут сильно запутать. Позвольте мне объяснить, почему. Скажем, другой разработчик развернул ветку, и у него есть коммиты aaaa -> gggg в их ветке. Затем они совершают коммит iiii

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

Description: tree -> rebase
Commit SHA1: aaaa -> hhhh

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

Примерно так (грязно):

Description: tree -> rebase -> mywork -> merge -> mywork -> merge -> mywork -> merge -> devwork -> merge 
Commit SHA1: aaaa -> hhhh   -> bbbb   -> cccc  -> dddd   -> eeee  -> ffff   -> gggg -> iiii    -> jjjj

Другими словами, если другие тянут и толкают, лучше придерживаться git merge или ИЗБЕГАТЬ НАЖАТИЯ до тех пор, пока не произойдет перебазирование (и только перебазирование вашей работы).


Модель общедоступного хранилища

Возможно, вы используете другую (более абсурдную) модель, где вы просто хотите, чтобы люди могли вытащить из вашего репо. В этом случае git push --force не так уж и плох, потому что тогда они могут справиться с этим. Они могут перебазировать своих изменений , чтобы быть в числе ваших изменений, прежде чем давать вам свои патчи. Он не позволяет вашему репо все испортить.

Однако, может быть для вас есть лучший способ. git push --mirror

С http://www.kernel.org/pub/software/scm/git/docs/git-push.html

Вместо того, чтобы называть каждую ссылку нажатием, указывает, что все ссылки под $ GIT_DIR / refs / (включая, но есть не ограничиваясь ссылками / руководителями /, refs / remotes / и refs / tags /) быть отражается в удаленном хранилище. Вновь созданные местные рефери будут подтолкнуть к удаленному концу, локально обновленные ссылки будут принудительно обновляться на удаленный конец, и удаленные ссылки будут быть удаленным с удаленного конца. это по умолчанию, если конфигурация опция remote..mirror установлена.


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

2 голосов
/ 11 января 2013

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

...