Отправить запрос на извлечение из дочерней ветки после объединения родительской ветки с вышестоящей

У меня есть локальный репозиторий git с удаленным апстримом в Github. Я создал ветку A в своем локальном репозитории для новой функции, над которой работал, а затем отправил запрос на извлечение для этой ветки. Ожидая, пока этот PR будет объединен с восходящей ветвью, я хотел поработать над некоторыми другими функциями, основанными на branchA. Поэтому я создал новую ветку A1 из ветки A и внес в нее некоторые изменения.

Теперь мой PR для ветки A удален и объединен с удаленным восходящим потоком в Github, и я хотел бы отправить PR для моей ветки A1. Что я сделал, так это то, что я сначала получил изменения из удаленного восходящего потока в мою локальную основную ветку. Затем я попытался выполнить git rebase master в ветке A1, но эта команда, кажется, удаляет все изменения, которые я сделал в ветке A1.

Что лучше всего сделать сейчас, если я хочу отправить PR из филиала A1?

Если я сделал что-то не так в своем рабочем процессе, как правильно работать над новыми функциями, ожидая слияния PR из родительской ветки?

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 483
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

TL;DR: вы, вероятно, хотите git rebase --onto (для чего нужны дополнительные параметры).

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

Однако у вас все еще есть исходный коммит(ы). Теперь ваша задача — использовать git rebase для копирования Только хороших коммитов на ваш A1, а не коммитов с заменой на лучший, которые были и на A1, и на A, а теперь есть только на A1.

Чтобы представить это в графической форме, ты имел, например:

...--o--o--A   <-- master, origin/master
            \
             B--C--D   <-- branch-A
                    \
                     E--F--G   <-- branch-A1

где каждая заглавная буква обозначает коммит, т. е. A — это хэш-идентификатор коммита, который было на кончике вашего (и их) master, когда вы начали, B — это первый коммит, который вы сделали на своем branch-A, и так далее. .

Потом сказали: Хорошо, нам нравятся ваши B-C-D коммиты. Но мы собираемся «улучшить» их, сделав новый коммит H, который является результатом объединениеB + C + D в один большой коммит, который мы поместим в конец нашего master (вашего origin/master). Тем временем они могли или не могли добавить еще несколько коммитов в свои master — давайте проведем один раунд o, чтобы представить любые такие неинтересные коммиты. Как только вы запускаете git fetch origin, вы получаете коммиты ихновый (у вас уже есть их старые) в репозиторий твой, обновляя свой origin/master:

             o--H   <-- origin/master
            /
...--o--o--A   <-- master
            \
             B--C--D   <-- branch-A
                    \
                     E--F--G   <-- branch-A1

Если вы git checkout master и git merge origin/master, вы переместите свой master вперед, чтобы он соответствовал вашему origin/master:

...--o--o--A--o--H   <-- master, origin/master
            \
             B--C--D   <-- branch-A
                    \
                     E--F--G   <-- branch-A1

Ваш branch-A все еще существует, если вы его специально не удалили. Но даже если вы его удалили, у вас все еще есть ваши B-C-D коммиты:

...--o--o--A--o--H   <-- master, origin/master
            \
             B--C--D--E--F--G   <-- branch-A1

Если вы теперь git checkout branch-A1 и git rebase master — независимо от того, есть ли у вас все еще ваше имя branch-A, указывающее на ваш коммит D, который они выбросили в пользу своего H — ваш Git теперь попытается скопировать коммиты все шесть, B-C-D-E-F-G, поверх H, в попытке произвести это:

                   B'-C'-D'-E'-F'-G'   <-- branch-A1 (rebased)
                  /
...--o--o--A--o--H   <-- master, origin/master
            \
             B--C--D--E--F--G   [abandoned]

Но копировать B поверх H не получится: будет конфликтовать сам с собой, плюс нужен эффект C и Dудаленный. Так что это будет выглядеть так, как будто вы пытаетесь удалить свой собственный код только для того, чтобы вернуть его снова, когда вы копируете C в C', а затем D в D'. В любом случае все от этого бесполезен.

На данный момент вы хотели бы сообщить Git не Скопируйте все мои коммиты на branch-A1, которых нет на master, чтобы перейти к H в конце master, а скорее: Скопируйте только немного моих коммитов на branch-A1, которых нет на master, чтобы перейти после H на кончике master. Набор коммитов, которые вы хотите скопировать, в данном конкретном примере — это E-F-G. Вы хотите завершить с:

                   E'-F'-G'   <-- branch-A1 (rebased)
                  /
...--o--o--A--o--H   <-- master, origin/master
            \
             B--C--D--E--F--G   [abandoned]

способ, чтобы сообщить Git, что нужно использовать git rebase --onto, который принимает аргументы два вместо одного. Вы хотите перебазировать * на master и хотите исключить коммит D и все, что раньше (C, B, A и все скучные коммиты слева от A). Итак, если у вас делать все еще есть имя branch-A, идентифицирующее коммит D, вы можете использовать:

git checkout branch-A1             # make sure you're on the right branch
git rebase --onto master branch-A  # tell Git: copy only commits after branch-A

Если у вас не есть имя branch-A, вы можете использовать необработанный хэш-идентификатор коммита в качестве ограничителя вместо имени branch-A, или вы можете запускать git rebase -i master и удалять нежелательные pick команды; или вы можете запустить git log --all --decorate --oneline --graph и подсчитать коммиты или что вам нужно, чтобы найти коммит.

Обратите внимание, что после перебазирования у вас есть новыйbranch-A1 (совершенно не связанный история с вашим предыдущим branch-A1, хотя три коммита скопированы, чтобы иметь тот же эффект). Поэтому вам нужно будет принудительно отправить это в любую веб-службу, которую вы используете для обработки запросов на вытягивание (очевидно, GitHub). Вы можете использовать --force-with-lease, если беспокоитесь, что кто-то другой может добавить коммиты к вашему branch-A1 на сервере GitHub.

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