Рабочий процесс разработки#
У вас уже есть собственная форкнутая копия репозитория NumPy, вы настроили Git и связали вышестоящий репозиторий, как объяснено в Привязка вашего репозитория к вышестоящему репозиторию. Ниже описывается рекомендуемый рабочий процесс с Git.
Базовый рабочий процесс#
Короче говоря:
Начать новый ветка функциональности для каждого набора правок, которые вы делаете. См. ниже.
Взламывайте! См. ниже
По завершении:
Участники: отправьте вашу ветку функций в ваш собственный репозиторий Github, и создать pull request.
Основные разработчики: Если вы хотите отправить изменения без дальнейшего ревью, см. примечания ниже.
Такой способ работы помогает сохранять работу хорошо организованной и историю как можно более ясной.
Создание новой ветки функций#
Сначала получите новые коммиты из upstream репозиторий:
git fetch upstream
Затем создайте новую ветку на основе основной ветки репозитория upstream:
git checkout -b my-new-feature upstream/main
Рабочий процесс редактирования#
Обзор#
# hack hack
git status # Optional
git diff # Optional
git add modified_file
git commit
# push the branch to your own Github repo
git push origin my-new-feature
Более подробно#
Внесите некоторые изменения. Когда вы почувствуете, что сделали полный, рабочий набор связанных изменений, переходите к следующим шагам.
Опционально: Проверьте, какие файлы изменились с помощью
git status. Вы увидите список, подобный этому:# On branch my-new-feature # Changed but not updated: # (use "git add
..." to update what will be committed) # (use "git checkout --..." to discard changes in working directory) # # modified: README # # Untracked files: # (use "git add..." to include in what will be committed) # # INSTALL no changes added to commit (use "git add" and/or "git commit -a")Опционально: Сравните изменения с предыдущей версией, используя
git diff. Это открывает простой текстовый интерфейс браузера, который подсвечивает разницу между вашими файлами и предыдущей версией.Добавьте все соответствующие изменённые или новые файлы с помощью
git add modified_file. Это помещает файлы в промежуточную область, которая является очередью файлов, которые будут добавлены в ваш следующий коммит. Добавляйте только файлы, которые имеют связанные, завершенные изменения. Оставляйте файлы с незавершенными изменениями для последующих коммитов.Чтобы зафиксировать подготовленные файлы в локальной копии вашего репозитория, выполните
git commit. На этом этапе откроется текстовый редактор, чтобы позволить вам написать сообщение коммита. Прочитайте раздел сообщения коммита чтобы убедиться, что вы пишете правильно отформатированное и достаточно подробное сообщение о коммите. После сохранения вашего сообщения и закрытия редактора ваш коммит будет сохранён. Для тривиальных коммитов короткое сообщение о коммите может быть передано через командную строку с использованием-mфлагом. Например,git commit -am "ENH: Some message".В некоторых случаях вы увидите эту форму команды commit:
git commit -a. Дополнительный-aфлаг автоматически фиксирует все измененные файлы и удаляет все удаленные файлы. Это может сэкономить вам набор многочисленныхgit addкоманды; однако она может добавить нежелательные изменения в коммит, если вы будете неосторожны.Отправьте изменения в ваш форк на GitHub:
git push origin my-new-feature
Примечание
Предполагая, что вы следовали инструкциям на этих страницах, git создаст ссылку по умолчанию на ваш репозиторий GitHub под названием origin. Вы можете гарантировать, что ссылка на origin установлена постоянно, используя
--set-upstream опция:
git push --set-upstream origin my-new-feature
Отныне git будет знать, что my-new-feature связано с
my-new-feature ветку в вашем собственном репозитории GitHub. Последующие вызовы push затем упрощаются до следующего:
git push
Вам необходимо использовать --set-upstream для каждой новой создаваемой ветки.
Может случиться так, что пока вы работали над своими правками, новые коммиты были
добавлены в upstream которые влияют на вашу работу. В этом случае следуйте
Перебазирование на main раздел этого документа, чтобы применить эти изменения к
вашей ветке.
Написание сообщения коммита#
Сообщения коммитов должны быть понятными и следовать нескольким базовым правилам. Пример:
ENH: add functionality X to numpy.<submodule>.
The first line of the commit message starts with a capitalized acronym
(options listed below) indicating what type of commit this is. Then a blank
line, then more text if needed. Lines shouldn't be longer than 72
characters. If the commit is related to a ticket, indicate that with
"See #3456", "See ticket 3456", "Closes #3456" or similar.
Описание мотивации изменения, характера ошибки для исправлений ошибок или
некоторых деталей о том, что делает улучшение, также хорошо включать в сообщение коммита.
Сообщения должны быть понятны без просмотра изменений кода.
Сообщение коммита, такое как MAINT: fixed another one является примером того, чего не следует делать; читателю приходится искать контекст в другом месте.
Стандартные акронимы для начала сообщения коммита:
API: an (incompatible) API change
BENCH: changes to the benchmark suite
BLD: change related to building numpy
BUG: bug fix
CI: continuous integration
DEP: deprecate something, or remove a deprecated object
DEV: development tool or utility
DOC: documentation
ENH: enhancement
MAINT: maintenance commit (refactoring, typos, etc.)
MNT: alias for MAINT
NEP: NumPy enhancement proposals
REL: related to releasing numpy
REV: revert an earlier commit
STY: style fix (whitespace, PEP8)
TST: addition or modification of tests
TYP: static typing
WIP: work in progress, do not merge
Команды для пропуска непрерывной интеграции#
По умолчанию для каждого PR запускается множество заданий непрерывной интеграции (CI), от запуска набора тестов на разных операционных системах и аппаратных платформах до сборки документации. В некоторых случаях вы уже знаете, что CI не нужен (или не весь), например, если вы работаете с файлами конфигурации CI, текстом в README или другими файлами, не участвующими в регулярных сборках, тестах или документации. В таких случаях вы можете явно пропустить CI, включив один или несколько из этих фрагментов в каждое сообщение коммита PR:
[skip ci]: пропустить все CIРекомендуется только если вы еще не готовы к запуску проверок в вашем PR (например, если это только черновик).
[skip actions]: пропустить задания GitHub ActionsGitHub Actions это место, где выполняется большинство проверок CI, включая линтер, бенчмаркинг, запуск базовых тестов для большинства архитектур и ОС, а также несколько настроек компилятора и оптимизации процессора. См. файлы конфигурации для этих проверок.
[skip circle]: пропустить задания CircleCICircleCI это место, где мы собираем документацию и храним сгенерированный артефакт для предварительного просмотра в каждом PR. Эта проверка также запустит все примеры в docstrings и проверит их результаты. Если вы не вносите изменения в документацию, но изменяете API функции, например, вам может потребоваться запустить эти тесты, чтобы убедиться, что doctests все еще действительны. Смотрите файл конфигурации для этих проверок.
[skip cirrus]: пропуск заданий CirrusCirrusCI в основном запускает загрузку колес Linux aarch64 и MacOS Arm64. Смотрите файл конфигурации для этих проверок.
Тестирование сборки колес#
NumPy в настоящее время использует cibuildwheel для сборки wheel-пакетов через сервисы непрерывной интеграции. Чтобы сэкономить ресурсы, сборщики wheel-пакетов cibuildwheel по умолчанию не запускаются при каждом PR или коммите в main.
Если вы хотите проверить, что ваш pull request не ломает сборщики wheel,
вы можете сделать это, добавив [wheel build] к первой строке сообщения коммита самого нового коммита в вашем PR. Пожалуйста, делайте это только для PR, связанных со сборкой, потому что запуск всех сборок колес медленный и дорогой.
Колёса, собранные через github actions (включая 64-битный Linux, x86-64 macOS и 32/64-битный Windows), будут загружены как артефакты в zip-файлах. Вы можете получить к ним доступ со страницы Summary действия "Wheel builder". Колёса aarch64 Linux и arm64 macOS, собранные через Cirrus CI, недоступны как артефакты. Кроме того, колёса будут загружены на https://anaconda.org/scientific-python-nightly-wheels/ при следующих условиях:
еженедельным заданием cron или
если сборка GitHub Actions или Cirrus была запущена вручную, что требует соответствующих разрешений
Сборки будут загружены на https://anaconda.org/multibuild-wheels-staging/
если сборка была запущена тегом в репозитории, который начинается с v
Получить мнение списка рассылки#
Если вы планируете новую функцию или изменение API, разумнее сначала написать в NumPy список рассылки запрашивая комментарий. Если вы не получили ответ в течение недели, можно снова написать в список рассылки.
Запрос на слияние ваших изменений с основным репозиторием#
Когда вы считаете свою работу завершенной, вы можете создать запрос на слияние (PR).
Если ваши изменения включают модификации API или добавление/изменение
функции, добавьте заметку о выпуске в doc/release/upcoming_changes/
каталог, следуя инструкциям и формату в
doc/release/upcoming_changes/README.rst файл.
Получение рецензии на ваш PR#
Мы рассматриваем запросы на включение как можно скорее, обычно в течение недели. Если вы не получите комментариев к обзору в течение двух недель, не стесняйтесь запросить обратную связь, добавив комментарий к вашему PR (это уведомит сопровождающих).
Если ваш PR большой или сложный, запрос ввода на почтовой рассылке numpy-discussion также может быть полезен.
Перебазирование на main#
Это обновляет вашу ветку feature изменениями из вышестоящего репозитория NumPy GitHub. Если вам не обязательно это делать, постарайтесь избегать этого, за исключением случаев, когда вы закончили. Первым шагом будет обновление удаленного репозитория новыми коммитами из вышестоящего:
git fetch upstream
Далее вам нужно обновить ветку feature:
# go to the feature branch
git checkout my-new-feature
# make a backup in case you mess up
git branch tmp my-new-feature
# rebase on upstream main branch
git rebase upstream/main
Если вы внесли изменения в файлы, которые также изменились в вышестоящем репозитории, это может вызвать конфликты слияния, которые нужно разрешить. См. ниже для помощи в этом случае.
Наконец, удалите резервную ветку после успешного перебазирования:
git branch -D tmp
Примечание
Предпочтительнее перебазирование на main, а не слияние upstream обратно в вашу ветку. Использование git merge и git pull не рекомендуется при работе над ветками функций.
Восстановление после ошибок#
Иногда вы путаетесь в слияниях или перебазированиях. К счастью, в Git относительно просто восстановиться после таких ошибок.
Если вы допустили ошибку во время перебазирования:
git rebase --abort
Если вы заметили ошибку после перебазирования:
# reset branch back to the saved point
git reset --hard tmp
Если вы забыли создать резервную ветку:
# look at the reflog of the branch
git reflog show my-feature-branch
8630830 my-feature-branch@{0}: commit: BUG: io: close file handles immediately
278dd2a my-feature-branch@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a my-feature-branch@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
...
# reset the branch to where it was before the botched rebase
git reset --hard my-feature-branch@{2}
Если вы на самом деле не напутали, но есть конфликты слияния, вам нужно их разрешить.
Дополнительные действия, которые вы, возможно, захотите выполнить#
Переписывание истории коммитов#
Примечание
Делайте это только для своих собственных веток функций.
В вашем коммите есть неловкая опечатка? Или, возможно, вы сделали несколько неудачных попыток, которые не хотите оставлять в истории.
Это можно сделать через интерактивный ребейзинг.
Предположим, что история коммитов выглядит следующим образом:
git log --oneline
eadc391 Fix some remaining bugs
a815645 Modify it so that it works
2dec1ac Fix a few bugs + disable
13d7934 First implementation
6ad92e5 * masked is now an instance of a new object, MaskedConstant
29001ed Add pre-nep for a couple of structured_array_extensions.
...
и 6ad92e5 является последним коммитом в main ветка. Предположим, мы
хотим внести следующие изменения:
Переписать сообщение коммита для
13d7934к чему-то более разумному.Объединить коммиты
2dec1ac,a815645,eadc391в один.
Мы делаем следующее:
# make a backup of the current state
git branch tmp HEAD
# interactive rebase
git rebase -i 6ad92e5
Это откроет редактор со следующим текстом:
pick 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
pick a815645 Modify it so that it works
pick eadc391 Fix some remaining bugs
# Rebase 6ad92e5..eadc391 onto 6ad92e5
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Чтобы достичь желаемого, мы внесем следующие изменения:
r 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
f a815645 Modify it so that it works
f eadc391 Fix some remaining bugs
Это означает, что (i) мы хотим отредактировать сообщение коммита для
13d7934, и (ii) объединить последние три коммита в один. Теперь мы сохраняем и выходим из редактора.
Git затем немедленно откроет редактор для редактирования сообщения коммита. После его изменения мы получаем вывод:
[detached HEAD 721fc64] FOO: First implementation
2 files changed, 199 insertions(+), 66 deletions(-)
[detached HEAD 0f22701] Fix a few bugs + disable
1 files changed, 79 insertions(+), 61 deletions(-)
Successfully rebased and updated refs/heads/my-feature-branch.
и история теперь выглядит так:
0f22701 Fix a few bugs + disable
721fc64 ENH: Sophisticated feature
6ad92e5 * masked is now an instance of a new object, MaskedConstant
Если что-то пошло не так, восстановление снова возможно, как объяснено выше.
Удаление ветки на GitHub#
git checkout main
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on github
git push origin --delete my-unwanted-branch
Смотрите также: https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely
Несколько человек, совместно использующих один репозиторий#
Если вы хотите работать над чем-то с другими людьми, где вы все вносите изменения в один и тот же репозиторий или даже в одну и ту же ветку, просто поделитесь им через GitHub.
Сначала форкните NumPy в свой аккаунт, как из Создание собственной копии (форка) scikit-image.
Затем перейдите на страницу вашего форка на GitHub, например,
https://github.com/your-user-name/numpy
Нажмите кнопку 'Admin' и добавьте других пользователей в репозиторий как соавторов:
Теперь все эти люди могут делать:
git clone git@github.com:your-user-name/numpy.git
Помните, что ссылки, начинающиеся с git@ используют протокол ssh и доступны для чтения-записи; ссылки, начинающиеся с git:// только для чтения.
Ваши коллабораторы могут затем коммитить напрямую в этот репозиторий с обычными:
git commit -am 'ENH - much better code'
git push origin my-feature-branch # pushes directly into your repo
Извлечение изменений из существующего pull request#
Если вы хотите протестировать изменения в pull request или продолжить работу в новом pull request, коммиты должны быть склонированы в локальную ветку вашего форкнутого репозитория.
Сначала убедитесь, что ваш upstream указывает на основной репозиторий, как в Привязка вашего репозитория к вышестоящему репозиторию
Затем извлеките изменения и создайте локальную ветку. Предполагая, что $ID это номер pull request
и $BRANCHNAME это имя новый локальный ветка, которую вы хотите создать:
git fetch upstream pull/$ID/head:$BRANCHNAME
Перейдите в новую созданную ветку:
git checkout $BRANCHNAME
Теперь у вас есть изменения в pull request.
Исследование вашего репозитория#
Чтобы увидеть графическое представление веток и коммитов репозитория:
gitk --all
Чтобы увидеть линейный список коммитов для этой ветки:
git log
Обратный порт#
Бэкпортинг — это процесс копирования новых функций/исправлений, добавленных в NumPy
main ветвление обратно в стабильные ветки релизов. Для этого вы создаете ветку от ветки, в которую выполняете обратный порт, и выбираете нужные коммиты из
numpy/main, а затем отправить pull request для ветки, содержащей обратный порт.
Сначала вам нужно создать ветку, над которой вы будете работать. Она должна быть основана на старой версии NumPy (не на main):
# Make a new branch based on numpy/maintenance/1.8.x, # backport-3324 is our new name for the branch. git checkout -b backport-3324 upstream/maintenance/1.8.x
Теперь вам нужно применить изменения из main в эту ветку, используя
git cherry-pick:# Update remote git fetch upstream # Check the commit log for commits to cherry pick git log upstream/main # This pull request included commits aa7a047 to c098283 (inclusive) # so you use the .. syntax (for a range of commits), the ^ makes the # range inclusive. git cherry-pick aa7a047^..c098283 ... # Fix any conflicts, then if needed: git cherry-pick --continue
Вы можете столкнуться с некоторыми конфликтами при выборочном слиянии здесь. Они разрешаются так же, как конфликты слияния/перебазирования. За исключением того, что здесь вы можете использовать
git blameчтобы увидеть разницу между основной и перенесенной веткой, чтобы убедиться, что ничего не испорчено.Отправьте новую ветку в ваш репозиторий Github:
git push -u origin backport-3324
Наконец, создайте pull request с помощью Github. Убедитесь, что он направлен в ветку обслуживания, а не в main, Github обычно предлагает создать pull request в main.
Отправка изменений в основной репозиторий#
Требуются права на коммит в основной репозиторий NumPy.
Когда у вас есть набор 'готовых' изменений в ветке функций, готовых для main или maintenance ветки, вы можете отправить их в upstream следующим образом:
Сначала слияние или ребейзинг на целевой ветке.
Только несколько несвязанных коммитов, тогда предпочтительнее перебазирование:
git fetch upstream git rebase upstream/main
Если все коммиты связаны, создать коммит слияния:
git fetch upstream git merge --no-ff upstream/main
Проверьте, что то, что вы собираетесь отправить, выглядит разумно:
git log -p upstream/main.. git log --oneline --graph
Отправить в upstream:
git push upstream my-feature-branch:main
Примечание
Обычно хорошая идея использовать -n флаг для git push чтобы сначала проверить,
что вы собираетесь отправить нужные изменения в нужное место.