Установка git
1. Установка, настройка
2. Описание серера gogs
3. Пример совместной работы
Термины
Репозиторий / репо - хранилище или архив. В каждом вашем проекте вы можете создать своё хранилище, для всех версий ваших файлов. Хранилище очень компактно и можно быстро извлекать из него, сравнивать разные версии проекта, объединять.
Рабочий каталог / working tree / working area - корневой каталог вашего проекта, например D:\home\user\site\www\ в котором вы создали репозиторий командой git init. Рабочий каталог сохраняется в репозитории командой git commit, а восстанавливается командой git checkout.
Индекс / stage - сохранение рабочего каталога происходит в два этапа: 1) индексация git add 2) фиксация или сохранение git commit. Индекс как буфер между репо и рабочим каталогом даёт больше возможности контроля над операциями.
Коммит / commit - фиксация изменений, слепок или архив всех файлов рабочего каталога. Коммит сохраняет (архивирует) в каталоге .git\ все новые/изменённые проиндексированные файлы, для каждого файла создавая хеш SHA-1. Хеш создаётся для каждого объекта (весь коммит или отдельный файл) и используется в качестве указателя. Если файл не изменился с прошлого коммита гит не архивирует его, а просто делает ссылку на файл прошлого коммита. Это быстрее и компактнее.
Ветка / branch - именованная цепочка коммитов, основная ветка по умолчанию называется master, ответвления называем сами dev, hotfix, feature и т.п. Когда мы раньше для разработки новой фичи чтобы не замусорить проект копировали весь каталог, то с гит нужно просто создать новую ветку git checkout -b feature и можно работать, мы уже, как бы, в новом каталоге и ничего не замусорится! При чём это очень быстро, ведь фактически в этом новом каталоге/ветке гит создаёт только указатели на родителя, а реально сохранять будет здесь только изменённые файлы.
HEAD - указатель на текущий коммит в репозитории из которого было извлечено текущее содержимое рабочего каталога. Если по назанию ветки адресуется только последний коммит ветки, то с помощью HEAD можно адресовать отдельные коммиты. Если HEAD перевести с последнего коммита на другой коммит то будет состояние "detached HEAD" (оторванная голова).
master - название по умолчанию основной ветки
origin - название по умолчанию удалённого репозитория
Установка, настройка
Установить гит можно отсюда, можно оставить по умолчанию все чекпоинты, нажать далее.
После установки, для удобства можно сделать авто переход в рабочий каталог после запуска bash-консоли для этого добавьте в строки в файл: C:\Users\ВашеИмя\.bashrc
cd D:\home\user\site\www\
Если такого файла нет, создайте его.
Редактор по умолчанию
Для Notepad++ нужно добавить в C:\Users\ВашеИмя\.gitconfig в раздел [core] строку:
[core] editor = 'C:\\Program Files\\Notepad++\\notepad++.exe' -multiInst -notabbar -nosession -noPlugin
Устанавливаем Мелд
Скачать Мелд по этой ссылке.
Осторожно! не устанавливайте последнюю версию (3.20), с ней были проблемы.
Рабочий гит-конфиг (C:\Users\Ваше_имя\.gitconfig ) для Мелд
[diff] tool = meld [difftool "meld"] cmd = 'C:/Program Files (x86)/Meld/Meld.exe' \"$LOCAL\" \"$REMOTE\" [difftool] prompt = false
Исключения
Если в проекте есть общие файлы, которые не надо отслеживать и удалять при смене ветки, можно добавить эти файлы в список исключений в файл .git\info\exclude вот пример:
D:\home\user\site\www\.git\info\exclude
fonts/ *.log *.jpg *.png *.svg *.m4s *.mp4 *.mpd *.woff2 *.ttf *.eot *.dat *.xlsx favicon.ico robots.txt *.map PHPExcel-1.8.2/ .gitignore
Кроме файла .git\info\exclude можно в каждом отдельном каталоге создать файл .gitignore и в него добавить исключения для этого каталога
Ветки, переключение, создание
Удалить лишнее из рабочего каталога и загрузит файлы из слепка на который указывает ветка/коммит:
git checkout <имя ветки или id коммита>
Создать новую ветку на основе master
git checkout -b feature/new-branch master
Взять текущие изменения (после последнего коммита) и создать из них новую ветку:
git stash git stash branch <имя-ветки>
Способы адресации
С помощью хеша (достаточно нескольких первых символов) можно адресовать коммиты и файлы. Команда checkout с указанием ветки, адресует последний коммит ветки. Также при помощи HEAD можно использовать относительную адресацию:
HEAD~0 (равен HEAD) HEAD~1 предпоследний коммит (-1). сокращённо HEAD~ HEAD~2 (-2) Коммиты указыаются c помощью символа ~ , а ветки ^, счёт с нуля HEAD~1^1
Посмотреть историю коммитов
Выход из git log: нажать - "q". Листать можно с помощью PgUp, PgDown.
git log git log --graph --all Выводит подробную историю, последние коммиты вверху git log --oneline --graph --all Сокращённый вариант git log -m --name-only --oneline --follow имя файла git log -m --name-only --oneline показывает историю включая слияния git commit --amend - Исправления коммита, вместо создания нового
Слияние отдельных коммитов
git cherry-pick - используется для того чтобы взять изменения, внесённые каким-либо коммитом, и попытаться применить их заново в виде нового коммита наверху текущей ветки. Это может оказаться полезным чтобы забрать парочку коммитов из другой ветки без полного слияния с той веткой. git rebase - это "автоматизированный" cherry-pick. Он выполняет ту же работу, но для цепочки коммитов, тем самым как бы перенося ветку на новое место.
Посмотреть различия
Посмотреть различия между рабочим каталогом и индексом
git diff С помощью Мелд git difftool то же, но в виде списков всех файлов/директорий git difftool --dir-diff
Сравнение локальных файлов (рабочего каталога) и коммита на который указывает второй параметр, если не задан второй параметр сравнивает с индексом (stage)
git difftool [коммит/ветка] Тоже но в виде списков всех файлов/директорий git difftool --dir-diff [коммит/ветка]
Сравнить два выборочных коммита
git diff da758 da761 или git diff HEAD~1 HEAD~2
Почему консоль, а не графический интерфейс (GUI)?
Потому что консольные команды легко складываются в отдельный файлик-скрипт и задачи автоматизируются, скрипт запускается с разными параметрами. Запускать скрипт можно по крону, по событиям ну и из консоли.
Мы можем создавать цепочки команд, анализировать результат завершения, например после успешного коммита автоматом опубликовать файлы на тестовом сервере.
Работа в консоли
Чтобы посмотреть предыдущую команду, можно просто нажать стрелочку вверх на клавиатуре, посмотреть историю команд:
history Найти в истории команды содержащие ssh history | grep ssh
Можно выделять мышкой нужную строку и вставлять Shift+Ins. Удобно!
В файл C:\Users\ВашеИмя\.bashrc можно добавить сокращения для команд.
alias init="git init" alias stat="git status" alias fix="git commit -a -m $1" Теперь для коммита достаточно набрать: fix "Первый коммит"
Что нельзя сделать в рамках alias, можно сделать с помощью функций. Например добавим функцию поиска строки в истории с условием что если строка не задана, выводить всю историю, добавим функцию в .bashrc
his(){ if [ -z "$1" ]; then history; else history | grep $1; fi }
Теперь можно набира в консоли his [строка поиска] и получим список нужных команд
Команды для работы с удалёнными репозиториями
Про совместную работу и как лучше сделать слияние написано тут .
Смотрим какие репо у нас уже добавлены:
git remote show
Имена получили, можно полчить ещё инфы по имени:
git remote show имя
Если удалённые репо не были добавлены, добавляем и придумываем ему имя:
git remote add придуманное_имя ssh://git@gogs.com/project/repo.git
Получаем в индекс объекты из указанного репозитория. Рабочий каталог при этом не изменяется, только индекс:
git fetch придуманное_имя
Получаем объекты только из явно указанной ветки репозитория:
git fetch придуманное_имя имя_ветки
Пример проверки изменений на удалённом репо
1) Загружаем изменения из удалённого репо в локальный индекс (Ваши файлы при этом не изменяются, только индекс)
[git remote add remRepo git://server.com/someuser/somerepo.git] если не добавлен раньше git fetch remRepo
2)Создаём локальную временную ветку от ветки remRepo/somebranch и переходим на неё, сравниваем с помощью Мелд текущий коммит с предыдущим
git checkout -b temp remRepo/somebranch git difftool --dir-diff HEAD~1
3)Возвращаемся назад, удаляем временную ветку, объединяем наш мастер с somebranch
git checkout master git branch -D temp git merge remRepo/somebranch
Другой способ показывает различия текущей локального индекса и origin/master в данном случае удалённого(origin)
git whatchanged origin/master -n 1
fetch + merge это тоже самое что и pull, только даёт больше возможности контроля.
git clone выгрузит вам весь репо, а по pull выгружается только ветка.