Как git -cherry-pick только изменяется на определенные файлы?
Если я хочу объединиться в ветвь Git, изменения, внесенные только в некоторые из файлов, были изменены в конкретном коммите, который включает изменения в несколько файлов, как это может быть достигнуто?
Предположим, что Git commit с именем stuff
имеет изменения в файлах A
, B
, C
и D
, но я хочу объединить только stuff
изменения в файлы A
и B
. Это похоже на задание для git cherry-pick
, но cherry-pick
знает, как слить целые коммиты, а не подмножество файлов.
Ответы
Ответ 1
Я бы сделал это с помощью cherry-pick -n
(--no-commit
), который позволяет вам проверять (и изменять) результат перед фиксацией:
git cherry-pick -n <commit>
# unstage modifications you don't want to keep, and remove the
# modifications from the work tree as well.
# this does work recursively!
git checkout HEAD <path>
# commit; the message will have been stored for you by cherry-pick
git commit
Если подавляющее большинство изменений - это то, чего вы не хотите, вместо того, чтобы проверять отдельные пути (средний шаг), вы могли бы reset вернуть все, а затем добавить то, что хотите:
# unstage everything
git reset HEAD
# stage the modifications you do want
git add <path>
# make the work tree match the index
# (do this from the top level of the repo)
git checkout .
Ответ 2
Другие методы не работали для меня, так как у коммита было много изменений и конфликтов с большим количеством других файлов. Я придумал просто
git show SHA -- file1.txt file2.txt | git apply -
На самом деле это не делает фиксацию для вас, поэтому вам может потребоваться выполнить ее с помощью
git commit -c SHA
Ответ 3
Возможно, преимущество этого метода над ответом Jefromi заключается в том, что вам не нужно помнить, какое поведение git reset является правильным:)
# Create a branch to throw away, on which we'll do the cherry-pick:
git checkout -b to-discard
# Do the cherry-pick:
git cherry-pick stuff
# Switch back to the branch you were previously on:
git checkout -
# Update the working tree and the index with the versions of A and B
# from the to-discard branch:
git checkout to-discard -- A B
# Commit those changes:
git commit -m "Cherry-picked changes to A and B from [stuff]"
# Delete the temporary branch:
git branch -D to-discard
Ответ 4
Обычно я использую флаг -p
с проверкой git из другой ветки, которую я нахожу более простой и более гранулированной, чем большинство других методов, с которыми я столкнулся.
В принципе:
git checkout <other_branch_name> <files/to/grab in/list/separated/by/spaces> -p
Пример:
git checkout mybranch config/important.yml app/models/important.rb -p
Затем вы получите диалоговое окно с запросом о том, какие изменения вы хотите в "блобах", это в значительной степени отражается на каждом фрагменте непрерывного изменения кода, который вы можете затем сигнализировать y
(да) n
(Нет) и т.д. для каждого фрагмент кода.
Параметр -p
или patch
работает для различных команд в git, включая git stash save -p
, который позволяет вам выбирать, что вы хотите сохранить из текущей работы
Я иногда использую эту технику, когда проделал большую работу, и хотел бы ее разделить и совершить в более строгих коммитах, используя git add -p
и выбрав то, что я хочу для каждой фиксации:)
Ответ 5
Выбор вишни - это выбор из определенного "фиксации". Самое простое решение - выбрать все изменения определенных файлов, чтобы использовать
git checkout source_branch <paths>...
В примере:
$ git branch
* master
twitter_integration
$ git checkout twitter_integration app/models/avatar.rb db/migrate/20090223104419_create_avatars.rb test/unit/models/avatar_test.rb test/functional/models/avatar_test.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: app/models/avatar.rb
# new file: db/migrate/20090223104419_create_avatars.rb
# new file: test/functional/models/avatar_test.rb
# new file: test/unit/models/avatar_test.rb
#
$ git commit -m "'Merge' avatar code from 'twitter_integration' branch"
[master]: created 4d3e37b: "'Merge' avatar code from 'twitter_integration' branch"
4 files changed, 72 insertions(+), 0 deletions(-)
create mode 100644 app/models/avatar.rb
create mode 100644 db/migrate/20090223104419_create_avatars.rb
create mode 100644 test/functional/models/avatar_test.rb
create mode 100644 test/unit/models/avatar_test.rb
Источники и полное объяснение http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
UPDATE:
С помощью этого метода git не будет MERGE файла, он просто переопределит любые другие изменения, сделанные в ветке назначения. Вам нужно будет объединить изменения вручную:
$git diff Имя файла HEAD
Ответ 6
Я бы просто вишневый-выбрать все, а затем сделать это:
git reset --soft HEAD^
Затем я бы отменил изменения, которые не хочу, а затем сделаю новую фиксацию.
Ответ 7
Я нашел другой способ, который предотвращает какое-либо противоречивое слияние с выбором вишни, которое ИМО легко запомнить и понять. Так как вы на самом деле не выбрали чартер, а часть его, вам нужно сначала разбить его, а затем создать фиксацию, которая будет соответствовать вашим потребностям и вишневым выбором.
Сначала создайте ветку из фиксации, которую хотите разбить, и проверьте ее:
$ git checkout COMMIT-TO-SPLIT-SHA -b temp
Затем верните предыдущую фиксацию:
$ git reset HEAD~1
Затем добавьте файлы/изменения, которые вы хотите выбрать cherry-pick:
$ git add FILE
и зафиксировать его:
$ git commit -m "pick me"
Обратите внимание на хеш-код фиксации, позвоните ему PICK-SHA и вернитесь в свою основную ветку, например, для запуска проверки:
$ git checkout -f master
и вишня выберите фиксацию:
$ git cherry-pick PICK-SHA
теперь вы можете удалить ветвь temp:
$ git branch -d temp -f
Ответ 8
Используйте git merge --squash branch_name
, это приведет к изменению всех изменений в другой ветке и подготовит для вас фиксацию.
Теперь удалите все ненужные изменения и оставьте тот, который вы хотите. И git не будет знать, что произошло слияние.
Ответ 9
Существует идеологически неправильный, но очень продуктивный способ.
- Используйте графический интерфейс git или
git show
для просмотра всего содержимого файла, который вы хотите использовать для выбора
- Затем вручную вставьте его в свой IDE/редактор
- Сохраните и просмотрите его
Это "некорректно", но все же мертво просто и позволяет настраивать изменения в вашем редакторе.