Нет, они совершенно разные.
Предполагая, что вы master
извлечены с чистым деревом, предложенный вами набор команд будет иметь эффект указания master
на один коммит, чьим родителем является выбранный восходящий поток, но чей контент имеет эффект замены нового вышестоящего дерева копией вашей предварительной выборки master
без объединения каких-либо вышестоящих изменений. (В частности, в окончательном варианте git merge remotes/origin/foo
всегда будет указано «Уже обновлено», и никогда не будет вноситься никаких изменений.)
Это потому, что команда:
git reset --soft remotes/origin/foo
устанавливает master
для указания remotes/origin/foo
без изменения текущего рабочего каталога (или индекса). Затем команда:
git commit -am "bar"
проверяет в единственном коммите (без изменений) дерево от вашего текущего мастера. Что касается Git, вы просто заново загрузили апстрим, а затем методично изменили его так, чтобы он выглядел точно так же, как ваш master
на основе более раннего апстрима, отменив все изменения, сделанные со времени вашего предыдущего пулла, а затем зарегистрировали его сверху вверх по течению. Поскольку этот коммит теперь является потомком восходящего потока, он уже считается объединенным, и:
git merge remotes/origin/foo
не будет иметь никакого эффекта.
В отличие, git pull --rebase
является эквивалентом
git fetch origin
git rebase remotes/origin/foo # or wherever you pull from
Это приводит к воспроизведению последовательности коммитов, которые были сделаны на master
с тех пор, как вы в последний раз вытягивали из восходящего потока вверх по ветке восходящего потока и указывали master
в результате.
Таким образом, он отличается от приведенных выше команд тем, что добавляет последовательность коммитов в восходящий поток вместо добавления одного коммита, и воспроизводит содержимое коммитов (что означает, что он пытается воспроизвести изменения, сделанные в этих коммитах) поверх восходящего потока, вместо замены восходящего потока старым содержимым master
и уничтожения вышестоящих изменений. В конце концов, master
является все еще потомком remotes/origin/foo
, поэтому работает:
git merge remotes/origin/foo
все равно ничего не будет делать, но это не должно ничего делать, потому что вновь извлеченные восходящие изменения будут включены в новую ветку master
.