Запомните, что git pull
означаетgit merge
.
Ну, это означает «Первый запуск git fetch
, а затем запустите git merge
, если я не попрошу вас вместо этого выполнить git rebase
».
Вы, следовательно, имеют четыре элементы, которые потенциально we'll получить обратно в «потенциально» части в одну минуту создать слияния:
git checkout R1609; git pull origin R1609
: это может создать новое слияние совершить на вашем (т. е. R1609
), используя то, что он находит и извлекает из вашего восходящего потока, то есть другой (origin's) Git's R1609
.
git checkout R1609_dpl; git pull origin R1609_dpl
. Как и в случае с шагом 1, это потенциально создает новое слияние.
git merge --no-ff R1609
: определенно создает слияние, если только он ничего не делает. (Лучше всего ничего не делать из-за пункта 4 здесь.)
git commit --amend -m "Push to R1609 triggered: Merge R1609 into R1609_dpl"
: это «исправляет» копирует текущую фиксацию на новую фиксацию с новым, другим сообщением. Он отбрасывает текущую фиксацию в сторону. Предполагая, что мы сделали слияние на шаге 3, это отталкивает слияние и заменяет его новым слиянием. Сброс влево-влево исчезнет с вывода git log
, так как текущий ответвление (сейчас R1609_dpl
) указывает на новую копию, и только его рефлог указывает на оригинал после того, как исправление закончено.
В некотором смысле, то, что это немного удивительно, что вы не получите три фиксаций. Тот, который вы : Получение происходит с шага 1, так как журнал показывает, что его сообщение «Объединить ветвь« R1609 »<URL> в R1609». Итак, пришло время описать «потенциальную» вещь.
Есть две возможности для git fetch
, а второй один распадается на два случая:
Восходящий, что ваш Git называет origin/R1609
но их (начало в) Git просто вызывает R1609
, в синхронизации с вашим собственный R1609
, или позади: у вас есть определенные фиксации (им) (пока вы не нажмете их). В этом случае git fetch
ничего не делает, и нет ничего, чтобы объединиться, и git merge
ничего не делает. (Yay, но также и boo, почему мы даже беспокоились? :-) Ну, чтобы проверить, конечно.)
Восходящий поток не синхронизируется с вашим R1609
. Git извлекает некоторые фиксации из восходящего потока. Это может быть строго впереди ваших собственных коммитов на вашем R1609
, иначе может быть, что у их R1609
есть фиксация, которой вам не хватает, в то время как у вашего R1609
есть обязательство, которое им не хватает. Шаг fetch
не нуждается в заботе; он просто приносит в зависимости от того, что они совершают, а вы этого не делаете. Затем он обновляет ваш origin/R1609
, чтобы запомнить их новые фиксации.
Когда выборка делает принести что-то, хотя, теперь вы можете быть строго за -вы просто нужно, чтобы догнать их R1609
-или вы можете быть одновременно впереди и позади , В первом случае git merge
по умолчанию выполняет операцию «быстрой перемотки вперед». Git изменяет метку вашего филиала, R1609
, так что он указывает на тот же фиксаж, что и их R1609
(ваш origin/R1609
). Конечно, если вы укажете --no-ff
, Git вместо этого сделает реальное слияние. В последнем случае, однако, Git должен сделать реальное слияние, чтобы объединить ваши фиксации (ы) и их фиксацию (ы). Таким образом, вы получаете слияние здесь, и его сообщение Merge branch 'R1609' of <url> into R1609
.
Очевидно, то, что-то вверх вызывает новые коммиты появляться на ихR1609
, что ваш Git считает он должен объединить в шаге 1. Ничего не происходит с восходящим потоком R1609_dpl
, поэтому ваш Git способен ускорить перемотку вперед или вообще ничего не делать на шаге 2. Шаг 3 создает новое слияние, и шаг 4 отбрасывает его в сторону, создавая третье слияние, оставляя вас два видимых слияния.
(я вижу, что к тому времени, когда я закончил писать все это, вы уже нашли виновника, который Вводя совершить на R1609
на origin
.)
Ну, до тех пор, как ваш Git является версии 1.8.4 или новее. Иногда версии Older Git не обновляют ветвь удаленного отслеживания. (В частности, они намеренно не обновлять его на fetch
пробеге от pull
сценария. Это оказалось ошибкой, так что было изменено в 1.8.4.)
Хотя документация git merge
описывает это как a ускоренное слияние, это действительно не слияние вообще. Ускоренная перемотка вперед - это свойство перемещения метки . Учитывая метку, которая указывает на фиксацию X, и запрос на ее изменение, чтобы указать на ярлык Y, мы проверяем: «Является ли X предком Y?» Если это так, это изменение является быстрой перемоткой вперед. Если нет, это не так.
Оба git fetch
и git pull
имеют встроенный код для обнаружения быстрых ходов, а не для перемотки вперед. Это то, что означает флаг --force
, при нажатии и, если на то пошло, при извлечении, хотя для извлечения он всегда выполняется с помощью синтаксиса +
в refspec. Без --force
или +
флага, Git отказывается изменить метку ветви от совершения X совершить Y, если не совершат X является предком Y.
командной merge
, конечно, также имеет тот же самый код, и ускоренная перемотка переместите ярлык вместо слияния, если (а) это возможно, и (б) вы его не запретили. Поскольку эта операция выполняется на текущей ветке , используя текущий индекс и рабочее дерево, git merge
также обновляет индекс и рабочее дерево для соответствия. Код выборки и push не обновляет ни индекс, ни рабочее дерево.
Это проясняет многое! Мне удалось исправить эту проблему, переписывая часть моего сценария bash и перестраивая его. Никогда не получил ответа на этот вопрос. Благодаря! – MikeB