Не существует встроенной команды Git для решения вашей ситуации. Если бы он был, его можно было бы назвать git vendor-import
или что-то в этом роде. Также нет единственного лучшего способа справиться с этим. Если бы там было, вероятно, существовал бы git vendor-import
или как бы там ни было его имя. Тем не менее, есть несколько общих тем.
Нарисуйте диаграмму того, что происходит, когда вы получаете новую версию от поставщика
По сути, у вас есть серия снимков, которые поступают от поставщика на которое вы создаете собственное программное обеспечение. Давайте нарисуем такую ситуацию:
V1.0---------V1.1 <-- new release from vendor
\
A--B--C <-- your versions
Каждый раз, когда вы получаете новый выпуск от поставщика, это полный снимок всего набора файлов, который они намереваются иметь. (Возможно, они не называются «версия 1.0» и «версия 1.1»; в противном случае вы можете использовать другие имена на диаграмме выше.)
Нарисуйте схему более типичного Git использования
Теперь давайте рассмотрим, как может выглядеть набор Git веток и коммитов. Помните, что Git commit - это снимок файлов, хотя вы обычно просматриваете коммиты как diff и делаете новые коммиты, извлекая некоторый снимок, затем изменяя некоторые файлы и делая следующий снимок. Мы начинаем с некоего начального снимка - возможно, у него даже есть только файл README
- и расширяемся оттуда:
A--B--C <-- master
(Эти прописные буквы заменяют Git ha sh ID, которые выглядят случайными, а не последовательными, но все же идентифицируют каждую фиксацию.)
Когда у нас будет достаточно системы, созданной, чтобы быть полезной, мы могли бы начать создавать ветки для определенных функций или идей: 1026 * Вложение со специальным именем HEAD
указывает, что у нас есть фиксация J
через ветку feature
, извлеченная прямо сейчас - это набор файлов, над которыми мы должны работать. (Файлы внутри снимков доступны только для чтения и не дублируются во всех коммитах, поэтому это копии снимка, а не сам снимок.)
На этом этапе, возможно, нам нужно чтобы исправить ошибку с высоким приоритетом на master
, поэтому мы запускаем git checkout master
или (начиная с Git 2.23) git switch master
, который удаляет копии файлов из фиксации J
и извлекает копии файлов из фиксации H
:
A--...--G--H <-- master (HEAD)
\
I--J <-- feature
Сейчас мы работаем с файлами master
/ commit- H
. Мы исправляем ошибку с высоким приоритетом и, как обычно, делаем новую фиксацию; назовем эту новую фиксацию K
:
A--...--G--H--K <-- master (HEAD)
\
I--J <-- feature
Теперь мы можем go вернуться к работе над нашей функцией с помощью git checkout feature
или git switch feature
, который удаляет все файлы K
из наша рабочая область и заменяет их файлами J
:
A--...--G--H--K <-- master
\
I--J <-- feature (HEAD)
Когда мы работаем с репозиторием upstream (через GitHub или другого провайдера fork механизмы ), это становится немного сложнее, но, по сути, репозиторий Git просто содержит коммитов , а также несколько способов найти последний коммит. Здесь два последних коммита: K
на master
и J
на feature
. Запуск git checkout <em>name</em>
или git switch <em>name</em>
дает вам последний коммит. Оттуда вы создаете новую работу и в конечном итоге запускаете git commit
, чтобы сделать новый коммит, который автоматически расширяет ту ветку, к которой прикреплено специальное имя HEAD
.
Сравните эти диаграммы
В типичной настройке Git без поставщика или настройке, при которой вы получаете весь репозиторий Git от своего поставщика, у вас будет какая-то основная ветка или ветка поставщика, а затем будет собственная филиалы, в которых вы настроили свое программное обеспечение:
...--o--o <-- main
\
o--o--o <-- customized (HEAD)
В вашем конкретном случае, когда вы получили запрос от поставщика, который мы называем V1.0
, у вас есть его дроп, который мы можем назвать vendor
, и ваши настройки:
V1.0 <-- vendor
\
o--o--o <-- customized (HEAD)
Теперь вы получаете новый дроп от продавца. Все, что вам нужно сделать сейчас, это вставить это как новый коммит поставщика в вашу ветку vendor
:
V1.0--------V1.1 <-- vendor
\
o--o--o <-- customized (HEAD)
, и вы видите типичную настройку Git, хотя и очень большой изменить на go с V1.0
на V1.1
вместо серии более мелких изменений, которые легче отлаживать, переваривать, понимать и т. д.
Единственный реальный трюк - это вставить V1.1
. Если у вас есть все имя ветки, это довольно просто, если вы не против испортить существующее дерево работы (очистить его, чтобы там не являются случайными файлами, et c):
git status # make sure everything is committed
git clean -dfx # remove all build products, etc
git checkout vendor # or `git switch vendor`
git rm -r . # remove all the old files
unzip path/to/vendor/drop # unpack the new drop
git add . # add all the new files
git commit # make a new commit on the vendor branch
git tag [options] vendor-v1.1 # optionally, tag each vendor drop too
(Есть несколько более эффективный способ сделать это с помощью операций Git более низкого уровня, и, возможно, лучше использовать отдельную работу - дерево, чтобы не вмешиваться в любую незавершенную работу - но в любом случае это можно было бы сделать с помощью инструмента vendor-import
.)
См. также Лучший способ объединить сторонний исходный код с локальными модификациями в git.