git rebase и git push: без быстрой перемотки вперед, зачем использовать?
У меня есть ветка, которая должна быть доступна другим участникам, и которая должна постоянно оставаться в курсе с мастером.
К сожалению, каждый раз, когда я делаю "git rebase" и затем пытаюсь нажать, это приводит к сообщению "не-перемотка вперед" и прерыванию нажатия. Единственный способ нажать здесь - это использовать --force. Означает ли это, что я должен использовать "git merge" вместо ребазинга, если моя ветка стала общедоступной, а другие работают над ней?
2 ответа
Несколько замечаний о том, как работает 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 или ИЗБЕЖАТЬ PUSHING до тех пор, пока не произойдет повторная загрузка (и только повторная проверка вашей работы).
Модель публично видимого репозитория
Возможно, вы используете другую (более абсурдную) модель, в которой вы просто хотите, чтобы люди могли извлечь из вашего репо. В этом случае, git push --force не так уж и плох, потому что тогда они могут справиться с этим. Они могут отменить свои изменения, чтобы быть в числе ваших изменений, прежде чем давать вам свои патчи. Это мешает вашему репо все испортить.
Тем не менее, может быть лучший способ для вас. git push --mirror
http://www.kernel.org/pub/software/scm/git/docs/git-push.html
Вместо того, чтобы называть каждую ссылку push, указывает, что все ссылки в $GIT_DIR/refs/ (которые включают в себя, но не ограничиваются ссылками refs/heads, refs / remotes / и refs/tags/), будут отражены в удаленном репозитории. Вновь созданные локальные ссылки будут отправлены на удаленный конец, локально обновленные ссылки будут принудительно обновлены на удаленном конце, а удаленные ссылки будут удалены с удаленного конца. Это значение по умолчанию, если задан параметр конфигурации remote..mirror.
Одним из замечательных преимуществ git является то, что он очень гибкий и допускает множество различных видов рабочих процессов. Но его реальная сила заключается в том, что это распределенная модель, поэтому я считаю, что с ее помощью можно получить наибольшую отдачу от инвестиций.
Нет, перебазирование совершенно законно с публичными репозиториями и может быть даже желательно, чтобы история оставалась свободной. Просто помните, что вы не должны использовать rebase, чтобы переписать историю удаленно опубликованных коммитов. То есть ребаз может быть применен только к вашим собственным локальным коммитам, которые вы никогда не публиковали. Вы используете rebase, чтобы поместить свои коммиты поверх них при получении, а затем, возможно, скорректировать их там. Другая причина, по которой вы можете получить такое сообщение, заключается в том, что ветка, которую вы нажимаете, была обновлена, и вам нужно синхронизировать - извлекать и повторно передавать ваши коммиты поверх того, что вы получили.