Отправка запроса извлечения из дочерней ветви после слияния родительской ветви с восходящей - PullRequest
1 голос
/ 29 мая 2019

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

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

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

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

1 Ответ

3 голосов
/ 29 мая 2019

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

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

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

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

...--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). Итак, если у вас do все еще есть имя 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 (полностью не связанный history с вашим более ранним branch-A1, даже если три коммита скопированы так, чтобы иметь одинаковый эффект),Поэтому вам необходимо принудительно передать это любому веб-сервису, который вы используете для обработки запросов на удаление (очевидно, GitHub).Вы можете использовать --force-with-lease, если беспокоитесь, что кто-то еще может добавлять коммиты к вашему branch-A1 на сервере GitHub.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...