Перебазирование git для линейной истории

У меня проблема с невозможностью создать «линейную» историю для моей ветки с помощью перебазирования.

Возможно, у меня неправильное представление о том, что можно/нужно сделать, но я работаю вот над чем:

---A---B---E   master
       |
       |---C---D  feature

На этом этапе обе ветки (главная и функциональная) синхронизируются со своими удаленными аналогами, а это означает, что эти коммиты есть как в локальном, так и в удаленном репозитории. В этот момент я побежал:

git checkout feature
git pull --rebase origin master

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

---A---B---E---C'---D'---MergeCommit---

Но вместо этого я получаю:

---A---B--------------------C---D---MergeCommit---
       |                            |
       |---E---C'---D'--------------|

Примечание. Я не уверен, что C и C' правильно расположены, поскольку у меня нет возможности определить, какой из этих двух был оригиналом, а какой — «копией», но их двое присутствуют.

Вы можете увидеть картинку ниже, чтобы было более понятно.

Я не возражаю против того, чтобы здесь было две «строчки», за неимением лучшего слова. Я не против иметь «фиксацию слияния». Все это нормально. Что меня сводит с ума, так это дублирование commit C и commit D.

Или даже следующее будет приемлемо:

---A---B-------------------MergeCommit---
       |                   |
       |---E---C'---D'-----|

Как мне избавиться от них на любой из «линий». Я продолжаю произносить строки, потому что все это одна ветвь. Я не баловался контролем версий уже несколько лет, я почти уверен, что раньше я этого не делал, и у меня не было дублированных коммитов, вместо этого они представляли собой один линейный график. Я бы винил git pull из-за сообщения, которое я получаю сейчас и которое я не узнаю, Merge made by the 'ort' strategy. это кажется мне новым, и я чувствую, что это причина проблем.

Вчера был аналогичный вопрос относительно git pull --rebase с отличным ответом от @Bert F. Предлагаю вам взглянуть на него, чтобы лучше понять, как на самом деле работает команда. stackoverflow.com/questions/78802778/… К сожалению, хотя git pull --merge соответствует git fetch + git merge, git pull --rebase не равно git fetch + git rebase.

dani-vta 29.07.2024 16:57

Забудьте о git pull (вас ввели в заблуждение миллионы плохих руководств) и попытайтесь пересмотреть свое понимание Git без использования git pull. Это приносит больше вреда, чем пользы. Я использовал Git 13 лет, не запуская его git pull, ни разу. Перебазирование меняет историю ветки. Если его нажать, git push отказывается работать. Вам нужно использовать git push --force или, еще лучше, git push --force-with-lease. Прочтите документацию git push: git-scm.com/docs/git-push

axiac 29.07.2024 17:05

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

j6t 29.07.2024 17:58

@dani-vta Указанный пост и ответ не относятся к этому случаю.

j6t 29.07.2024 17:59

@j6t да, извини, мне следовало расширить свой комментарий. Я поделился этой ссылкой только потому, что увидел некоторую путаницу в том, как ОП думал, что git pull --rebase работает. Это было не решение, а просто дополнительное разъяснение. @Axiac на самом деле очень хорошо заметил, что не использовал git push --force среди некоторых неправильных/отсутствующих вещей, сделанных OP.

dani-vta 29.07.2024 18:08

Я согласен с оценкой ОП о том, что проблема заключалась в регулярном «git pull» удаленной функциональной ветки после «git pull --rebase origin main». Как только произошло перебазирование (из git pull --rebase), удаленная ветка больше не была действительной, и ее следовало принудительно переместить, а не вытащить. Извлечение с помощью слияния после извлечения с помощью rebase — вот что привело к созданию дубликатов коммитов.

Bert F 29.07.2024 18:32

Итак, прочитав все это, я понял, что принудительное нажатие после перебазирования - это нормально? Я правильно понял? Для меня «силовое нажатие» всегда представлялось как БОЛЬШОЕ НЕТ-НЕТ. Как тогда решить совместную работу, у всех остальных нет принудительных изменений в своих локальных ветках?

Dellirium 30.07.2024 09:08

Есть ли у кого-нибудь ответ, как в этом случае получить линейную одну строку?

Dellirium 30.07.2024 09:09

Привет, неожиданная история коммитов на вашем скриншоте была из ветки master или ветки feature? Я был в замешательстве, так как мог запустить git checkout feature -> git pull --rebase origin master, а затем смог запустить git push, чтобы отправить коммиты в свою feature ветку. История коммитов в моей функциональной ветке будет выглядеть так: A-B-E-C'-D'. Кажется, вы отправили коммиты с помощью коммита слияния на master. Был ли пропущен какой-либо шаг для воспроизведения проблемы?

Alvin Zhao - MSFT 30.07.2024 12:15

Не могли бы вы попробовать запустить git log feature --oneline и git log origin/master --oneline, чтобы дважды проверить историю коммитов и сравнить идентификатор коммита в каждой локальной ветке перед отправкой?

Alvin Zhao - MSFT 30.07.2024 12:18

С тех пор я удалил это репо, поэтому не могу точно проверить, но в названии самого последнего коммита написано: «Объединить ветку «feat....», поэтому я предполагаю, что это дерево происходит из «главной ветки».

Dellirium 30.07.2024 12:18

Попробую повторить еще раз и сделать так, как вы просили.

Dellirium 30.07.2024 12:18

