Когда я должен использовать git pull --rebase? - PullRequest
723 голосов
/ 18 марта 2010

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

Ответы [ 8 ]

689 голосов
/ 13 января 2011

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

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

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

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

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

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

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

522 голосов
/ 18 марта 2010

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

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

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


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

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

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

161 голосов
/ 12 февраля 2015

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

  1. Алиса создает ветку темы A и работает над ней
  2. Боб создает несвязанную ветку темы B и работает над ней
  3. Алиса делает git checkout master && git pull. Мастер уже в курсе.
  4. Боб делает git checkout master && git pull. Мастер уже в курсе.
  5. Алиса делает git merge topic-branch-A
  6. Боб делает git merge topic-branch-B
  7. Боб делает git push origin master перед Алисой
  8. Алиса делает git push origin master, что отклонено, поскольку это не ускоренное слияние.
  9. Алиса смотрит на журнал источника / мастера и видит, что коммит не связан с ее.
  10. Алиса делает git pull --rebase origin master
  11. Фиксация слияния Алисы отменяется, фиксация Боба отменяется, а фиксация Алисы применяется после фиксации Боба.
  12. Алиса делает git push origin master, и все рады, что им не нужно читать бесполезный коммит слияния, когда они просматривают журналы в будущем.

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

139 голосов
/ 18 марта 2010

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

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

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

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

47 голосов
/ 19 марта 2010

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

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

26 голосов
/ 08 июля 2017

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

  • pull = fetch + merge
  • pull --rebase = fetch + rebase

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

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

7 голосов
/ 18 марта 2010

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

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

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

5 голосов
/ 19 июня 2017

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...