Про GIT. Использование
Примеры решения основных задач при работе с GIT репозиторием.
Термины
- branch — (бранч) ветка репозитория;
- origin — алиас на удаленный репозиторий;
- master — алиас на основную ветку (бранч) локального репозитория репозитория;
- index — снапшот (снимок), временное хранилище изменений, которые затем войдут в коммит;
- commit — фиксация изменений в индексе;
Настройка GIT
Настройки сохраняются в файле ~/.gitconfig. Для первичной настройки гита, выполните в консоли:
git config --global user.name "Your Name"
git config --global user.email your_name@gmail.com
git config --global core.autocrlf true
git config --global core.safecrlf true
git config --global color.branch auto
git config --global color.diff auto
git config --global color.interactive auto
git config --global color.status auto
Также можем добавить для удобства алиасы в этом же файле конфига ~/.gitconfig:
[alias]
st = status
ci = commit
br = branch
co = checkout
df = diff
lg = log -p
Использование
Репозитории
Посмотреть список удаленных репозиториев:
git remote -v
Инициализация / Клонирование
Инициализировать новый репозиторий в каталоге с проектом:
git init
git commit, все изменения войдут в ветку master, если вы не указывали другие опции.Клонировать удаленный репозиторий в текущий каталог:
git clone ssh://git@123.45.67.89/vendor/progect/ .
Клонировать удаленный репозиторий в заданный каталог my-project:
git clone ssh://git@123.45.67.89/vendor/project my-project
Индексация изменений
Команды add и rm позволяют добавить или исключить файлы из индекса, соответственно.
Добавить указанные файлы, каталоги (рекурсивно) в индекс:
git add index.php
git add path/to/file.php
Внести в индекс все изменения, включая новые файлы:
git add .
Исключить файлы из индекса и дерева проекта:
git rm .buildpath .project *.php~
Исключить файлы *.php из папки tmp/smarty/compile/:
git rm tmp/smarty/compile/*.php
Отменить индексацию последних изменений:
git reset
git reset HEAD file.php # Убрать из индекса file.php
Добавить в индекс только удаленные файлы:
git add -A
Удалить из индекса файл и добавить в игнор. Файл останется в каталоге.
git rm --cached ИМЯ_ФАЙЛА
Коммиты
Коммит — фиксация изменений в репозитории, находящихся в индексе.
Посмотреть действия при коммите (сравнить индекс с кешем):
git diff --cached
Сделать коммит всех измененных файлов (НЕ добавленных) с заданным комментарием:
git commit -a -m "Текст комментария"
-a позволяет автоматически проиндексировать все изменения в файлах, перед коммитом. Новые файлы при этом индексироваться не будут, удаленные файлы будут учтены.Добавить изменения в последний коммит. Изменять комментарий обязательно?
git commit --amend
git откроет файл с данными последнего коммита, в котором нужно отредактировать строку с комментарием. Можно добавить просто UPD #1. Если оставить комментарий без изменений — последний коммит не будет обновлен. Сохраняем изменения и выходим из режима редактирования файла. После этого изменения будут добавлены к предыдущему коммиту.Переключиться на определенный коммит:
git checkout <hash-коммита>
Синхронизация (Pull, Push, Fetch)
Отправить изменения
Отправить свои изменения в основную ветку удаленного репозитория (созданную при клонировании по умолчанию):
git push
# то же, что и
git push origin master
Залить изменения в ветку fetures:
git push origin features
Внести изменения в удаленный репозиторий ветку experimental:
git push experimental:experimental
Забрать изменения
Забрать изменения с удаленного репозитория и слить их с активной веткой:
git pull
Забрать изменения с удаленного репозитория БЕЗ слияния с активной веткой:
git fetch
Ветки (branch)
Посмотреть список всех веток репозитория:
git branch # локальные ветки
git branch -a # локальные и удаленные ветки
Создать новую ветку bugfix:
git branch bugfix
Переименовать ветку:
git branch -m new-name-branch
Переключиться на ветку feature:
git checkout feature
Удалить ветку, если она слита (merged) с текущей и разрешены все конфликты:
git branch -d new-branch
Создать ветку и перейти в нее:
git branch new-branch
git checkout new-branch
// или так
git checkout -b new-branch
Слить изменения из ветки featute в текущую:
git merge featute
Состояние и история изменений
Команда status выводит информацию обо всех изменениях, внесенных в дерево директорий проекта по сравнению с последним коммитом рабочей ветки; отдельно выводятся внесенные в индекс и не индексированные файлы.
А также файлы с неразрешенными конфликтами слияния и файлы, игнорируемые git.
Показать последние изменения: не проиндексированные, удаленные, добавленные, измененные файлы:
git status
Показать историю коммитов с комментариями:
git log
Оценка изменений:
git diff
Показать изменения в исходниках последнего коммита:
git show
Посмотреть изменения в исходниках, внесенные определенным коммитом:
git show <COMMIT TAG>
Показать изменения в последнем коммите. Не показывает тип изменения — модификация, удаление, добавление.
git log -1 --name-only
git log --stat --summary # детальный лог
История изменений файла (№ коммита, кто, когда, строка, ..):
git blame -L 160,+10 file.ext // показать 10 строк со 160-й строки
Скрыть изменения (изменения вносятся в стек):
git stash
Показать стек скрытых изменений:
git stash show
Очистить стек скрытых изменений:
git stash clear
Откат изменений
Отменить индексацию последних изменений:
git reset
Удалить из индекса файл и добавить его в игнор. Файл останется в каталоге.
git rm --cached path/to/file.src
Получить версию файла из последнего коммита:
git show HEAD^:path/to/file > path/to/save/file
Отменить изменения файла до последнего коммита:
git checkout path/to/file.src
git add перед коммитом)Отменить последний коммит (изменения сохранятся):
git reset --soft HEAD^
Удалить последний коммит и изменения:
git reset --hard HEAD^
Команда rebase позволяет выбрасывать и сливать коммиты.
Больше никто и никогда не увидит этот позорный коммит:
git reset --hard HEAD~3 //...вернее, три последних коммита. Никто. Никогда!
Прочие
Залить изменения на сервер:
git commit -m 'initial commit'
git remote add origin git@codebasehq.com:exmedia/croco-webmasters/wm2.git
git push origin master
Рекомендации
- Не хорошо делать
push --force— будут большие проблемы при попытке синхронизации с репозиторием у остальных клиентов. Есть правило — не модифицировать историю комитов, которые доступны публичны. - Для удаления коммитов
push --forceбезобиден, если работаешь с ним один; - Вместо 40-значного хеша пожно ссылаться на коммиты по имени: HEAD — последний коммит в текущей ветке, HEAD^ — предпоследний, HEAD^^ — пред-предпоследний;
- push access — разрешение вносить изменения в исходный репозиторий;
- gitk — утилита для визуализации веток и коммитов;
<<<<<<< HEAD
мои правки
=======
удаленные обновления
>>>>>>> 13b5514fe52ac9315978d0022598c05ba7e0e03a
Решение проблем
Aborting commit due to empty commit message
Ошибка возникает при указании к коммиту длинного комментария с переносом строк.
Подробнее здесь.
Решение: Нужно создать файл с текстом комментария и выполнить коммит следующей коммандой:
git commit -a -F /path-to/commit-message/commit-text.txt
Проблема с символами переноса строк
Нужно конвертировать символы переноса каретки. Для конвертации переносов строк можно использовать утилиту dos2unix:
dos2unix find ./src/path/ -type f
dos2unix можно из пакета tofrodos:
sudo aptitude install tofrodos
И создать симлинки:
sudo ln -s fromdos dos2unix
sudo ln -s todos unix2dos
core.autocrlf
false- default.
true - символы новой строки будут переводится к \n при записи в хранилище, а при чтении будут приводится к \n (Unix), \r\n (Windows) или \r (MacOS).
core.safecrlf
true - символы новой строки будут переводится к \n при записи в хранилище, а при чтении будут приводится к \n (Unix), \r\n (Windows) или \r (MacOS).
warn - проводит авто замену с предупреждениями в ошибками консоле;
Если сразу же не настроить переносы строк, то при каждом push большинство файлов будут помечаться как измененные, хотя никаких изменений в них нет.
При этом все равно время от времени появляются такие файлы, им вручную приходится делать revert.
У меня используется core.autocrlf true, core.eol native(по умолчанию) , core.safecrlf false (по умолчанию)
Офигеть просто! Все, блин, всё знают, кроме меня
Практика — залог успеха;)
Я после плотной работы с SVNом вообще гиту не нарадуюсь. Из консоли спокойно можно работать, только команды помни и общее представление что-куда)