2009-02-18 2 views
68

У меня есть филиал, который должен быть доступен другим участникам и который должен постоянно оставаться в курсе работы мастера.git rebase и git push: non-fast forward, зачем использовать?

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

ответ

99

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

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

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 в примере выше).


Shared Repo Модель

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

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

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

Когда другой разработчик пытается подтолкнуть, он получает " non-fast forward ". Когда он делает слияние, то обе истории являются Relinked вместе, и вы в конечном итоге с беспорядке

Что-то вроде этого (грязный):

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, или ИЗБЕГАЙТЕ ПОМОЩЬ до тех пор, пока не будет восстановлена ​​(и только перезарядите свою работу).


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

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

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

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

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


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

+7

Err, на самом деле, слияние создает слияния, недостающие уточняют ненужные. Вместо этого полезно «git fetch, git rebase origin/master», разрешить все локальные конфликты с главной (централизованной) ветвью, а затем нажимать чистые коммиты, которые только продвигаются вперед. 'git pull --rebase' имеет аналогичный рабочий процесс. Это мощный вариант, но вы должны быть осторожны с ним, так как перезарядка неправильных вещей может переписать фиксации, которые уже находятся в оригинале/мастер. Например. не переустанавливайте другие ветви, если они не были сначала перепутаны с текущим начальником/мастером. – Kzqai

+0

Согласитесь, следует избегать фиксации слияния при выполнении git pull. Тем не менее, я считаю, что они хороши, когда умышленно объединяют ветвь функций в мастер. – ndbroadbent

+3

Мне нравится объяснение, почему возникает проблема, нажав на переустановленную ветку. Но я не уверен, что происходит --mirror. Чтение описания - «указывает, что * все refs * будут зеркалированы» - беспокоит меня. Я не хочу, чтобы все refs * зеркалировались, только одна ветка. :) Будет ли именовать ветку только зеркально? Мне это не понятно из git docs. –

2

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