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.