Skip to content

Conversation

tigermun
Copy link
Member

@tigermun tigermun commented Feb 7, 2025

Выполнены 1-3 пункт issue SENATOROVAI/intro-cs#1: в файле git.ipynb сделан конспект главы про Git из книги Эла Свейгарта "Чистый код".
Closes SENATOROVAI/intro-cs#1 (https://github.com/SENATOROVAI/intro-cs/issues/1)

Closes #22 (https://github.com/SENATOROVAI/docs/issues/22)
В файле git.ipynb сделан конспект главы про Git из книги Эла Свейгарта "Чистый код"
Copy link
Member Author

@tigermun tigermun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сабмичу

Comment on lines +1 to +368
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"Git и организация программных проектов.\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Системы контроля версий представляют собой программные средства, которые регистрируют все изменения в исходном коде и позволяют легко восст\n",
"\n",
"Система контроля версий управляет файлами при внесении в них изменений\n",
"\n",
"Git, Mercurial и Subversion — популярные приложения контроля версий, хотя система Git остается самой популярной\n",
"\n",
"\n",
"### Коммиты и репозитории\n",
"\n",
"Git позволяет сохранить состояние файлов проекта при внесении в них изменений. Такие сохранения называются снимками (snapshots) или коммитами (commits).\n",
"\n",
"Система контроля версий управляет исходным кодом проекта, который хранится в специальной папке — репозитории (repo).\n",
"\n",
"\n",
"### Создание новых проектов Python с использованием Cookiecutter\n",
"\n",
"В терминологии Git папка, содержащая весь исходный код, документацию, тесты и другие файлы, относящиеся к проекту, называется рабочим каталогом или рабочим деревом, а в более общей терминологии — папкой проекта. Файлы в рабочем каталоге в совокупности называются рабочей копией.\n",
"\n",
"Для проектов Python действуют определенные соглашения по поводу имен папок и иерархий. Более простая программа может содержать один файл .py. Но когда проекты усложнятся, в них будут включаться дополнительные файлы .py, файлы данных, документация, модульные тесты и т. д. Как правило, корневая папка проекта содержит папку src для файлов с исходным кодом .py, папку tests для модульных тестов и папку docs для документации (например, сгенерированной системой документирования Sphinx). Другие файлы содержат информацию о проекте и конфигурации системы\n",
"\n",
"Чтобы ускорить выполнение рутинных операций, можно использовать модуль Python cookiecutter для автоматического создания этих файлов и папок. Полная документация по модулю и программе командной строки Cookiecutter доступна на https://cookiecutter.readthedocs.io/.\n",
"\n",
"Чтобы установить Cookiecutter, выполните команду pip install --user cookiecutter\n",
"(в системе Windows) или pip3 install --user cookiecutter (в macOS и Linux).\n",
"\n",
"```powershell\n",
"pip install --user cookiecutter\n",
"```\n",
"\n",
"Модуль cookiecutter использует шаблоны для создания начальных файлов для различных видов проектов. Часто шаблон представляет собой простую ссылку на GitHub.com\n",
"\n",
"```powershell\n",
"python -m cookiecutter gh:asweigart/cookiecutter-basicpythonproject\n",
"```\n",
"\n",
"В разделе https://github.com/cookiecutter/cookiecutter вы найдете шаблоны для многих языков программирования. Так как шаблоны Cookiecutter часто размещаются на GitHub, вы также можете ввести gh: как сокращение для https://github.com/ в аргументе командной строки.\n",
"\n",
"\n",
"### Установка Git\n",
"\n",
"Git уже установлена на компьютере. Чтобы узнать это, вводим команду ```git --version``` в командной строке. Если получаем сообщение вида ```git version 2.29.0.windows.1```, значит, программная поддержка Git уже установлена. Если сообщение «команда не найдена» - Git придется установить (в системе Windows перейдите на страницу https://git-scm.com/download, загрузите и запустите программу установки Git; в Ubuntu или Debian Linux выполните команду sudo apt install git-all из окна терминала).\n",
"\n",
"\n",
"### Работа с Git\n",
"\n",
"Работа с репозиторием Git состоит из нескольких этапов:\n",
"\n",
"1. Создание репозитория Git:\n",
" + командой git init инициализируем гит в новом проекте\n",
" + командой git clone <url> копируем удалённый репозиторий на локальную машину\n",
"2. Добавление файлов в репозиторий для отслеживания:\n",
" + командой git add <имя_файла>\n",
"3. Сохранение файлов:\n",
" + командой git commit -am \"<сообщение, описывающее содержание коммита>\"\n",
"\n",
"Справку по каждой из этих команд можно посмотреть командой git help <команда> — например, git help init или git help add.\n",
"\n",
"\n",
"### Как Git отслеживает статус файлов\n",
"\n",
"1. Отслеживаемые файлы:\n",
" + В **сохраненном** (закрепленном) состоянии файл в рабочей копии идентичен последнему коммиту в репозитории. (Иногда это состояние называется неизмененным, или чистым.)\n",
" + В **измененном** состоянии файл в рабочей копии отличается от последнего коммита в репозитории.\n",
" + В **индексированном**, или подготовленном (staged), состоянии файл был изменен и помечен для включения в следующий коммит. Также говорят, что файл находится в индексной области (или кэше).\n",
"2. Неотслеживаемые файлы:\n",
" + Для репозитория Git **неотслеживаемые** файлы в рабочей копии не существуют\n",
" + Для перехода в отслеживаемого необходимо добавить его с помощью команды git add\n",
"\n",
"Переход файла между четырьмя возможными состояниями\n",
"\n",
"1. Добавляем **неотслеживаемый** файл в репозиторий Git, после чего он становится отслеживаемым и **индексированным**\n",
"2. Сохраняем **индексированные** файлы, чтобы перевести их в **индексированное** состояние\n",
"3. Для перевода файла в измененное состояние никакие команды Git не нужны; как только файл изменяется, он автоматически помечается как **измененный**\n",
"\n",
"На любом этапе после создания репозитория выполните команду ```git status``` для\n",
"просмотра текущего статуса репозитория и состояния его файлов\n",
"\n",
"\n",
"### Для чего нужно индексирование?\n",
"\n",
"С технической точки зрения область индексирования содержит не столько файлы,\n",
"сколько описания изменений. Это может привести к следующим особым случаям:\n",
"\n",
"+ файл может быть изменен после того, как он был проиндексирован, в результате чего файл существует как в измененном, так и в индексированном состоянии\n",
"+ одни части измененного файла могут быть индексированы, а другие — нет\n",
"\n",
"Чтобы избежать сложностей, необходимо использовать команду ```git commit -am``` для индексирования и закрепления измененных файлов на одном шаге. В этом случае файлы переходят из измененного состояния сразу же в чистое.\n",
"\n",
"\n",
"#### Создание репозитория Git на компьютере\n",
"\n",
"Git является распределенной системой контроля версий. Это приводит к следующиму:\n",
"+ коммиты и метаданные репозиториев хранятся локально на компьютере в папке с именем .git.\n",
"+ не нужно подключаться к серверу по интернету для сохранения данных\n",
"+ Git работает быстро и остается доступной при автономной работе\n",
"\n",
"Сценарий создания локального репозитория\n",
"1. Создаём папку с проектом, если нет:\n",
"\n",
" + Windows:\n",
" ```powershell\n",
" md project\n",
" ```\n",
"\n",
" + Linux, MacOS:\n",
" ```bash\n",
" mkdir project\n",
" ```\n",
"\n",
"2. Заходим в папку проекта:\n",
"\n",
" ```bash\n",
" cd project\n",
" ```\n",
"\n",
"3. Инициализируем гит-репозиторий:\n",
"\n",
" ```bash\n",
" git init\n",
" ```\n",
"\n",
"Для папки project команда ```git init``` создает папку ```project/.git``` с метаданными репозитория Git. Имя ```.git``` присваивается ей из-за того, что многие операционные системы автоматически скрывают папки и файлы, имена которых начинаются с точки.\n",
"Все файлы в папке ```project``` в исходном состоянии являются _неотслеживаемыми_.\n",
"\n",
"Репозиторий на нашем компьютере называется локальным; репозиторий на другом компьютере называется удаленным.\n",
"\n",
"После того как репозиторий будет создан, команда git может использоваться для добавления файлов и отслеживания изменений в рабочем каталоге. Выполнив команду git status в созданном репозитории, мы увидим, что в репозитории еще ничего не сохранено.\n",
"\n",
"\n",
"#### Добавление файлов для отслеживания\n",
"\n",
"Только отслеживаемые файлы можно сохранять, откатывать к предыдущей версии или выполнять иные операции командой git.\n",
"\n",
"Процесс сохранения файлов в репозиториии состоит из двух этапов:\n",
"1. Выполнение команды ```git add``` для каждого сохраняемого файла\n",
"2. Выполнение команды ```git commit``` для создания коммитов всех этих файлов.\n",
"После того как файл будет сохранен, Git начинает его отслеживать.\n",
"\n",
"Команда ```git add``` переводит файлы из неотслеживаемого или измененного состояния в индексированное состояние. Можно выполнить команду git add для каждого файла, который нужно проиндексировать, перечислив названия файлов после команды, но лучше воспользоваться подстановочным символом * для добавления сразу нескольких файлов. Например, команда git add *.py добавляет все файлы .py из текущего рабочего каталога и его подкаталогов. Чтобы добавить все неотслеживаемые файлы, используйте точку (git add .)\n",
"\n",
"Команда ```git commit -m \"Adding new files to the repo.\"``` сохраняет все выбранные в команде ```git add``` файлы в репозитории.\n",
"\n",
"Файлы, перечисленные в файле .gitignore, не включаются в индексирование.\n",
"\n",
"\n",
"#### Игнорирование файлов в репозитории\n",
"\n",
"В процессе написания кода некоторые файлы можно исключить из системы контроля версий, чтобы предотвратить их случайное отслеживание. К этой категории относятся:\n",
"+ временные файлы в папке проекта;\n",
"+ файлы .pyc, .pyo и .pyd, генерируемые интерпретатором Python при выполнении программ .py;\n",
"+ папки .tox, htmlcov и другие папки, генерируемые различными средствами разработчика;\n",
"+ другие откомпилированные или сгенерированные файлы, которые можно сгенерировать заново (потому что репозиторий предназначен для исходных файлов, а не для производных файлов, которые генерируются на их основе);\n",
"+ файлы с исходным кодом, содержащие пароли баз данных, маркеры аутентификации, номера кредитных карт или другие конфиденциальные данные.\n",
"\n",
"Перечисленные в файле с именем .gitignore файлы и папки не отслеживаются Git. Git автоматически исключает их из команд ```git ad```d или ```git commit```, и они не будут отображаться при выполнении команды ```git status```. В файле .gitignore символ * используется для шаблонов, а # — для комментариев.\n",
"\n",
"Файл .gitignore следует добавить в репозиторий Git, чтобы он был у других программистов, клонировавших репозиторий.\n",
"\n",
"Команда ```git ls-files --other --ignored --exclude-standard``` позволяет просмотреть список игнорируемых файлов на основании настроек в .gitignore\n",
"\n",
"\n",
"#### Сохранение изменений\n",
"\n",
"```git add .``` + ```git commit -m <сообщение>``` = ```git commit -am <сообщение>``` - созраним все изменения в репозитории\n",
"```git commit -m <сообщение> file1.py file2.py``` сохраним изменения только в выбранных файлах\n",
"\n",
"Не поддавайтесь искушению написать короткое обобщенное сообщение вида «Обновленный код», «Исправлены некоторые ошибки» или просто «x» (потому что пустые сообщения запрещены). Через три недели, когда вам захочется вернуться к более ранней версии вашего кода, подробные сообщения в каждом коммите сэкономят вам немало времени, когда вы будете выбирать, к какой именно версии следует вернуться.\n",
"\n",
"Если забыли написать сообщение коммита, открывшееся в этом случае окно Vim закрываем (Esc -> ввод qa! -> Enter) и коммитим заново с вводом сообщения\n",
"\n",
"Хороший пример коммитов - веб-фреймворк Django (https://github.com/django/jango/commits/master. Так как Django является большим проектом с открытым кодом, коммиты выполняются часто, а сообщения коммитов формализованы.\n",
"\n",
"В репозитории Git нельзя сохранять папки. Git автоматически включает папки в репозитории при сохранении хранящихся в них файлов, но сохранить пустую папку не получится.\n",
"\n",
"Если допущена ошибка в последнем сообщении коммита, его можно переписать командой ```git commit --amend -m \"<новое_сообщение>\"```\n",
"\n",
"\n",
"#### Просмотр изменений перед коммитом\n",
"\n",
"Для просмотра различий между рабочей копией кода и последним сохраненным кодом можно воспользоваться командой ```git diff command```. В отчёте команды строки, начинающиеся со знака '-', были удалены; строки, начинающиеся со\n",
"знака '+', были добавлены.\n",
"\n",
"\n",
"#### Просмотр изменений в графическом приложении командой git difftool\n",
"\n",
"Изменения проще просматривать в программе с графическим интерфейсом:\n",
"\n",
"+ для Windows можно загрузить ```WinMerge``` (https://winmerge.org/)\n",
"+ в Linux можно установить:\n",
" + ```Meld```\n",
" ```bash\n",
" sudo apt-get install meld\n",
" ```\n",
" + ```Kompare```\n",
" ```bash\n",
" sudo apt-get install kompare\n",
" ```\n",
"+ macOS для установки программы ```tkdiff``` необходимо установить Homebrew (менеджер пакетов для установки программ), а затем с помощью Homebrew установить ```tkdiff```:\n",
" ```bash\n",
" /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/\n",
" master/install.sh)\"\n",
" brew install tkdiff\n",
" ```\n",
"\n",
"Командой ```git config diff.tool <название приложения>``` настраиваем Git для использования приложение ```winmerge```, ```tkdiff```, ```meld``` или ```kompare```\n",
"\n",
"Чтобы система Git не запрашивала подтверждения каждый раз, когда запускаем программу просмотра изменений, настраиваем Git командой ```git config --global difftool.prompt false```\n",
"\n",
"\n",
"#### Частота сохранения изменений\n",
"\n",
"Код следует сохранять:\n",
"1. При завершении блока функциональности, класса\n",
"2. Исправления ошибки\n",
"\n",
"Не следует сохранять код:\n",
"1. Содержащий синтаксические ошибки\n",
"2. Неработоспособный\n",
"\n",
"Всегда выполняйте все модульные тесты перед сохранением. В идеале все тесты должны проходить (а если они не проходят, упомяните об этом в сопроводительном сообщении)\n",
"\n",
"\n",
"#### Удаление файлов из репозитория\n",
"\n",
"Рекомендуется удалять файл из папки проекта и репозитория командой ```git rm <название файла>```. Это равносильно простому удалению файла из папки проекта (```rm/del <название файла>```) с добавлением этого изменения в проекте в индекс с помощью команды ```git add <название файла>```.\n",
"\n",
"Команда ```git rm``` работает только с файлами, находящимися в чистом, сохраненном, состоянии без каких-либо изменений. В противном случае Git предложит сохранить изменения или отменить их командой ```git reset HEAD <имя_файла>```\n",
"\n",
"\n",
"#### Переименование и перемещение файлов из репозитория\n",
"\n",
"Команда ```git mv``` показывает гиту, что файл был переименован/перемещён, а не удалён и создан новый файл с тем же содержимым, что и удалённый.\n",
"\n",
"\n",
"### Просмотр журнала коммитов\n",
"\n",
"Команда ```git log``` выводит список всех коммитов с подробным описанием каждого.\n",
"\n",
"Хеш коммита — строка из 40 шестнадцатеричных цифр (0–9 и буквы A–F), которая\n",
"служит уникальным идентификатором коммита (yа практике обычно используются только первые семь знаков)\n",
"\n",
"Чтобы вернуться к более старому коммиту, надо заранее узнать его хеш с помощью команды ```git log```.\n",
"\n",
"Ключ ```--oneline``` укорачивает вывод до сокращенных хешей и первой строки каждого сообщения коммита, ведь со временем журнал может стать очень длинным.\n",
"```bash\n",
"git log --oneline```\n",
"```\n",
"\n",
"Чтобы вывести содержимое файла на момент конкретного коммита, можно задать команду ```git show <хеш>:<имя_файла>```\n",
"\n",
"\n",
"### Восстановление старых изменений\n",
"\n",
"Система контроля версий позволяет вернуть рабочую копию к состоянию более раннего коммита. Конкретная команда зависит от состояния файлов в рабочей копии.\n",
"\n",
"\n",
"#### Отмена несохраненных локальных изменений\n",
"\n",
"Команда ```git restore<имя_файла>``` возвращает выбранный файл к состоянию, сохранённому в последнем коммите. Фактически это операция отмены изменений, внесенных в файл (который еще не был проиндексирован или сохранен).\n",
"\n",
"Важно: невозможно отменить эту «отмену», чтобы вернуть последние изменения\n",
"\n",
"Хотя Ctrl+z в открытом файле сработает:)\n",
"\n",
"\n",
"#### Деиндексирование проиндексированного файла\n",
"\n",
"Команда ```git restore --staged <имя_файла>``` исключает выбранный файл из списка индексированных файлов\n",
"\n",
"\n",
"#### Отмена последних коммитов\n",
"\n",
"Команда ```git revert -n HEAD~<количество коммитов назад относительно текущего>..HEAD``` отменяет конкретное число последних коммитов\n",
"\n",
"Репозитории Git обычно только добавляют информацию, поэтому при отмене коммитов они остаются в истории коммитов. Если потребуется «отменить отмену», можно снова вернуться к нужному состоянию командой ```git revert```.\n",
"\n",
"\n",
"#### Возврат к конкретному коммиту для отдельного файла\n",
"\n",
"Команда ```git show <хеш>: <имя_файла>``` выведет выбранный файл в состоянии, соответствующем коммиту с введённым хешем.\n",
"\n",
"Команда ```git checkout <хеш> -- <имя_файла>``` вернёт содержимое выбранного файла в состоянии, соответствующем коммиту с введённым хешем. Эта команда изменяет только рабочую копию. Чтобы сохранить изменения нужно проиндексировать и закоммитить этот файл.\n",
"\n",
"\n",
"#### Перезапись истории коммитов\n",
"\n",
"Если случайно сохранён файл, содержащий конфиденциальную информацию (пароли, ключи API, номера кредитных карт), недостаточно вычеркнуть эту информацию и создать новый коммит. Каждый, кто имеет доступ к репозиторию на компьютере или к удаленному репозиторию, сможет вернуться к версии, содержащей эту информацию.\n",
"\n",
"Удалить информацию из репозитория так, чтобы ее было невозможно восстановить, непросто, но возможно:\n",
"\n",
"1. командой git filter-branch\n",
"2. программой [BFG Repo-Cleaner](https://help.github.com/en/articles/removing-sensitivedata-from-a-repository.)\n",
"\n",
"Простейшая превентивная мера — разместить конфиденциальную информацию в файле с именем secrets.txt, conidential.py или что-нибудь в этом роде. Файл включается в .gitignore, чтобы он никогда не был сохранен в репозитории.\n",
"\n",
"\n",
"#### GitHub и команда git push\n",
"\n",
"Mногие бесплатные веб-сайты позволяют размещать клоны локальных репозиториев в интернете, чтобы другие люди могли легко загрузить проекты и участвовать в работе над ними. Самый большой из таких сайтов — GitHub.\n",
"\n",
"Плюсы:\n",
"+ другие люди могут участвовать в работе над проектом\n",
"+ коллеги смогут дополнять код, даже если компьютер с локальным репозиторием отключен\n",
"+ клонированная копия фактически выполняет роль резервной копии\n",
"\n",
"**ПРИМЕЧАНИЕ**\n",
"Чтобы избежать путаницы с терминами: Git — система контроля версий, которая поддерживает репозиторий и включает команду git. GitHub — веб-сайт для размещения репозиториев Git в интернете.\n",
"\n",
"Веб-страница для репозиториев будет располагаться по адресу https://github.com/<имя_пользователя>/<имя_репозитория>\n",
"\n",
"\n",
"#### Отправка существующего репозитория на GitHub\n",
"\n",
"Команда ```git remote add origin https://github.com/<имя_пользователя>/<имя_репозитория>``` добавляет GitHub как удаленный репозиторий, соответствующий локальному репозиторию. \n",
"\n",
"Команда ```git push -u origin master``` отправляет все изменения, внесенные в локальном репозитории, в удаленный.\n",
"\n",
"Следующие коммиты можно отправлять командой ```git push```\n",
"\n",
"Хорошая практика - отправлять копии на GitHub после каждого коммита: она гарантирует синхронизацию удаленного репозитория на GitHub с локальным репозиторием. Однако, она не обязательна.\n",
"\n",
"\n",
"#### Клонирование существующего репозитория GitHub\n",
"\n",
"Можно создать новый репозиторий на GitHub и клонировать его на компьютер. Для этого необходимо при создании нового репозитория на веб-сайте GitHub установить флажок ```Initialize this repository with a README```.\n",
"\n",
"Команда ```git clone <repo url>``` позволяет клонировать репозиторий на локальный компьютер. Url репозитория можно получить на странице репозитория на GitHub, щелкнув на кнопке Clone или Download: откроется окно с URL-адресом вида https://github.com/<пользователь_github>/<название репозитория>.\n",
"\n",
"Команда ```git clone``` также пригодится в том случае, если ваш локальный репозиторий оказался в состоянии, когда не ясно, что с ним делать и как отказаться от последних изменений. И хотя такое решение далеко не идеально, всегда можно сохранить копию файлов в рабочем каталоге, удалить локальный репозиторий и воспользоваться командой git clone для повторного создания репозитория.\n",
"\n",
"\n",
"### Итоги\n",
"\n",
"Две бесплатные книги, которые можно найти в интернете:\n",
"1. [«Pro Git» Скотта Чаркона (Scott Charcon)](https://git-scm.com/book/en/v2)\n",
"2. [«Version Control by Example» Эрика Синка (EricSink)](https://ericsink.com/vcbe/index.html)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сделай ревью, пожалуйста

valkl777 added a commit to valkl777/git that referenced this pull request Mar 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants