Как объяснить "git pull --rebase" простыми словами?

Я думаю, что понял git pull и вот как я это объясняю, что я называю "простыми терминами":

  1. Вообще говоря, git pull о слиянии "удаленной" ветви с "локальной" веткой.
  2. Более подробно, git использует содержимое "удаленной" ветви для "обновления" / "изменения" содержимого "локальной" ветви.
  3. Более подробно, если файл был изменен в "локальной" ветви, но не в "удаленной" ветви, то после слияния содержимое файла будет таким же, как содержимое в "локальной" ветви. Обратное тоже верно. Если файл был изменен в "удаленной" ветви, но не в "локальной" ветви, содержимое будет извлечено из "удаленной" ветви.
  4. Если файл был изменен в обеих ветвях ("локальных" и "удаленных"), то git попытается получить изменения из обеих веток. Если изменения происходят в разных местах файла, оба изменения будут применены и будут присутствовать в содержимом файла после слияния.
  5. Если изменения происходят в одном и том же месте, мы имеем то, что известно как "конфликт слияния", и я не буду касаться этого случая для простоты.
  6. В результате слияния мы модифицируем "локальный" репозиторий и, следовательно, нам необходимо "зафиксировать".

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

ADDED

Я думаю, что в какой-то момент я услышал следующее объяснение. От git pull --rebase, Когда мы объединяем, мы делаем это не "симметрично", как описано выше. Вместо этого мы сначала "забываем" об изменениях в "локальном" хранилище и применяем только изменения из "удаленного" хранилища. Делая это, мы в основном "копируем" удаленный репозиторий как есть. После этого мы применяем изменения из "локального" хранилища сверху. Однако мне все еще не ясно, что именно это означает. В частности, что означает "сверху".

2 ответа

Решение

Я вижу две вещи, которые можно уточнить: вы сосредотачиваетесь на состоянии файла в двух ветвях, но лучший способ рассмотреть происходящее с точки зрения произошедших изменений. Вторая проблема заключается в том, что git pull является сокращением для двух операций: git fetch, а также git merge, Да, ты пишешь, что "не хочешь использовать такие слова, как fetch", но это не" продвинутая концепция ". Если вы хотите понять, что происходит, вам нужно начать с этого.

  • git fetch по сути, сообщает местному репо об изменениях, о которых он не знал.

  • git merge объединяет вновь прибывшие изменения с вашими локальными изменениями.

Подвох в том, что если что-то происходило в обоих репозиториях без синхронизации, они могли расходиться:

... b--o--o--o--o  (remote)
     \
      x--x--x      (local)

Выше показано время слева направо; самая правая точка - самая последняя. Таким образом, вновь поступившие изменения являются модификациями более старого состояния файлов, помеченного буквой "b".

  • git pullт.е. простой git merge, объединит самое последнее состояние двух веток как можно лучше.

  • git pull --rebase будет делать вид, что ваши изменения были сделаны не в состоянии с пометкой "b", а в самом текущем удаленном состоянии. Другими словами, он попытается переписать историю так, чтобы это выглядело так:

    ... b--o--o--o--o              (remote)
                     \
                      x--x--x      (local)
    

В этом разница. Одним из следствий этого является то, что если вы не сделаете ребазинг, история вашего репо содержит несколько состояний (к которым вы можете вернуться в будущем, если хотите), где изменения "x" были применены, а изменения "o" отсутствуют. После ребазинга такого места в репозитории нет.

Просто: пока ваша работа является локальной (то есть она не была выдвинута), git pull --rebase будет служить для воспроизведения вашей локальной работы поверх обновленной истории.

git fetch обновит указанную историю последними коммитами удаленного репо (origin/master например).
Тогда ваша работа (ваши местные коммиты вашего master ветвь) будет воспроизводиться один за другим (что и делает перебазирование) поверх этой обновленной истории.

Идея состоит в том, что когда вы хотите нажать, указанный push будет очень простым и не потребует слияния, так как ваши коммиты - это просто новые коммиты, сделанные поверх origin/master,

Обратите внимание, что вы можете полностью скрыть эту часть, начиная с Git 2.6:

git config pull.rebase true
git config rebase.autoStash true

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

Другие вопросы по тегам