Применение изменений из ветки b в a без слияния или добавления коммитов


86

Мой сценарий заключается в том, что у меня есть одна ветка, в которой я значительно улучшил процесс сборки (ветка A), а в другой я работаю над несвязанной функцией (ветка B). Итак, теперь, когда я взламываю ветку B, я хочу добавить то, что написал в ветке A, потому что мне нужны более быстрые и простые сборки. Однако я не хочу «загрязнять» свою ветку B, просто добавляю изменения из ветки A в неустановленные изменения.

Что пробовал (стоя на ветке B):

git merge --no-commit branchA

Не работает, потому что помещает вас внутрь слияния. Если бы этого не было, это было бы идеально.

git checkout branchA -- .

Не работает, потому что он применяет изменения между branchA..branchB, а не master..branchA изменений.

Что-нибудь еще?

Изменить: Да, изменения в ветке A фиксируются. В этом примере есть только одна ветка с улучшениями сборки, но может быть до N веток с улучшениями сборки, которые я хочу применить при работе над функциональной веткой.


Изменения на A уже зафиксированы?
Theolodis

Ответы:


152

Мне просто нужно было сделать что-то подобное, и я смог исправить это, добавив --squashв команду слияния

git merge --no-commit --squash branchA
git reset HEAD # to unstage the changes

3
Это также должно иметь пояснительную записку о том, что он делает. Он устанавливает разницу изменений из ветки A в вашу текущую ветку
Карим Элашмави

Допустим, я только что слил код из branchA в master, но я кое-что забыл и хочу добавить еще несколько кода / изменений в этот коммит слияния, не отображаясь как еще один коммит слияния в истории git. будет ли этот метод работать?
Сушмит Сагар

@Sushmit, я думаю, вы можете сделать, git commit —amendи он добавит новые изменения в последний коммит, я просто не совсем уверен, работает ли он с
коммитами

1
Я не думаю, что здесь нужен --no-commit? Должно быть по умолчанию.
Петтер

11

cherry-pick -n должны делать то, что вы хотите, но я не уверен, почему вы хотите, чтобы улучшения сборки были неустановленными изменениями - это только усложняет некоторые вещи (например, объединение других изменений в измененные файлы или перебазирование чего-либо).

В этом примере есть только одна ветка с улучшениями сборки, но может быть до N веток с улучшениями сборки, которые я хочу применить при работе над функциональной веткой.

В этом случае я бы создал новую ветку C, которую вы объедините как с A, так и с B (и с любыми другими ветвями с улучшениями сборки). Зафиксируйте изменения в функциональной ветви B, затем объедините их с ветвью C, которая теперь содержит улучшения сборки и изменения функциональной ветви, чтобы вы могли протестировать их вместе. Если вам нужно внести больше изменений, сделайте это в соответствующей ветке, а не в C, а затем выполните слияние с C. Поэтому никогда ничего не меняйте в ветке C, просто используйте ее для интеграции изменений из других веток.

Это означает, что вы можете использовать все функции Git в ветви C вместо того, чтобы манипулировать незафиксированными изменениями в грязном дереве.


Пример использования cherry-pick -n: я создал рабочую копию своего кода, добавив много чего в случайные места. Теперь я хочу очистить свой код, прежде чем переходить к ветке этой функции. Поэтому я переключаюсь на временную ветку, фиксирую все изменения. Вернитесь в ветку функций, cherry-pickкоторая фиксирует. Есть ли лучший способ сделать это?
Tejas Kale

6

У вас должна быть возможность тщательно выбирать коммиты ( -nчтобы сразу не совершать коммит ).


-n не сработало. Он говорит, что опция -m не удалась при фиксации вишневого выбора.
Алехандро Санс Диас

5

Я не уверен на 100%, что понял это ясно, но в моем случае я только что создал патч различий между ветвями, а затем применил этот путь к ветке B.

Внутри ветви A:

 git diff branchA..branchB > patch.diff
 git apply patch.diff

4

Я не уверен, что понимаю ваши требования.

Можете запустить слияние, потом позвонить git reset HEAD~1.


Следующая последовательность должна воспроизводить каждую фиксацию между masterи branchAповерх branchB. Коммиты, которые уже были применены, branchBбудут пропущены.

# start from branchA
git checkout branchA
# create a temporary branch wip
git checkout -b wip
# use rebase to replay each commit between master and wip on branchB
git rebase --onto branchB master wip

# if you want to remove all the commit history and only keep the resulting diffs,
# use git reset
git reset branchB

# change the active branch
git checkout branchB
# remove temp branch
git branch -d wip

Это добавляет файлы в промежуточную область git, которые мне не нужны. Кроме того, кажется, что это работает хорошо только тогда, когда все ветки ответвляются от одного и того же коммита в основной ветке. В противном случае вводятся различия, не входящие в диапазон master..branchA.
Björn Lindqvist

@ BjörnLindqvist: удалите эту --softопцию, если вы не хотите вносить изменения в промежуточную область. Не могли бы вы нарисовать график того, как устроены ваши филиалы?
LeGEC
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.