Когда следует использовать git pull --rebase?

Я знаю некоторых людей, которые используют git pull --rebase по умолчанию, и другие, которые настаивают, чтобы никогда не использовать его. Я считаю, что я понимаю разницу между слиянием и перезагрузкой, но я пытаюсь поставить это в контексте git pull. Является ли это не желанием видеть много сообщений об объединении с фиксацией или есть другие проблемы?

Ответ 1

Вы должны использовать git pull --rebase, когда

  • ваши изменения не заслуживают отдельной ветки

В самом деле - почему бы и нет? Это более понятно и не накладывает логическую группировку на ваши коммиты.


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

Однако иногда - по любой причине - вы думаете, что было бы лучше, если бы эти две - удаленные и локальные - были одной ветвью. Как в SVN. Именно здесь вступает в игру git pull --rebase. Вы больше не сливаетесь - вы фактически совершаете поверх удаленной ветки. Это то, что на самом деле происходит.

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

Ответ 2

Я хотел бы представить другую точку зрения на то, что "git pull -rebase" на самом деле означает, потому что иногда кажется, что он теряется.

Если вы когда-либо использовали subversion (или CVS), вы можете использовать поведение "svn update". Если у вас есть изменения в фиксации, и коммит завершился неудачно, потому что изменения были сделаны вверх по потоку, вы обновляете "svn update". Subversion исходит из слияния восходящих изменений с вашими, что может привести к конфликтам.

Какая подрывная деятельность только что сделала, по существу была "pull -rebase". Акт повторной формулировки ваших локальных изменений будет относиться к более новой версии - это "перезаряжающая" часть. Если вы выполнили "svn diff" до неудачной попытки совершения транзакции и впоследствии сравниваете полученный diff с выходом "svn diff", разница между этими двумя различиями - это то, что сделала операция перезаписи.

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

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

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

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

Ответ 3

Я думаю, вы должны использовать git pull --rebase при взаимодействии с другими в той же ветке. Вы находитесь в своей работе → commit- > work- > commit cycle, и когда вы решаете нажать свою работу, ваш push-код отклоняется, потому что параллельно была одна работа над той же ветвью. В этот момент я всегда делаю тягу - ребазу. Я не использую squash (чтобы сгладить коммиты), но я переустанавливаю, чтобы избежать дополнительных компромиссов.

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

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

--- Изменить: (*) Преподавая курс git, у меня был студент, арестовавший меня по этому поводу, так как я также выступал за переделку ветвей функций в определенных обстоятельствах. И он прочитал этот ответ;) Такая перезагрузка также возможна, но всегда должна быть в соответствии с заранее подготовленной/согласованной системой и как таковая не должна "всегда" применяться. И в то время я обычно не делаю притяжения - тоже делаю это, о чем идет речь;)

Ответ 4

Возможно, лучший способ объяснить это с помощью примера:

  • Алиса создает ветку темы A и работает над ней
  • Боб создает не связанную ветку темы B и работает над ней
  • Алиса делает git checkout master && git pull. Мастер уже обновлен.
  • Боб делает git checkout master && git pull. Мастер уже обновлен.
  • Алиса делает git merge topic-branch-A
  • Боб делает git merge topic-branch-B
  • Боб делает git push origin master до Алисы
  • Алиса делает git push origin master, которая отвергается, потому что это не ускоренное слияние.
  • Алиса смотрит журнал происхождения/мастера и видит, что фиксация не связана с ней.
  • Алиса делает git pull --rebase origin master
  • Алис слияния фиксации разматывается, Боб-фиксация вытягивается, а фиксация Алиса применяется после фиксации Боба.
  • Алиса делает git push origin master, и все счастливы, что им не нужно читать бесполезное коммандное слияние, когда они смотрят на журналы в будущем.

Обратите внимание, что конкретная ветвь, объединенная в нее, не имеет отношения к этому примеру. Мастером в этом примере может быть так же легко, как ветвь релиза или ветвь dev. Ключевым моментом является то, что Алиса и Боб одновременно объединяют свои локальные ветки в общую удаленную ветвь.

Ответ 5

Я не думаю, что когда-либо была причина не использовать pull --rebase - я добавил код в git специально, чтобы моя команда git pull всегда перегружалась против коммитов верхнего уровня.

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

Ответ 6

Просто помните:

  • pull = выборка + слияние
  • pull --rebase = fetch + rebase

Итак, выберите способ, которым вы хотите управлять своей веткой.

Вам лучше знать разницу между слиянием и rebase:)

Ответ 7

Я думаю, это сводится к личным предпочтениям.

Вы хотите скрыть свои глупые ошибки, прежде чем нажимать на свои изменения? если это так, git pull --rebase совершенен, он позволяет вам позже выкачать ваши коммиты до нескольких (или одного) фиксации. Если у вас есть слияния в вашей (нераскрытой) истории, сделать git rebase позже не так просто.

Я лично не против публикации всех моих глупых ошибок, поэтому я склонен сливаться, а не перебазировать.

Ответ 8

git pull --rebase может скрывать переписывание истории из коллаборатора git push --force. Я рекомендую использовать git pull --rebase только, если вы знаете, что забыли перетащить свои коммиты, прежде чем кто-то другой сделает то же самое.

Если вы ничего не совершили, но ваше рабочее пространство не чистое, просто git stash до git pull. Таким образом, вы не будете автоматически переписывать свою историю (которая могла бы тихо отбросить часть вашей работы).