Git для разработчика: commit, branch, merge, rebase, конфликты и pull request?
Три области и поток изменений
git clone https://github.com/company/shop.git
cd shop
git switch -c feature/SHOP-123-cart-discount # новая ветка от текущей
# ... правим код ...
git status # что изменено
git diff # сами изменения
git add src/Cart.cs # добавить в индекс (git add -p — по частям)
git commit -m "feat(cart): add percentage discount"
git push -u origin feature/SHOP-123-cart-discount
# → открыть Pull Request на GitHubКоммиты и ветки
- Каждый коммит знает своего родителя — история образует граф.
mainиfeature— просто имена, указывающие на последние коммиты своих линий. Создание ветки мгновенно и дёшево.- Хороший коммит: одно логическое изменение, понятное сообщение в повелительном наклонении («add», «fix»), собирается и проходит тесты.
Merge и rebase
# Merge: влить main в свою ветку (или ветку в main)
git switch feature
git merge main
# Rebase: переставить свои коммиты поверх свежего main
git fetch origin
git rebase origin/main
git push --force-with-lease # история ветки изменилась — нужен force (только для СВОЕЙ ветки)| Merge | Rebase | |
|---|---|---|
| История | Нелинейная, честная | Линейная, «чистая» |
| Коммиты | Сохраняются как есть | Пересоздаются (новые хэши) |
| Безопасно для общих веток | Да | Нет |
| Конфликты | Разрешаются один раз | Могут повторяться для каждого коммита |
Конфликты
public decimal Discount()
{
<<<<<<< HEAD
return Total * 0.10m; // ваша версия
=======
return Math.Min(Total * 0.15m, 500_000m); // версия из main
>>>>>>> main
}# 1. Отредактировать файл: оставить правильный итог, удалить маркеры
# 2. Проверить сборку и тесты
git add src/Cart.cs
git commit # при merge
git rebase --continue # при rebase
git merge --abort # или отменить слияние целикомКак уменьшить конфликты: маленькие короткоживущие ветки, частое обновление из main, не смешивать рефакторинг и форматирование с функциональными изменениями.
Отмена изменений
git stash # убрать незакоммиченное «в карман»
git switch main # ... сделать срочное исправление ...
git switch - # вернуться
git stash pop # вернуть изменения
git commit --amend # исправить последний (ещё не запушенный) коммит
git log --oneline --graph # история
git reflog # журнал перемещений HEAD — спасение «потерянных» коммитовPull Request
- Ветка от актуального
main, небольшое законченное изменение. - Push и PR с описанием: что, зачем, как проверить.
- CI (сборка, тесты, линтеры) должен быть зелёным.
- Ревью коллег, исправления новыми коммитами.
- Слияние (чаще всего squash merge — один коммит в
main), удаление ветки.
.gitignore
bin/
obj/
.vs/
*.user
appsettings.Development.local.json
.envНе коммитьте артефакты сборки, настройки IDE и секреты. Создать стандартный файл: dotnet new gitignore.
Вопросы на засыпку
Чем git fetch отличается от git pull?
fetch скачивает новые коммиты и обновляет удалённые ветки (origin/main), не трогая ваши файлы и локальные ветки. pull = fetch + merge (или rebase с --rebase) в текущую ветку. fetch безопасен всегда — можно посмотреть изменения перед слиянием.
Что такое detached HEAD?
Состояние, когда HEAD указывает напрямую на коммит, а не на ветку (например, после git checkout <хэш>). Новые коммиты не принадлежат никакой ветке и могут «потеряться». Чтобы сохранить работу — создайте ветку: git switch -c new-branch.
Что делать, если случайно закоммитил пароль?
Считать его скомпрометированным и немедленно сменить (ротировать). Удаление коммита или переписывание истории — вторично: копии могли уже разойтись. Затем добавить файл в .gitignore и настроить сканирование секретов.
Зачем squash merge?
Все промежуточные коммиты ветки («fix typo», «review fixes») объединяются в один осмысленный коммит в main. История основной ветки читаема: один PR — один коммит, его легко найти и откатить через revert.
Итог
Git хранит историю как граф коммитов, ветки — лёгкие указатели. Рабочий цикл: ветка → изменения → add → commit → push → Pull Request → ревью → слияние. Merge сохраняет историю, rebase делает её линейной, но переписывает коммиты — только для своих веток. Конфликты разрешайте вручную с проверкой сборки, отменяйте общие изменения через revert и никогда не коммитьте секреты.