Если я хочу объединить ветку Git с изменениями, внесенными только в некоторые файлы, измененные в конкретном коммите, который включает в себя изменения в нескольких файлах, как это может быть достигнуто?
Предположим , что Git коммит называется stuff
имеет изменения в файлах A
, B
, C
и , D
но я хочу , чтобы объединить только stuff
изменения «s к файлам A
и B
. Звучит как работа, git cherry-pick
но cherry-pick
знает, как объединить все коммиты, а не подмножество файлов.
источник
git checkout .
я бы порекомендовал такжеgit clean -f
удалить все новые, но нежелательные файлы, введенные вишневым коммитом.git add -p
который позволяет вам в интерактивном режиме решить, какие изменения вы хотите добавить в индекс для каждого файлаgit reset -p HEAD
. Это эквивалент,add -p
но очень немногие знают, что он существует.Другие методы не работали для меня, так как в коммите было много изменений и конфликтов с множеством других файлов. То, что я придумал, было просто
На самом деле
add
это не файлы или коммит для вас, поэтому вам может потребоватьсяИли, если вы хотите пропустить добавление, вы можете использовать
--cached
аргумент дляgit apply
Вы также можете сделать то же самое для целых каталогов
источник
show SHA -- file | apply
это не так,checkout SHA -- file
как в ответе Марка Лонгаира ?checkout SHA -- file
будет проверять именно версию в SHA, в то время какshow SHA -- file | apply
будут применены только изменения в SHA (точно так же, как cherry-pick). Имеет значение, если (а) существует более одного коммита, изменяющего данный файл в исходной ветке, или (б) есть коммит, изменяющий файл в вашей текущей целевой ветке.git revert
отменяет весь коммит). В этом случае просто используйтеgit show -R SHA -- file1.txt file2.txt | git apply -
git diff SHA -- file1.txt file2.txt | git apply -
означает применить все различия между текущей версией файла и версией в SHA к текущей версии. По сути это так же, какgit checkout SHA -- file1.txt file2.txt
. Смотрите мой предыдущий комментарий, почему это отличается от того, чтоgit show
версия.git apply -3 -
вместо простоgit apply -
, тогда, если конфликт возникает, вы можете использовать свою стандартную технику разрешения конфликтов, включая использованиеgit mergetool
.Я обычно использую
-p
флаг с git checkout из другой ветки, который я считаю более простым и более детальным, чем большинство других методов, с которыми я сталкивался.В общем:
пример:
Затем вы получите диалоговое окно, в котором вас спросят, какие изменения вы хотите внести в «BLOB-объекты», и это в значительной степени работает с каждым фрагментом непрерывного изменения кода, который затем можно сигнализировать
y
(Да)n
(Нет) и т. Д. Для каждого фрагмента кода.Опция
-p
orpatch
работает с множеством команд в git, в том числеgit stash save -p
позволяет выбрать то, что вы хотите сохранить в своей текущей работе.Я иногда использую эту технику, когда проделал большую работу и хотел бы выделить ее и зафиксировать в коммитах на основе нескольких тем, используя
git add -p
и выбирая то, что я хочу для каждого коммита :)источник
git-add -p
, но я не знал,git-checkout
также есть-p
флаг - это решает проблемы слияния, которые есть у-p
ответа ?-p
, допускается ручное редактирование для такого противоречивого раздела, чтоcherry-pick
, вероятно, в любом случае также приведет к. Я проверю это в следующий раз, когда мне это понадобится, безусловно, интересный подходgit reset -p HEAD
также позволяет-p
легко выйти из него, если вы хотите удалить только некоторые патчи из индекса.Возможно, преимущество этого метода перед ответом Джефроми в том, что вам не нужно помнить, какое поведение git reset является правильным :)
источник
cherry-pick
и напрямую использоватьgit checkout stuff -- A B
? И сgit commit -C stuff
сообщением фиксации тоже останется то же самоеstuff
не были изменены в вашей текущей ветке или где-либо между общим предкомHEAD
иstuff
и верхушкойstuff
. Если они есть, тоcherry-pick
создает правильный результат (по сути, результат слияния), в то время как ваш метод отбрасывает изменения в текущей ветви и сохраняет все изменения от общего предка доstuff
- не только те, что в одиночный коммит.stuff
поскольку результат выбора вишни уйдетA
и будетB
отличаться от их содержания в коммитеstuff
. Однако, если бы это было так же, вы правы - вы могли бы просто сделать, как вы говорите.Cherry pick - это выбор изменений из определенного «коммита». Самое простое решение состоит в том, чтобы выбрать все изменения определенных файлов, это использовать
В примере:
Источники и полное объяснение http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
ОБНОВИТЬ:
С помощью этого метода git не будет MERGE файл, он просто переопределит любые другие изменения, сделанные в целевой ветви. Вам нужно будет объединить изменения вручную:
источник
Ситуация:
Допустим, вы в своей ветке,
master
и у вас есть коммит в любой другой ветке. Вы должны выбрать только один файл из этого конкретного коммита.Подход:
Шаг 1: Оформить заказ на нужную ветку.
Шаг 2: Убедитесь, что вы скопировали необходимый хеш коммита.
Шаг 3: Теперь у вас есть изменения нужного файла в нужной ветке. Вам просто нужно добавить и зафиксировать их.
источник
Я бы просто все выбрал, а потом сделал бы это:
Затем я отменил бы изменения, которые мне не нужны, а затем сделал бы новый коммит.
источник
Используйте
git merge --squash branch_name
это, чтобы получить все изменения из другой ветки и подготовить коммит для вас. Теперь удалите все ненужные изменения и оставьте тот, который вы хотите. И мерзавец не узнает, что произошло слияние.источник
Я нашел другой способ, который предотвращает любое противоречивое слияние при сборке вишни, которое IMO легко запомнить и понять. Поскольку на самом деле вы выбираете не коммит, а его часть, вам нужно сначала разделить его, а затем создать коммит, который соответствует вашим потребностям, и выбрать его.
Сначала создайте ветку из коммита, который вы хотите разделить, и извлеките его:
Затем верните предыдущий коммит:
Затем добавьте файлы / изменения, которые вы хотите в cherry-pick:
и совершить это:
обратите внимание на хэш коммита, давайте назовем его PICK-SHA и вернемся к вашей основной ветке, например, master для принудительной проверки:
и черри выбирай коммит:
Теперь вы можете удалить временную ветку:
источник
Объедините ветку в новую (сквош) и удалите ненужные файлы:
источник
Для полноты картины лучше всего мне подходит:
Он делает именно то, что хочет ОП. Он делает разрешение конфликтов, когда это необходимо, так же, как
merge
это делает. Это делает,add
но неcommit
ваши новые изменения.источник
Ты можешь использовать:
Обозначение
<commit>^
указывает (первого) родителя<commit>
. Следовательно, эта команда diff выбирает изменения, сделанные<path>
в коммите<commit>
.Обратите внимание, что это еще ничего не зафиксирует (как это
git cherry-pick
делает). Так что если вы хотите этого, вам придется сделать:источник