Вместо вступления
Привет тебе, будущий Senior Software Engineer.![Начало работы с Git: подробный гайд для новичков - 1](https://cdn.javarush.com/images/article/a1d39060-a02e-4a92-9e18-1fe27245ef4f/800.jpeg)
Основы Git
Git — это распределенная система контроля версий нашего кода. Зачем она нам? Для распределенных команд нужна какая-то система управления работы. Нужна, чтобы отслеживать изменения, которые происходят со временем. То есть шаг за шагом мы видим, какие файлы изменились и как. Особенно это важно, когда анализируешь, что было проделано в рамках одной задачи: это дает возможность возвращаться назад. Представим себе ситуацию: был работающий код, всё в нем было хорошо, но мы решили что-то улучшить, там подправить, сям подправить. Все ничего, но такое улучшение поломало половину функционала, сделало невозможным работу. И что дальше? Без Гита нужно было бы часами сидеть и вспоминать, как же все было изначально. А так мы просто откатываемся на коммит назад — и все. Или что делать, если есть два разработчика, которые делают одновременно свои изменения в коде? Без Гита это выглядит так: они скопировали код из оригинала, сделали что нужно. Наступает момент, и оба хотят добавить свои изменения в главную папку. И что делать в этой ситуации?.. Я даже не берусь оценить время, чтоб проделать эту работу. Таких проблем не будет вовсе, если пользоваться Гитом.Установка Git
Установим гит на компьютер. Я понимаю, что у всех разные OS, поэтому постараюсь описать для нескольких случаев.Установка для Windows
Как обычно, нужно скачать exe файл и запустить его. Здесь все просто: жмем на первую ссылку гугла, устанавливаем и всё. Для работы будем использовать bash консоль, которую они предоставляют. Чтобы работать в виндоусе, нужно запустить Git Bash. Вот как он выглядит в меню пуск:![Начало работы с Git: подробный гайд для новичков - 2](https://cdn.javarush.com/images/article/7f9c3203-5ae5-46fd-b500-42b3979c2eaf/800.jpeg)
![Начало работы с Git: подробный гайд для новичков - 3](https://cdn.javarush.com/images/article/52ad1966-4e34-4e47-ba78-8ce1ff395d18/1024.jpeg)
Установка для Linux
Обычно git уже установлен и есть в дистрибутивах линукса, так как это инструмент, первоначально написанный для разработки ядра линукса. Но бывают ситуации, когда его нет. Чтобы проверить это, нужно открыть терминал и прописать: git --version. Если будет вразумительный ответ, ничего устанавливать не нужно. Открываем терминал и устанавливаем. Я работаю на Ubuntu, поэтому могу сказать, что писать для нее: sudo apt-get install git. И все: теперь в любом терминале можно пользоваться гитом.Установка на macOS
Здесь также для начала нужно проверить, есть ли уже гит (смотри выше, как на линуксе). Если все же нет, самый простой путь — это скачать отседова последнюю версию. Если установлен XCode, то гит уже точно будет автоматически установлен.Настройка гита
У гита есть настройка пользователя, от которого будет идти работа. Это разумная и необходимая вещь, так как когда создается коммит, гит берет именно эту информацию для поля Author. Чтобы настроить имя пользователя и пароль для всех проектов, нужно прописать следующие команды:
git config --global user.name ”Ivan Ivanov”
git config --global user.email ivan.ivanov@gmail.com
Если есть необходимость для конкретного проекта поменять автора (для личного проекта, например), можно убрать --global, и так получится:
git config user.name ”Ivan Ivanov”
git config user.email ivan.ivanov@gmail.com
Немного теории…
Чтобы быть в теме, желательно добавить в свое обращение несколько новых слов и действий… А то говорить будет не о чем. Конечно это некий жаргон и калька с английского, поэтому я буду добавлять значения на английском. Какие слова и действия?- гит репозиторий (git repository);
- коммит (commit);
- ветка (branch);
- смерджить (merge);
- конфликты (conflicts);
- спулить (pull);
- запушить (push);
- как игнорировать какие-то файлы (.gitignore).
Состояния в Гит
У Гита есть несколько состояний, которые нужно понять и запомнить:- неотслеживаемое (untracked);
- измененное (modified);
- подготовленное (staged);
- закомиченное (committed).
Как это понимать?
Это состояния, в которых находятся файлы из нашего кода. То есть, их жизненный путь обычно выглядит так:- Файл, который создан и не добавлен в репозиторий, будет в состоянии untracked.
- Делаем изменения в файлах, которые уже добавлены в гит репозиторий — находятся в состоянии modified.
- Из тех файлов, которые мы изменили, выбираем только те (или все), которые нужны нам (например, скомпилированные классы нам не нужны), и эти классы с изменениями попадают в состояние staged.
- Из заготовленных файлов из состояния staged создается коммит и переходит уже в гит репозиторий. После этого staged состояние — пустое. А вот modified еще может что-то содержать.
![Начало работы с Git: подробный гайд для новичков - 4](https://cdn.javarush.com/images/article/6136c12e-46b4-4fda-820c-3287237c48ab/800.jpeg)
Что такое коммит
Коммит — это основной объект в управлении контроля версий. Он содержит все изменения за время этого коммита. Коммиты связаны между с собой как односвязный список. А именно: Есть первый коммит. Когда создается второй коммит, то он (второй) знает, что идет после первого. И таким образом можно отследить информацию. Также у коммита есть еще своя информация, так называемые метаданные:- уникальный идентификатор коммита, по которому можно его найти;
- имя автора коммита, который создал его;
- дата создания коммита;
- комментарий, который описывает, что было сделано во время этого коммита.
![Начало работы с Git: подробный гайд для новичков - 5](https://cdn.javarush.com/images/article/f0a1025b-2f0c-4e65-b9bc-641db79a7704/512.jpeg)
Что такое ветка
![Начало работы с Git: подробный гайд для новичков - 6](https://cdn.javarush.com/images/article/29945159-3a11-47a9-ae00-c762a4f5d6fb/512.jpeg)
Начало работы с Гитом
Можно работать и только с локальный репозиторием, и с удаленным. Для отработки нужных команд можно воспользоваться только локальным репозиторием. Он хранит всю информацию только локально в проекте в папке .git. Если говорить об удаленном, то вся информация хранится где-то на удаленном сервере: локально хранится только копия проекта, изменения которой можно запушить (git push) в удаленный репозиторий. Здесь и далее будем обсуждать работу с гитом в консоли. Конечно, можно пользоваться какими-то графическими решениями (например, в Intellij IDEA), но сперва нужно разобраться, какие команды происходят и что они значат.Работа с гитом в локальном репозитории
Далее я предлагаю вам проделать все те шаги, которые проделал я, в то время как будете читать статью. Это улучшит ваше понимание и усвоение материала. Так что приятного аппетита :) Чтобы создать локальный репозиторий, нужно написать:
git init
![Начало работы с Git: подробный гайд для новичков - 7](https://cdn.javarush.com/images/article/5dbf6234-0ea6-40a8-9d37-ce14609d53b4/800.jpeg)
git status
![Начало работы с Git: подробный гайд для новичков - 8](https://cdn.javarush.com/images/article/348071fa-ccab-4a0c-ae94-6f9f0e6fa671/800.jpeg)
- git add -A — добавить все файлы из состояния в staged;
- git add . — добавить все файлы из этой папки и все внутренних. По сути тоже самое, что и предыдущее;
- git add <имя файла> — добавляет только конкретный файл. Здесь можно пользоваться регулярными выражениями, чтобы добавлять по какому-то шаблону. Например, git add *.java: это значит, что нужно добавить только файлы с расширением java.
git add *.txt
Чтобы проверить статус, используем уже известную нам команду:
git status
![Начало работы с Git: подробный гайд для новичков - 9](https://cdn.javarush.com/images/article/948c12dc-8227-48d0-8bd3-2ac9ed8be271/800.jpeg)
git commit -m “all txt files were added to the project”
![Начало работы с Git: подробный гайд для новичков - 10](https://cdn.javarush.com/images/article/5159fcca-3b1c-4308-b1e4-854c1d480385/800.jpeg)
git log
![Начало работы с Git: подробный гайд для новичков - 11](https://cdn.javarush.com/images/article/b869b551-e804-4ac1-b199-6f16684be943/800.jpeg)
git status
![Начало работы с Git: подробный гайд для новичков - 12](https://cdn.javarush.com/images/article/00e768e8-6568-42d8-9d03-437c71028b50/800.jpeg)
git status
![Начало работы с Git: подробный гайд для новичков - 13](https://cdn.javarush.com/images/article/3abb8e35-ebfd-4480-b26e-fc8f19322b36/800.jpeg)
git diff
![Начало работы с Git: подробный гайд для новичков - 14](https://cdn.javarush.com/images/article/1f3506ae-1746-4ee9-b346-c992be73bb63/800.jpeg)
git add test_resource.txt
git commit -m “added hello word! to test_resource.txt”
Чтобы посмотреть на все коммиты, пишем:
git log
![Начало работы с Git: подробный гайд для новичков - 15](https://cdn.javarush.com/images/article/12d64adf-c2ae-4d62-ab36-df174fdab5b8/800.jpeg)
git add GitTest.java
git commit -m “added GitTest.java”
git status
![Начало работы с Git: подробный гайд для новичков - 16](https://cdn.javarush.com/images/article/e5e89bbd-baa2-43cc-bace-cbb24e030c7a/800.jpeg)
Работа с .gitignore
Ясно, что мы хотим хранить только исходный код и ничего другого в репозитории. А что может быть еще? Как минимум, скомпилированные классы и/или файлы, которые создают среды разработки. Чтобы гит их игнорировал, есть специальный файл, который нужно создать. Делаем это: создаем файл в корне проекта с названием .gitignore, и в этом файле каждая строка будет шаблоном для игнорирования. В этом примере гит игнор будет выглядеть так:
```
*.class
target/
*.iml
.idea/
```
Смотрим теперь:
- первая строка — это игнорирование всех файлов с расширением .class;
- вторая строка — это игнорирование папки target и всего, что она содержит;
- третья строка — это игнорирование всех файлов с расширением .iml;
- четвертая строка — это игнорирование папки .idea.
git status
![Начало работы с Git: подробный гайд для новичков - 17](https://cdn.javarush.com/images/article/78f2e2ef-72df-41ed-9f16-6aeb16be9c92/800.jpeg)
![Начало работы с Git: подробный гайд для новичков - 18](https://cdn.javarush.com/images/article/cb845a33-8843-4ee9-8842-545e11a8436b/1024.jpeg)
git add .gitignore
git commit -m “added .gitignore file”
И теперь момент истины: у нас есть в untracked состоянии скомпилированный класс GitTest.class, который мы не хотели добавлять в гит репозиторий.
Вот здесь-то и должен заработать гит игнор:
git status
![Начало работы с Git: подробный гайд для новичков - 19](https://cdn.javarush.com/images/article/d094337b-01dc-43a6-8326-c0ba309d0df7/800.jpeg)
Работа с ветками и иже с ним
Разумеется, работать в одной ветке неудобно одному и невозможно, когда в команде больше одного человека. Для этого существует ветвление. Как я уже говорил, ветка — это просто подвижный указатель на коммиты. В этой части рассмотрим работу в разных ветках: как смерджить изменения одной ветки в другую, какие могут возникнуть конфликты и многое другое. Чтобы посмотреть список всех веток в репозитории и понять, на какой находишься, нужно написать:
git branch -a
![Начало работы с Git: подробный гайд для новичков - 20](https://cdn.javarush.com/images/article/3a5ccec8-3fe1-4b6c-b19f-2e66280f4fc6/800.jpeg)
- создать новую ветку на основе той, на которой находимся (99% случаев);
- создать ветку на основе конкретного коммита (1%).
Создаем ветку на основе конкретного коммита
Опираться будем на уникальный идентификатор коммита. Чтобы найти его, напишем:
git log
![Начало работы с Git: подробный гайд для новичков - 21](https://cdn.javarush.com/images/article/6f312f65-a820-4faf-a218-686182020e32/800.jpeg)
git checkout -b development 6c44e53d06228f888f2f454d3cb8c1c976dd73f8
Создается ветка, в которой будут только первые два коммита из ветки master. Чтобы проверить это, мы сперва убедимся, что перешли в другую ветку и посмотрим на количество коммитов ней:
git status
git log
![Начало работы с Git: подробный гайд для новичков - 22](https://cdn.javarush.com/images/article/32e2010a-16e6-4342-a082-c5181a876dfd/800.jpeg)
git branch -a
![Начало работы с Git: подробный гайд для новичков - 23](https://cdn.javarush.com/images/article/b0fa2136-26d5-4c09-867a-9faebdc3be8e/800.jpeg)
Создаем ветку на основе текущей
Второй способ создания ветки — создание на основе другой. Я хочу создать ветку на основе master ветки, поэтому нужно сперва перейти на нее, а уже следующим шагом — создать новую. Смотрим:- git checkout master — переходим на ветку master;
- git status — проверяем, точно ли на мастере.
![Начало работы с Git: подробный гайд для новичков - 24](https://cdn.javarush.com/images/article/fc59d1e4-d887-4b07-add7-0a1ed53ede8b/800.jpeg)
git checkout -b feature/update-txt-files
![Начало работы с Git: подробный гайд для новичков - 25](https://cdn.javarush.com/images/article/19d396fc-af1c-4d3f-8deb-2dbba09dfaf2/800.jpeg)
Резолвим конфликты
Прежде чем разобраться с тем, что такое конфликт, нужно поговорить о слиянии (смердживании) одной ветки в другую. Вот такой картинкой можно показать процесс, когда одну ветку мерджат в другую:![Начало работы с Git: подробный гайд для новичков - 26](https://cdn.javarush.com/images/article/5be87984-024c-43ab-be88-a3cdf3331692/512.jpeg)
![Начало работы с Git: подробный гайд для новичков - 27](https://cdn.javarush.com/images/article/47a002ed-bea0-4be5-b60c-f9c822c5c834/800.jpeg)
git add *.txt
git commit -m “updated txt files”
git log
![Начало работы с Git: подробный гайд для новичков - 28](https://cdn.javarush.com/images/article/99af1950-f2b6-4792-8fe7-4ad7442dd8fc/800.jpeg)
git checkout master
git merge feature/update-txt-files
git log
![Начало работы с Git: подробный гайд для новичков - 29](https://cdn.javarush.com/images/article/96f5d6f1-3d22-4597-b85b-b8af900b2e35/800.jpeg)
git branch -D feature/update-txt-files
Пока понятно, да?
Усложняем ситуацию: теперь допустим, что опять нужно изменить txt файл. Но теперь еще и в мастере этот файл будет изменен также. То есть он будет параллельно изменяться, и гит не сможет понять что нужно делать в ситуации, когда мы захотим смерджить в master ветку новый код.
Поехали!
Создаем новую ветку на основе master, делаем изменения в text_resource.txt и создаем коммит под это дело:
git checkout -b feature/add-header
... делаем изменения в файле
![Начало работы с Git: подробный гайд для новичков - 30](https://cdn.javarush.com/images/article/0a9176d6-8054-4655-b90a-315e215aa56f/800.jpeg)
git add *.txt
git commit -m “added header to txt”
![Начало работы с Git: подробный гайд для новичков - 31](https://cdn.javarush.com/images/article/2635b663-7fd8-4d22-947b-df8c50777840/800.jpeg)
git checkout master
… обновили test_resource.txt
![Начало работы с Git: подробный гайд для новичков - 32](https://cdn.javarush.com/images/article/ac84fa61-0381-48e0-bf5c-1dcf633b779f/800.jpeg)
git add test_resource.txt
git commit -m “added master header to txt”
И теперь самый интересный момент: нужно смерджить изменения из feature/add-header ветки в master. Мы находимся в мастер ветке, поэтому нужно только написать:
git merge feature/add-header
Но мы получим результат с конфликтом в файле test_resource.txt:
![Начало работы с Git: подробный гайд для новичков - 33](https://cdn.javarush.com/images/article/233f6738-b599-4f22-8552-2d39813d6dd8/800.jpeg)
![Начало работы с Git: подробный гайд для новичков - 34](https://cdn.javarush.com/images/article/efa04c3b-e279-4f6f-8f05-c3d2318d8ff2/800.jpeg)
- между “<<<<<<< HEAD” и “=======” находятся изменения мастер, которые были в этой строке в мастер ветке.
- между “=======” и “>>>>>>> feature/add-header” находятся изменения, которые были в feature/add-header ветке.
![Начало работы с Git: подробный гайд для новичков - 35](https://cdn.javarush.com/images/article/c167e2b2-1cb1-4d19-862e-80ee06a7b6b4/800.jpeg)
git status
![Начало работы с Git: подробный гайд для новичков - 36](https://cdn.javarush.com/images/article/4416b14b-0e87-4877-b098-702624219f04/800.jpeg)
git add *.txt
![Начало работы с Git: подробный гайд для новичков - 37](https://cdn.javarush.com/images/article/99a41e85-fb52-429a-86c3-65ad32dd54aa/800.jpeg)
git commit
![Начало работы с Git: подробный гайд для новичков - 38](https://cdn.javarush.com/images/article/c07c9f20-993a-42ed-91d6-91fbf8f37646/800.jpeg)
Работа с удаленными репозиториями
Последний шаг — разобраться еще с несколькими командами, которые нужны для работы с удаленным репозиторием. Как я уже говорил, удаленный репозиторий — это какое-то место, где хранится репозиторий и откуда можно его клонировать. Какие бывают удаленные репозитории? Примеров тьма:GitHub — это крупнейшее хранилище для репозиториев и совместной разработки. Я уже описывал его в предыдущих статьях.
Подписывайтесь на мой гитхаб аккаунт. Я часто выставляю там свои наработки в тех сферах, которые изучаю во время работы.GitLab — веб-инструмент жизненного цикла DevOps с открытым исходным кодом, представляющий систему управления репозиториями кода для Git с собственной вики, системой отслеживания ошибок, CI/CD пайплайн и другими функциями.
После новости о том, что Microsoft купила GitHub, некоторые разработчики продублировали свои наработки в GitLab.BitBucket — веб-сервис для хостинга проектов и их совместной разработки, основанный на системе контроля версий Mercurial и Git. Одно время имел большое преимущество перед GitHub в том, что у него были бесплатные приватные репозитории. В прошлом году GitHub также открыл эту возможность для всех бесплатно.
И так далее…
git clone https://github.com/romankh3/git-demo
Теперь локально есть полная копия проекта. Чтобы быть уверенным, что локально находится последняя копия проекта, нужно, как говорится, спулить данные, написав:
git pull
![Начало работы с Git: подробный гайд для новичков - 39](https://cdn.javarush.com/images/article/782b84b1-e001-4849-be0b-c319133afca0/800.jpeg)
![Начало работы с Git: подробный гайд для новичков - 40](https://cdn.javarush.com/images/article/5598fa4d-3058-4994-b17d-63c6b5710076/800.jpeg)
git add test_resource.txt
git commit -m “prepated txt for pushing”
И теперь команда, чтобы отправить это на удаленный репозиторий:
git push
![Начало работы с Git: подробный гайд для новичков - 41](https://cdn.javarush.com/images/article/46c49cfa-afb0-4b3a-b95f-7506a199a189/800.jpeg)
Полезные ссылки
- Официальная дока на гит, есть на русском. Рекомендую как справочное пособие.
- Git
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