Вы можете использовать эти git log команды для ведения записей каждой git команды, которая может изменить историю коммитов и идентификатор коммитов. Нам было бы полезно понять, как это было воспроизведено.

Alvin Zhao - MSFT 30.07.2024 12:22

Итак, мое первоначальное предположение, что это изображение было из основной ветки, было неверным, на самом деле оно было в функциональной ветке. Я воспроизводил эту проблему несколько раз, и она всегда без ошибок создает такой график. У меня есть список шагов для воспроизведения, но он не подходит для «комментария», если хотите, я могу отредактировать вопрос. git log --oneline указывает на следующий порядок: A--B--C--D--E--C'--D' после git pull и git push.

Dellirium 30.07.2024 12:36

Это кажется безумием... git pull полностью разрушает/повреждает цель git rebase, которую я хочу продвигать/сохранять. Коммиты C' и D' по сути будут «пустыми», потому что изменения уже были реализованы C и D... извлечение из удаленной функции (чтобы вернуться к ней - как того требует git) после перебазирования - это как если бы я только сделало обычное слияние с мастером, победив всю цель перебазирования

Dellirium 30.07.2024 12:37

Невозможно перебазировать ветку объекта (т. е. иметь линейную историю) без какого-либо принудительного нажатия позже (ну, я думаю, вы могли бы удалить удаленную ветку и воссоздать ее из новой локальной). Непринудительное нажатие требует, чтобы локальная ветка добавляла только коммиты к кончику удаленной — перебазирование явно перемещает всю ветку.

Bert F 30.07.2024 16:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
16
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я создал репозиторий, похожий на ваш: у меня есть ветка функций «feature»/eabd641, изначально ответвленная от локального «master»/5d2cce8. После git fetch --all мы видим, что удаленная ветка «master» перешла на новый коммит 82e4b59.

* eabd641 Mon Jul 29 12:01:01 2024 -0400 test 1
|  (origin/feature, feature)
| * 82e4b59 Sun May 5 23:15:23 2024 -0400 Fix bug
|/   (origin/master)
* 5d2cce8 Sun May 5 21:54:15 2024 -0400 3/3 challenges
|  (HEAD -> master)
* f0994f1 Sun May 5 18:06:48 2024 -0400 2/3 challenges

Если я применю команду OP, используемую

git checkout feature
git pull --rebase origin master

Мое репо теперь выглядит так. Моя ветка функций была переведена на удаленное отслеживание «origin/main»/82e4b59 (мой локальный «master» не был обновлен). Эта функция теперь является линейной, поскольку она находится за пределами (удаленного) главного устройства, но моя ветка удаленного отслеживания «источник/функция» теперь не синхронизирована из-за перебазирования. Коммит «тест 1» существует в локальной и удаленной ветках функций — теперь git pull будет объединяться с локальным и удаленным, что сохранит оба коммита «тест 1» в истории, как видел ОП.

* b1f6f71 Mon Jul 29 12:01:01 2024 -0400 test 1
|  (HEAD -> feature)
* 82e4b59 Sun May 5 23:15:23 2024 -0400 Fix bug
|  (origin/master, origin/main)
| * eabd641 Mon Jul 29 12:01:01 2024 -0400 test 1
|/   (origin/feature)
* 5d2cce8 Sun May 5 21:54:15 2024 -0400 3/3 challenges
|  (master)
* f0994f1 Sun May 5 18:06:48 2024 -0400 2/3 challenges

Теперь я бы git push -f синхронизировал удаленную ветку «функция» с перебазировкой, затем выполнил сборку и запустил тесты, чтобы код был в порядке, сделал бы еще одну выборку, чтобы проверить, что удаленная «главная» ветка снова не продвинулась, затем git checkout master, git pull и git merge feature (это перемотка вперед — добавьте --no-ff, если вы хотите коммит слияния).

Не уверен, что мне нравится использовать «git pull --rebase origin master», чтобы объединить вытягивание и перебазирование, чтобы перебазировать функцию на кончик удаленного отслеживания «origin/master». Я бы предпочел сначала обновить локальный «мастер», а затем явно перебазировать «функцию» на мой локальный «мастер», а затем git push -f. В любом случае вам все равно придется обновить локальный «мастер».

Я не против обновить локальный мастер, я думал, что pull --rebase — это просто ярлык. Как обеспечить совместную работу локальных компьютеров товарища по команде, у которых есть другая копия из-за push -f? Просто попросить их удалить свои копии и вытащить? Что, если у них есть локальные коммиты (еще не отправленные), основанные на предыдущей истории, есть ли способ изменить их?

Dellirium 31.07.2024 06:11

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

Похожие вопросы

Возникла проблема с фиксацией моего приложения на GitHub после обновления модулей
Почему «git pull --rebase» переопределяет локальные фиксации, когда push и pull нацелены на разные репозитории?
Как управлять исправлениями в основной ветке и ветке разработки в Git
Могу ли я написать конкретное правило о том, как git должен обрабатывать конкретный часто встречающийся конфликт слияния в конкретном файле?
Git log -p -- <файл> показывает коммит без патча
Почему `git clone --length 1` оставляет паковочные файлы?
Как устранить ошибку «Необходимо указать, как согласовать расходящиеся ветки» при перебазировании в Git?
Git-фильтр-репо не удаляет файл из истории коммитов
Некоторые конвейеры сборки ADO отображают все рабочие элементы в связанных элементах, а другие — только соответствующие элементы. Ищем идеи
Как удалить подключение репозитория git и github к решению в Visual Studio 2022?