Советы по Git#
Перебазирование на main#
Это обновляет вашу ветку функций изменениями из вышестоящего SciPy 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 copule 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 :my-unwanted-branch
(Обратите внимание на двоеточие : до test-branch. См. также:
guides/remove-a-remote-branch
Несколько человек, совместно использующих один репозиторий#
Если вы хотите работать над чем-то с другими людьми, где вы все коммитите в один и тот же репозиторий или даже в одну и ту же ветку, просто поделитесь им через github.
Сначала форкните SciPy в свой аккаунт, как описано в Создание собственной копии (форка) SciPy.
Затем перейдите на страницу вашего форка на GitHub, скажем
https://github.com/your-user-name/scipy
Нажмите кнопку 'Admin' и добавьте других пользователей в репозиторий как соавторов:
Теперь все эти люди могут делать:
git clone git@github.com:your-user-name/scipy.git
Помните, что ссылки, начинающиеся с git@ используют протокол ssh и доступны для чтения-записи; ссылки, начинающиеся с git:// только для чтения.
Ваши коллабораторы могут затем коммитить напрямую в этот репозиторий с обычными:
git commit -am 'ENH - much better code'
git push origin my-feature-branch # pushes directly into your repo
Исследование вашего репозитория#
Чтобы увидеть графическое представление веток и коммитов репозитория:
gitk --all
Чтобы увидеть линейный список коммитов для этой ветки:
git log
Вы также можете посмотреть на визуализатор сетевого графа для вашего github репозиторий.
Обратный порт#
Бэкпортинг — это процесс копирования новых функций/исправлений, зафиксированных в
scipy/main обратно в стабильные ветки релизов. Для этого вы создаете ветку
от ветки, в которую выполняете обратный порт, и выбираете нужные коммиты из
scipy/main, а затем отправить pull request для ветки, содержащей обратный порт.
Сначала вам нужно создать ветку, над которой будете работать. Она должна быть основана на старой версии SciPy (не main):
# Make a new branch based on scipy/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.
Отправка изменений в основной репозиторий#
Это актуально только если у вас есть права на коммит в основной репозиторий SciPy.
Когда у вас есть набор "готовых" изменений в ветке feature, готовых для SciPy 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 чтобы сначала проверить,
что вы собираетесь отправить нужные изменения в нужное место.