Что именно происходит в git push? почему git push не рассматривается как слияние git?

Итак, как уже упоминалось, здесь, git pull просто загружает самые свежие и затем объединяет их. Разве это не то же самое для git push? т.е. с пульта ... вы берете локальный и объединяете его в ветку?

Или вы ничего не объединяете, а полностью переписываете историю коммитов ... игнорируя все, что там было, и просто заменяете списки коммитов более новыми?

(Я полностью знаю, когда использовать git push, т.е. я использую, когда я закончил с функцией в моем локальном. Я нажимаю на свое происхождение. Мой вопрос больше о том, что происходит под капотом)

Нажатие не перезаписывает историю на пульте дистанционного управления, если только ваша локальная ветвь не перезаписывает историю, и даже в этом случае, я думаю, вам нужно использовать флаг --force.

Abizern 10.08.2018 16:35

Push и pull являются семантически противоположными, но отнюдь не симметричными операциями в git. Вы ничего не переписываете, когда тянете или нажимаете (--force - еще одна тема), вы добавляете к существующему дереву. И на удаленном компьютере не происходит слияния. Предполагается, что слияния обрабатываются локально, потом помещается поверх удаленного дерева.

RomainValeri 10.08.2018 16:42

вот как я это вижу. Если master - 1-> 2-> 3 (количество коммитов), и я оформляю заказ на 'featureBranch' ... и делаю некоторые изменения и фиксирую, тогда история коммитов на моем 'featureBranch' составляет 1-> 2-> 3 -> 4. Поэтому я переписал историю коммитов. И когда я нажимаю это, разве удаленному не нужно знать об этой измененной истории? @Abizern

Honey 10.08.2018 16:42

Вы не переписываете историю. исходный 1-> 2-> 3 все еще там, вы только что добавили 4 поверх него. Это не переписывание истории, а добавление к ней.

Abizern 10.08.2018 16:44

Полностью переписать историю коммитов? Замена списков коммитов? Это приведет к поражению цели полностью. Вы должны рассказать это, чтобы испортить историю коммитов, и в общем, вам не нужно. Единственный распространенный случай, когда вы ошибаетесь с историей, - это когда вы раздавливаете материал перед тем, как отправить его, и даже тогда все может пойти очень не так.

Dave Newton 10.08.2018 16:45

ХОРОШО. Вы не переписываете историю. исходный 1-> 2-> 3 все еще там, вы только что добавили 4 поверх него. Разве это не то же самое с git merge, т.е. для обоих, которые вы добавляете в историю коммитов. Это корень моего замешательства @Abizern

Honey 10.08.2018 16:53
git push немного похож на слияние с быстрой перемоткой вперед. Если это настоящее слияние, оно будет отклонено и не удастся.
ElpieKay 10.08.2018 16:54

@ElpieKay, что за слияние с быстрой перемоткой вперед? Что такое настоящее слияние?

Honey 10.08.2018 16:55

@ Дорогой насчет быстрого и истинного слияния, git-scm.com/docs/git-merge#_fast_forward_merge

ElpieKay 10.08.2018 17:01

Подозреваю, что главная проблема здесь в именовании. Ближайшая противоположность git push - это нетgit pull, на самом деле это git fetch! Еще на заре Git они вложили слишком много вещей в сценарий pull, так что pull = fetch + merge. Но они не добавили дополнительный шаг в push, так что это полная противоположность выборке. (Другой VCS, Mercurial, избежал этой ошибки: его push и pull противоположны. Однако затем кто-то добавил на некоторое время hg fetch, который был pull + merge!)

torek 10.08.2018 17:17
0
10
1 267
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

git pullтянет последний коммит с удаленного на ваш локальный клиент.

git pushтолкает ваши последние локальные коммиты от локального клиента к удаленному.

Когда вы используете push, если в вашем локальном репозитории не все коммиты с пульта, push отклоняется, не объединен в удаленную ветку, как вы, кажется, думаете. В этом случае вы должны сначала pull последние изменения пульта и либо merge, либо rebase ваши локальные изменения. Теперь ваш локальный репозиторий опережает удаленный, и вы можете перейти к push.

В особом случае, когда локальная и удаленная истории совпадают, вы можете рассматривать push как симметрично противоположный pull, то есть удаленный "вытягивает" изменения из локального, и в этом случае вы правы. Стратегия слияния была бы эквивалентна pull, вносящему новые изменения удаленно (в частности, стратегия слияния - это fast-forward; объяснено примерно на полпути вниз по эта страница). Однако удаленное репо не работает точно так же, как локальное репо, нет способа авторизоваться для удаленного и pull; скорее команда выполняется на локальном компьютере, поэтому мы должны использовать правильный глагол push.

Можете ли вы увидеть комментарии выше и, возможно, отредактировать свой вопрос соответствующим образом. Мне все еще что-то не хватает в основе моего понимания git: /

Honey 10.08.2018 17:00

Смотрите мой последний абзац; Думаю, мы с @ElpieKay говорим об одном и том же. И я думаю, вы не так запутались, как думаете. Вы правы, что push, когда предыдущая история актуальна, является (с точки зрения пульта) зеркальным эквивалентом pull, когда предыдущая история актуальна. Но за исключением случая, когда предыдущая история актуальна, они различаются: pull объединит ваши локальные изменения с новыми изменениями удаленно, но push будет отклоненный.

nvioli 10.08.2018 17:03

добавлена ​​ссылка на объяснение слияния с быстрой перемоткой вперед.

nvioli 10.08.2018 17:05

когда тяга будет отклонена?

Honey 10.08.2018 18:56

pull никогда не будет отвергнут. Вы можете думать о том, что push может быть отклонен, потому что пульт не хочет, чтобы его заставляли принимать решения о слиянии. Пульт с радостью примет любые коммиты, которые находятся «перед» текущим HEAD, но если удаленный и локальный имеют разные исторические коммиты, он просто поднимает руки и говорит «нет, вам нужно исправить это» и отклоняет толкать. Напротив, при извлечении, если удаленный и локальный имеют разные исторические фиксации, пользователь должен завершить слияние. Это работает, потому что это решение может принять человек.

nvioli 10.08.2018 19:05

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

nvioli 10.08.2018 19:08

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

Honey 10.08.2018 19:41
тяга никогда не будет отклонена. как такое возможно? Может ли сбой слияния git? следовательно, git pull также не удастся ...
Honey 10.08.2018 19:48

Позвольте нам продолжить обсуждение в чате.

nvioli 10.08.2018 20:31

@Honey: да, операция перемотки вперед на самом деле вовсе не слияние. Истинное слияние может не удалось; в этом случае git pull, на котором запущен git merge, имеет ненулевой статус выхода. Называть ли это неудавшаяся тяга - открытый вопрос: половина тяги (git fetch) сработала, а половина (git merge) - нет.

torek 10.08.2018 20:31

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

Honey 12.08.2018 21:23

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

Honey 21.01.2019 13:49

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