Git и GitHub — разница и основные команды - Вопросы

Всего: 5 вопросов

1. 

В чём принципиальная разница между Git и GitHub?

Git — это распределённая система контроля версий, то есть программа, которую устанавливают на компьютер. Она хранит полную историю проекта локально, умеет коммиты, ветки, слияния и откаты и работает без интернета. Git создал Линус Торвальдс в 2005 году для разработки ядра Linux.

GitHub — это облачный веб-сервис для хостинга Git-репозиториев, запущенный в 2008 году и принадлежащий Microsoft с 2018 года. Поверх Git он добавляет веб-интерфейс, pull requests, code review, трекер задач (issues), CI/CD (GitHub Actions), GitHub Pages и права доступа для команды.

Короткий ответ: Git — это технология, GitHub — сервис, построенный вокруг этой технологии. Git отлично работает без GitHub, а GitHub без Git не имеет смысла: он хранит именно Git-репозитории. Аналоги Git — Mercurial, Subversion (SVN), Perforce; аналоги GitHub — GitLab, Bitbucket, Gitea, Azure Repos.

2. 

Какие состояния бывают у файла в Git и через какие области он проходит по пути в репозиторий?

Git делит файлы на отслеживаемые (были в последнем снимке проекта или уже добавлены в индекс) и неотслеживаемые (всё остальное). Файл проходит три области: рабочий каталог → индекс (staging area) → репозиторий.

Состояния и переходы между ними:

Неотслеживаемый (untracked) — лежит в рабочем каталоге, git status пишет «Untracked files»; переводится дальше командой git add file.
Изменённый (modified) — тоже в рабочем каталоге, git status пишет «Changes not staged for commit»; переводится дальше командой git add file.
Подготовленный (staged) — уже в индексе, git status пишет «Changes to be committed»; фиксируется командой git commit -m "...".
Зафиксированный (committed) — в локальном репозитории, git status пишет «nothing to commit, working tree clean»; отправляется на сервер командой git push.

Посмотреть состояние всех файлов сразу помогает git status или короткий формат git status -s, где ?? — новый файл, M — изменён, A — добавлен в индекс. Важно помнить: git commit фиксирует только то, что попало в индекс через git add.

3. 

Как отправить локальный проект на GitHub из командной строки?

Отдельных «команд GitHub» в терминале нет: с GitHub работают теми же командами Git, просто в качестве удалённого репозитория указывают адрес на github.com. Сначала создайте на GitHub пустой репозиторий (без README), затем в папке проекта выполните:

git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/user/project.git
git push -u origin main

Флаг -u связывает локальную ветку с удалённой, поэтому дальше достаточно писать просто git push и git pull. Проверить настроенные адреса можно командой git remote -v, а сменить адрес (например, перейти на SSH) — git remote set-url origin [email protected]:user/project.git.

Важно: с 13 августа 2021 года GitHub не принимает пароль от аккаунта при работе по HTTPS — вместо пароля нужен Personal Access Token (Settings → Developer settings → Tokens) либо настроенный SSH-ключ.

4. 

Что такое fork и pull request на GitHub и чем pull request отличается от команды git pull?

Fork — кнопка GitHub, которая создаёт копию чужого репозитория в вашем аккаунте. Она нужна, когда вы хотите поучаствовать в проекте, но прав на запись в оригинал у вас нет. Стандартный сценарий для open source выглядит так:

1. Нажать Fork на странице проекта — копия появляется у вас.
2. Клонировать свою копию: git clone.
3. Создать ветку, внести изменения, сделать коммит и git push.
4. Открыть pull request в оригинальный репозиторий.
5. Автор проекта проводит code review и принимает или отклоняет изменения.

GitHub сохраняет связь копии с оригиналом, поэтому свежие изменения из upstream подтягиваются кнопкой Sync fork или командами:

git remote add upstream https://github.com/original/project.git
git fetch upstream
git merge upstream/main

Pull request — это не команда git pull. git pull — команда Git, которая забирает изменения с сервера в вашу локальную ветку. Pull request — функция GitHub: предложение владельцу репозитория влить вашу ветку в основную, с обсуждением, комментариями к коду и проверками CI. В GitLab то же самое называется merge request.

5. 

Почему git push отклоняется с ошибкой ! [rejected] main -> main (non-fast-forward) и как правильно её исправить?

Ошибка означает, что в удалённом репозитории есть коммиты, которых нет у вас: пока вы работали, коллега успел отправить свои изменения, и истории разошлись. Git не позволяет затереть чужую работу, поэтому отклоняет push.

Правильное решение — сначала забрать чужие коммиты и наложить свои сверху, затем повторить отправку:

git pull --rebase
git push

Флаг --rebase не создаёт лишний merge-коммит, и история остаётся линейной; включить такое поведение по умолчанию можно один раз: git config --global pull.rebase true. А вот git push --force в общей ветке применять нельзя — он затирает коммиты коллег.

Родственные грабли новичков: коммит без git add (изменения просто не попадут в коммит); git add . без .gitignore, из-за чего в репозиторий улетают target/, .idea/ и пароли из конфигов; git pull с незакоммиченными правками (спасает git stash и затем git stash pop); отсоединённый HEAD после git checkout <хеш коммита>, из которого возвращаются командой git switch -.

Страница 1 из 1