Одиночный разработчик, единственная ветвь
Даже если вы являетесь единственным разработчиком вашего проекта и (по крайней мере, пока), вы не планируете его менять, система управления версиями по-прежнему полезна. Это позволяет:
-
Вернитесь к некоторой рабочей версии. Если вы работаете над своим проектом и понимаете, что вы полностью напортачили, подход, который вы пробовали, не работает, и вы не знаете, как заставить его работать, приятно иметь возможность просто вернуться к последнему рабочему версии и начать заново.
Это означает, что вы должны совершить, т.е. сделать снимок ваших изменений, когда у вас есть рабочая версия (ну, есть исключения, см. ниже). Чтобы не потерять много работы, вы должны совершать довольно часто, лучше всего (см. Ниже), когда вы завершаете одиночную функцию, отдельную проблему или отдельную часть функции или проблемы.
Вы также хотели бы знать, что вы сделали, и то, над чем вы работали в последнее время. Это означает, что вы должны описывать каждый набор изменений (каждый фиксатор).
-
Аннотировать файл/просмотр истории. Если у вас нет идеальной памяти, иногда вам нужно знать, почему (и когда, и в случае, когда есть несколько разработчиков, и кто), вы написали заданный набор строк. Комментарии не всегда достаточно. Для этого вы можете использовать (если ваша система управления версиями предоставляет) линейные аннотации истории файлов ( или ) или другие аналогичные инструменты, такие как так называемый поиск “pickaxe” в Git, где вы выполняете поиск/просмотреть историю для коммитов, которые ввели или удалили заданную строку.
Чтобы это было полезно, вам нужно написать хорошие сообщения о совершении, описать изменение и намерение изменения, чтобы вы знали, почему было сделано изменение.
-
История поиска, чтобы найти ошибки. Современные системы управления версиями предлагают альтернативные (для вставки инструкций печати или отладчика) способ поиска ошибок… в некоторых случаях. Когда вы замечаете ошибку или получаете ошибку, и ошибка не является результатом последнего изменения, вы можете использовать систему управления версиями (), чтобы автоматически найти фиксацию, введшую ошибку (первая фиксация, которая дала ошибку), Система контроля версий находит такую фиксацию, используя биссектную историю проекта, извлекая (проверяя) версии, которые вы отмечаете как хорошие (без ошибок) или плохие, пока не найдет коммиты, которые ввели ошибку.
Для этого вы всегда должны гарантировать, что версия работает (или, по крайней мере, компилирует), прежде чем совершать ее, иначе вы не будете ebale, чтобы решить, есть ли у команды ошибка или нет. Вы должны держать коммиты маленькими (с небольшим количеством изменений), поэтому, когда вы обнаружите фиксацию, которая ввела ошибку, вам нужно будет проверить только количество бесплатных строк, затронутых изменением. Вам также понадобятся хорошие сообщения о фиксации, поэтому вы должны знать, почему было сделано изменение (и решить, правильно ли это изменение).
Инструмент 2: Pull Requests
Pull Requests — отличный способ внести свой вклад в репозиторий, сделав его форк. В конце дня, если мы хотим, мы можем отправить pull request владельцу репозитория, чтобы объединить наши изменения кода. Сам pull request может включать обсуждение качества кода, функций или даже общей стратегии.
Давайте теперь рассмотрим основные шаги для pull request.
Инициирование pull request
В Github есть две модели для pull request:
- Модель Fork & Pull — используется в общедоступном репозитории, на который у вас нет push-доступа
- Share Repository Model — используется в частном репозитории, на который у нас есть push-доступ. В этом случае форк не требуется.
Здесь мы видим рабочий процесс между двумя пользователями ( и ) для модели Fork and Pull:
- Определите репозиторий Github, в который вы хотите внести свой вклад, и нажмите кнопку «Fork», чтобы создать клон репозитория в вашей собственной учетной записи Github:
- Это создаст точную копию репозитория в вашем собственном аккаунте
- Выберите URL-адрес SSH, чтобы он запрашивал вашу парольную кодовую фразу SSH вместо имени пользователя и пароля каждый раз, когда вы делаете или . Затем мы будем клонировать этот репозиторий на наш локальный компьютер:
- Как правило, мы создадим новую ветку git для каждой новой задачи. Это хорошая практика, потому что в будущем, если мы продолжим обновление ветки после некоторых обсуждений, запрос на перенос будет автоматически обновляться. Давайте создадим новую ветку, чтобы внести очень простое изменение в файл :
- После внесения соответствующих дополнений для создания новых функций мы просто передадим новые изменения и проверку в ветку git master:
- На этом этапе мы запушим ветку в удаленный репозиторий. Для этого мы сначала перейдем на ветку с новой задачей, а так же на псевдоним для удаленного репозитория. Затем мы будем пушить изменения с помощью :
- На нашей развязанной странице Github репозитория мы перейдем к ветке с новой функцией, а затем нажмите кнопку «Pull Request».
- После отправки пул реквеста он напрямую приведет нас к странице запроса в исходном репозитории. Мы увидим наш запрос на pull.
- После обсуждения возможно, что владелец форкнутого репозитория может захотеть добавить изменения в новую функцию. В этом случае мы выберем одну и ту же ветку на нашей локальной машине, зафиксируем ее и запушим ее обратно на Github. Когда мы заходим на страницу запроса в оригинальном репозитории, он будет автоматически обновляться!
Слияние пул реквеста
Если вы являетесь владельцем оригинального репозитория, существует два способа слияния входящего пул реквеста:
- Слияние непосредственно на Github: если мы делаем слияние непосредственно на Github, то убедитесь, что нет конфликтов, и реквест готов к объединению в ведущую ветку. Владелец оригинального хранилища может просто щелкнуть зеленую кнопку «Слить запрос», чтобы сделать это:
- Слияние на наших локальных машинах: в других случаях могут возникнуть конфликты слияния, и после нажатия кнопки «Информация» у Github будут четкие инструкции о том, как мы можем объединить ветвь на нашей локальной машине, потянув за изменения из ветви контрибьютера:
Существуют различные модели создания веток, используемые для управления версиями в командах разработки программного обеспечения. Вот две популярные модели рабочего процесса git: (1) рабочий процесс Github, который имеет простую ветвящуюся модель и использует запросы на pull, и (2) Gitflow, который имеет более обширное разветвление. Модель, которая в конечном итоге будет выбрана, определенно будет меняться в зависимости от команды, проекта и ситуации.
Зачем новичку учить Git
Git используется в большинстве компаний, где над проектом работает хотя бы два разработчика:
- Новый человек приходит в компанию и клонирует репозиторий проекта на ПК.
- Получает задачу, создаёт новую ветку и пишет код.
- Когда всё готово — отправляет запрос на добавление кода в master-ветку.
- Другие разработчики смотрят код, оставляют комментарии и указывают на ошибки.
- Новичок дорабатывает код, обновляет master-ветку и переходит к следующей задаче.
Это общая схема того, как проходит командная работа в проекте. В ней не учтены правила использования Git, которые каждая команда пишет под себя. Например, у каждой команды свой порядок проверки кода и свои критерии его готовности для добавления в master-ветку.
Общее
Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит)
Важно: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (), потом «сохраняем» ()
Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые).
Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту).
Ключ к пониманию
Ключ к пониманию концепции git — знание о «трех деревьях»:
- Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете).
- Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов).
- Директория — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.).
Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать.
У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний.
Простейший цикл работ
- Редактирование, добавление, удаление файлов (собственно, работа).
- Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить).
- Коммит (фиксация изменений).
- Возврат к шагу 1 или отход ко сну.
Указатели
- — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим.
- — указатель на коммит, с которого вы только что переместили (командой , например).
- Ветка (, etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый.
- Теги — простые указатели на коммиты. Не перемещаются.
Перед началом работы нужно выполнить некоторые настройки:
Если вы в Windows:
Длинный вывод в консоли: Vim
Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w.
# Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти ```bash # Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти # Ввод в командном режиме :q! — выйти без сохранения :wq — сохранить файл и выйти :w filename.txt — сохранить файл как filename.txt
Tree-ish
Понятие tree-ish часто используется в документации по git. Tree-ish – это то, что указывает на коммит, эту сущность мы можем передавать в качестве аргумента для команд git. Вот список того, чем может являться tree-ish.
---------------------------------------------------------------------- | Tree-ish | Examples ---------------------------------------------------------------------- | 1. <sha1> | dae86e1950b1277e545cee180551750029cfe735 | 2. <describeOutput> | v1.7.4.2-679-g3bee7fb | 3. <refname> | master, heads/master, refs/heads/master | 4. <refname>@{<date>} | master@{yesterday}, HEAD@{5 minutes ago} | 5. <refname>@{<n>} | master@{1} | 6. @{<n>} | @{1} | 7. @{-<n>} | @{-1} | 8. <refname>@{upstream} | master@{upstream}, @{u} | 9. <rev>^ | HEAD^, v1.5.1^0 | 10. <rev>~<n> | master~3 | 11. <rev>^{<type>} | v0.99.8^{commit} | 12. <rev>^{} | v0.99.8^{} | 13. <rev>^{/<text>} | HEAD^{/fix nasty bug} | 14. :/<text> | :/fix nasty bug | 15. <rev>:<path> | HEAD:README.txt, master:sub-directory/ ---------------------------------------------------------------------- Рассмотрим работу с tree-ish на примере команды git show.
> git show cf3d9d8f -q commit cf3d9d8f7b283267a085986e85cc8f152cca420d Author: Writer <[email protected]> Date: Mon Mar 5 23:21:59 2018 +0500 ignore .tmp files > git show -q HEAD commit cf3d9d8f7b283267a085986e85cc8f152cca420d Author: Writer <[email protected]> Date: Mon Mar 5 23:21:59 2018 +0500 ignore .tmp files > git show -q master commit cf3d9d8f7b283267a085986e85cc8f152cca420d Author: Writer <[email protected]> Date: Mon Mar 5 23:21:59 2018 +0500 ignore .tmp files > git show -q @{5} commit cf3d9d8f7b283267a085986e85cc8f152cca420d Author: Writer <[email protected]> Date: Mon Mar 5 23:21:59 2018 +0500 ignore .tmp files
Во всех примерах, представленных выше, команде git show мы передаем различные tree-ish, которые на самом деле указывают на одно и тоже место – последний коммит.
<<< Часть 6. Просмотр информации по коммитам Часть 8. Добавление, удаление и переименование файлов в репозитории>>>
HEAD
Начнем с HEAD. HEAD – это указатель, задача которого ссылаться на определенный коммит в репозитории. Суть данного указателя можно попытаться объяснить с разных сторон.
Во-первых,HEAD – это указатель на коммит в вашем репозитории, который станет родителем следующего коммита. Для того, чтобы лучше понять это, обратимся к репозиторию, созданному в рамках предыдущей статьи, в этом репозитории сделано шесть коммитов, посмотрим на них.
> git log --oneline cf3d9d8 ignore .tmp files a7b88ee : git ignore file c185b80 : header for main 2b826bb : main file of programm bc067c8 : caption into README file a98cce4
Эти коммиты создавались в порядке от самого нижнего (a98cce4) к самому верхнему (cf3d9d8). Каждый раз, когда мы отправляли новый коммит в репозиторий, HEAD смещался и указывал на него. Посмотрите на картинку ниже: на ней показана ситуация, когда были отправлены три первых коммита.
После того как вы отправили коммит с id = 2b826bb, указатель HEAD стал показывать на него, т.е. данный коммит будет родителем для следующего, и когда мы сделаем еще один коммит, HEAD сместится.
Во-вторых,HEAD указывает на коммит, относительного которого будет создана рабочая копия во-время операции checkout. Другими словами, когда вы переключаетесь с ветки на ветку (о ветвлении в git будет рассказано в одной из ближайших статей), используя операцию checkout, то в вашем репозитории указатель HEAD будет переключаться между последними коммитами выбираемых вами ветвей.
В нашем репозитории пока только одна ветвь – master, но и этого будет достаточно, чтобы показать зависимость между положением указателя HEAD и операцией checkout.
Текущее состояние репозитория выглядит так, как показано на рисунке ниже.
Для того, чтобы скопировать снимок репозитория относительно последнего коммита ветки master, т.е. того на который указывает HEAD, необходимо выполнить следующую команду.
> git checkout master Switched to branch 'master'
Содержимое репозитория, в данном случае, выглядит так.
> git log --oneline cf3d9d8 ignore .tmp files a7b88ee : git ignore file c185b80 : header for main 2b826bb : main file of programm bc067c8 : caption into README file a98cce4
Теперь передвинем указатель HEAD на коммит с id=2b826bb.
Для этого передадим команде checkout идентификатор коммита.
> git checkout 2b826bb Note: checking out '2b826bb'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at 2b826bb... : main file of programm
Обратите внимание на текст, который напечатал git, после того, как была выполнена эта команда. Нас интересует самая последняя строка “HEAD is now at 2b826bb…”, теперь HEAD указывает на коммит с id=2b826bb – именно то, что мы хотели
Посмотрим на текущий список коммитов.
> git log --oneline 2b826bb : main file of programm bc067c8 : caption into README file a98cce4
Git выводит коммиты, которые были сделаны до того коммита, на который ссылается HEAD.
Вернем HEAD на прежнее место.
> git checkout cf3d9d8 Previous HEAD position was 2b826bb... : main file of programm HEAD is now at cf3d9d8... ignore .tmp files > git log --oneline cf3d9d8 ignore .tmp files a7b88ee : git ignore file c185b80 : header for main 2b826bb : main file of programm bc067c8 : caption into README file a98cce4
Все вернулось на прежнее место. Таким образом, вы можете получать в виде рабочей копии содержимое репозитория на момент отправки того или иного коммита. Перейдем в каталог .git, в котором находится наш репозиторий, он расположен в корневой директории нашего проекта, и посмотрим его содержимое.
> cd .git > ls -la total 21 drwxr-xr-x 1 User 197121 0 мар 18 17:10 ./ drwxr-xr-x 1 User 197121 0 мар 18 17:10 ../ -rw-r--r-- 1 User 197121 24 мар 5 23:21 COMMIT_EDITMSG -rw-r--r-- 1 User 197121 184 мар 5 23:10 config -rw-r--r-- 1 User 197121 73 мар 5 23:10 description -rw-r--r-- 1 User 197121 41 мар 18 17:10 HEAD drwxr-xr-x 1 User 197121 0 мар 5 23:10 hooks/ -rw-r--r-- 1 User 197121 441 мар 18 17:10 index drwxr-xr-x 1 User 197121 0 мар 5 23:10 info/ drwxr-xr-x 1 User 197121 0 мар 5 23:10 logs/ drwxr-xr-x 1 User 197121 0 мар 5 23:21 objects/ drwxr-xr-x 1 User 197121 0 мар 5 23:10 refs/
В данном каталоге содержится файл HEAD, в нем находится идентификатор, на который ссылается данный указатель. Посмотрим содержимое файла HEAD.
> cat HEAD cf3d9d8f7b283267a085986e85cc8f152cca420d
HEAD указывает на коммит cf3d9d8.
Необходимость контроля версий
В команде разработчиков каждый человек должен иметь возможность получить доступ к текущей версии проекта. Они также должны быть в состоянии работать на этой версии в индивидуальном порядке; код не является библиотекой книг, которая может заимствованы, изменилось, а затем положить обратно. Каждый член команды должен иметь доступ, когда это необходимо, а не ждать, пока код должен быть возвращен, прежде чем они смогут увидеть последнюю версию.
Основная проблема с двумя разработчиками работают над одним проектом в то же время является то, что каждый последующий разработчик будет сохранить проект и таким образом отменить все изменения, сделанные ранее, без записи их. Контроль версий позволяет разработчикам получить доступ к проекту и работать на нем в то время как другие делают то же самое. После того, как они завершили свою работу, он будет отправлен обратно в хранилище с изменениями, объединены в систему управления версиями.
Что это означает, есть копия каждой версии доступна для разработчиков. В случае смены не работают так, как должно, вы просто вернуться к предыдущей версии и начать все заново. Вам не нужно, чтобы получить доступ ко всем изменениям и удалить их, чтобы вернуться к предыдущему состоянию развития
История Кодекс имеет важное значение, и без контроля версий не было бы ни одного