Небольшая памятка по командам Git, приемы работы с локальным репозиторием.
1. Основные команды (выполненные в текущем каталоге корневой папки проекта):
Команда
Функция
git init
Создание репозитория в текущем каталоге.
git config user.name "имя"
Ввод имени пользователя репозитория(1).
git config user.email "box@domain.ru"
Ввод email пользователя репозитория(1).
git add -n *
Проверка, какие файлы будут добавлены в репозиторий.
git add readme.txt
Добавить в репозиторий файл readme.txt(2).
git add util/**/*.cpp
Добавить все файлы *.cpp, которые находятся в папке util и её подкаталогах.
git add *.c *.h *.s *.asm
Добавить в репозиторий все файлы(2) с расширениями *.c, *.h, *.s, *.asm.
git add --all
Добавит изменения всех отслеживаемых и не отслеживаемых в базе файлов. Опция -A аналогична опции --all, см. далее врезку "Q20. Как удалить отслеживаемые файлы из репозитория".
git commit -m "190311 first commit"
Выполнить коммит репозитория. Чтобы исправить текущую фиксацию, используйте команду git commit --amend.
git commit -am "текст комментария"
Добавление опции -a автоматически отразит в базе репозитория все отслеживаемые, модифицированные файлы перед применением фиксации. См. далее врезку "Q20. Как удалить отслеживаемые файлы из репозитория".
git status
Показать состояние репозитория - какие файлы были добавлены или изменены.
git status --untracked-files=no
Показать состояние репозитория без отображения файлов, которые еще не добавлены в репозиторий.
git rm --cached имяфайла
Убирает из индекса репозитория указанный файл (он больше не отслеживается). В рабочем каталоге этот файл останется. Команду удобно использовать, если вы поторопились добавить в индекс файл командой add, и хотите сделать дополнительные изменения в этом файле.
git log
Просмотр истории изменений репозитория (история фиксаций commit).
git log --reflog
Просмотр истории ВСЕХ фиксаций. Эта команда полезна, когда был произведен откат на более старую фиксацию (простая команда git log более свежие фиксации не покажет). См. также git reflog.
git reflog
Просмотр истории всех фиксаций в сокращенном виде. В некоторых случаях эта команда более удобна, чем git log --reflog. См. также врезку "Отличия git log --reflog и git reflog".
git pull
Взять изменения из remote-репозитория в локальный репозиторий.
git push
Выгрузить изменения в локальном репозитории в remote-репозиторий.
git push -uf
Принудительная выгрузка локальных изменений на сервер. Полезно использовать после команды git commit --amend.
git clone address [newname]
Сделать локальную копию репозитория(3).
git checkout -b имяветки
Создание новой ветви имяветки в репозитории, и переключение на работу в ней. Основная ветвь носит имя master, содержимое ветви master будет сохраняться неизменной.
git checkout master
Возврат в основную ветвь репозитория.
git checkout -- файл
Откат текущих изменений файла. Файл вернется к состоянию, которое было сохранено в последнем commit. Внимание: все изменения в файле, если они были, будут безвозвратно потеряны!
git stash
Позволяет временно заархивировать (припрятать [7]) измененные, но не прошедшие commit файлы, когда их требует перезаписать команда git pull.
git commit -e
Откроет текстовый редактор для ввода комментария фиксации. Этот вариант создания фиксации позволяет нативно вводить многострочный комментарий [11].
git diff ...
Сравнение фиксаций или ветвей проекта [12].
git reset --hard
Откат изменений всех файлов к последней фиксации. Внимание: это опасная команда в том плане, что все не зафиксированные изменения в файлах будут потеряны, и проект вернется к последнему состоянию, который был сохранен последним commit.
Примечания:
(1) Просмотреть все настройки можно командой git config -l или git config --list. (2) Если добавляемые файлы уже присутствуют в репозитории, то будут отображены изменения в этих файлах. (3) Команда git clone автоматически создаст папку для репозитория. Если не указан параметр newname, то имя этой папки будет назначено автоматически из имени репозитория, иначе репозиторий будет создан в папке с именем newname.
2. Подробная помощь по команде (откроется окно браузера со справкой):
git help команда
3. Краткая подсказка по команде:
git команда -h
4. Файл .gitignore позволяет создать список файлов, которые не нужно отслеживать. В этом файле можно делать комментарии, комментарием считается строка, которая начинается на символ #. В каждой строке указывается имя файла, который игнорируется, в именах можно использовать символы группирования * и ?. Чтобы исключить папку и файлы в ней, нужно добавить имя папки со слешем в конце, например: Debug/. Примеры файлов .gitignore см. в [4].
5. Можно создавать алиасы (синонимы) команд для быстрого доступа к ним. Вот так например, можно создать синоним git st для команды git status:
git config --global alias.st "status -s"
После этого команды git st и git status будут выполняться одинаково.
Установка выполняется по шагам с помощью обычного мастера. Однако не некоторых шагах не очевидно, какие опции выбирать.
Начальные 4 шага вопросов не вызывают. Нужно согласиться с условиями лицензии, выбрать папку для установки, поставить галочки устанавливаемых компонентов, выбрать место размещения для ярлыков запуска. Можно оставить все по умолчанию:
На этом шаге лучше всего выбрать редактор, которым Вы привыкли пользоваться. Мне нравится Notepad2:
На этом шаге предлагают настроить рабочее окружения для запуска Git. Первый вариант никак не модифицирует переменные окружения, подразумевается запуск Git под управлением командной строки MinGW bash. Второй и третий вариант прописывает некоторые переменные окружения (пути запуска), чтобы можно было запускать Git как из стандартного интерпретатора команд Windows, так и из MinGW bash. Я выбрал второй вариант, который задан по умолчанию:
Здесь выбирается библиотека, с помощью которой обслуживаются защищенные соединения. Оставил этот вариант по умолчанию:
Здесь выбрал вариант, который при операциях Git не модифицирует окончания строк текстовых файлов:
Здесь лучше оставить выбор по умолчанию. Вариант настройки MinTTY обеспечивает удобную цветовую подсветку выводимого текста в консоли:
Как работать с Git по шагам, начиная с создания репозитория. Предполагается, что Git уже установлен.
1. Зайдите в рабочий каталог проекта, запустите сессию bash. Можно конечно пользоваться и стандартной командной строкой Windows, но MINGW64 Bash удобнее, потому что он предоставляет цветовую подсветку сообщений, и корректно поддерживает Unicode, что позволяет пользоваться русскими буквами в командах Git.
2. Необходимо создать репозиторий и указать для него имя пользователя и email. Для создания репозитория выполните команду:
git init
После этого выполните следующие команды (вместо Your Name и anyemail@domain.ru укажите любое имя и адрес электронной почты):
3. Выполните команду git add -n *, которая выведет список файлов, которые могут быть потенциально добавлены в репозиторий. Скорее всего, в этом списке будут некоторые файлы, изменение которых отслеживать не нужно (объектные и двоичные файлы, картинки, логи и т. п.). Если такие файлы есть, то перейдите к шагу 4, а если нужно добавить все файлы из выведенного списка, то перейдите к шагу 6.
Если проект большой, и много его файлов находится в отдельных папках, то команду проверки git add -n можно запускать на файлы только одной папки. Например, вот проверка, какие файлы будут добавляться в репозиторий из папки lib проекта:
git add -n lib
4. Создайте в текстовом редакторе файл .gitignore, после этого начните добавлять в него записи для тех файлов, которые нужно игнорировать (Git не будет их отслеживать). Начните с папок, которые находятся в каталоге проекта, папку .git обрабатывать не нужно, это служебная папка.
Внимание: чтобы можно было в файле .gitignore использовать имена файлов с русскими буквами, файл .gitignore должен быть в кодировке UTF-8.
Предположим, что есть папка bin в каталоге проекта, и в ней находятся файлы с расширениями dlb, ldr, bin, log, которые не надо добавлять в репозиторий. Тогда в файл .gitignore добавьте следующие строки:
# Что игнорировать в папке bin:
bin/*.dlb
bin/*.ldr
bin/*.bin
bin/*.log
Если в папке много подкаталогов, и Вы хотите обработать их сразу все, то можно воспользоваться группировкой /**/:
doc/**/*.bmp
Обратите внимание, что первая строка начинается на #, это просто комментарий, добавленный для удобства. Сохраните файл .gitignore и снова выполните команду git add -n *, Вы увидите, что файлы из составленного списка игнорируются.
Каждую отдельную папку можно проверять командой git add -n имяпапки/.
5. После того, как создали список игнорируемых файлов для папки, добавьте её в репозиторий на отслеживание, для этого выполните команду git add без опции -n. Например, так добавляется папка lib:
git add lib/
Аналогичные шаги 4 и 5 проделайте со всеми папками и файлами проекта.
6. Теперь осталось сделать коммит.
git commit -m "190312 первый коммит"
Здесь опция -m задает обязательный комментарий для коммита. В комментарии я люблю указывать 6 цифрами дату коммита (YYMMDD). Имейте в виду, что русские буквы в комментарии можно указывать только в командной строке bash (он устанавливается вместе с Git).
7. Чтобы сделать локальную копию репозитория в текущем каталоге на диске, используйте команду git clone. Пример клонирования репозитория BluetoothBLEClient [8] через web-ссылку:
[git reflog]
NAME
git-reflog - Управление информацией reflog
SYNOPSIS
git reflog < subcommand> < options>
DESCRIPTION
Эта команда принимает различные субкоманды (subcommand), а также различные опции (options), зависящие от
subcommand:
git reflog [show] [log-options] [< ref>]
git reflog expire [--expire=< time>] [--expire-unreachable=< time>]
[--rewrite] [--updateref] [--stale-fix]
[--dry-run | -n] [--verbose] [--all [--single-worktree] | < refs>...]
git reflog delete [--rewrite] [--updateref]
[--dry-run | -n] [--verbose] ref@{specifier}...
git reflog exists < ref>
Ссылка на лог (reference logs, или "reflogs") записывается, когда в локальном репозитории обновляются подсказки
по ветвям (tips of branches) и другие ссылки. Reflogs полезны в различных командах Git, чтобы можно было
указать старое значение ссылки. Например, HEAD@{2} означает "где имя HEAD использовалось за 2 перемещения
до этого", а master@{one.week.ago} означает "где имя master используется для указания на одну неделю ранее
в этом локальном репозитории", и так далее. См. в gitrevisions(7) для более подробной информации.
Эта команда управляет информацией, записанной в reflogs.
Субкоманда "show" (которая также активируется по умолчанию, когда не указана субкоманда для git reflog) покажет
лог ссылки, предоставленной в командной строке (или HEAD, по умолчанию). Команда reflog охватывает все недавние
действия, и дополнительно HEAD reflog записывает переключение между ветвями репозитория. Команда git reflog show
это алиас для команды git log -g --abbrev-commit --pretty=oneline; см. git-log(1) для дополнительной информации.
Субкоманда "expire" elfkztn старые записи журнала. Записи, которые старше чем expire time, или записи, которые
старее чем expire-unreachable time, и недоступные из текущего состояния (current tip), будут удалены из reflog.
Обычно это не используется напрямую — вместо этого см. git-gc(1).
Субкоманда "delete" удаляет одиночные записи из reflog. Её аргумент должен четко указывать на удаляемую запись
(например "git reflog delete master@{2}"). Эта субкоманда также обычно не используется напрямую.
Субкоманда "exists" проверит, subcommand есть ли в reflog ссылка ref. Если есть, то будет возвращен нулевой
статус, иначе будет возвращен ненулевой статус.
Опции для show:
git reflog принимает любые опции, которые принимает команда git log.
Опции для expire:
--all
Обработать reflogs всех ссылок.
--single-worktree
По умолчанию, когда указано --all, обрабатываются reflogs из всех рабочих ветвлений (working trees). Эта опция
ограничит обработку на reflogs только из текущего working tree.
--expire=< time>
Удалит записи, которые старше указанного времени time. Если эта опция не указана, то время устаревания
(expiration time) берется из установки конфигурации gc.reflogExpire, которая в свою очередь по умолчанию
равна 90 дней. Опция --expire=all удалит записи независимо от их возраста; --expire=never выключит удаление
доступных записей (однако см. --expire-unreachable).
--expire-unreachable=< time>
Удалит записи старее чем < time>, которые недоступны из текущего положения (current tip) ветви репозитория.
Если эта опция не указана, то expiration time берется из установки конфигурации gc.reflogExpireUnreachable,
которая в свою очередь по умолчанию равна 30 дням. Опция --expire-unreachable=all удалит недоступные
записи независимо от их возраста; --expire-unreachable=never выключит раннее удаление недоступных
записей (однако см. --expire).
--updateref
Обновит ссылку на значение верхней записи reflog (т. е. < ref>@{0}), если предыдущая верхняя запись была
удалена (эта опция игнорируется для символических ссылок).
--rewrite
Если предшествующая запись reflog была удалена, подстроит её "old" поле SHA-1 равным "new" SHA-1 полю записи,
которая ей теперь предшествует.
--stale-fix
Удалит любые записи reflog, указывающие на "испорченные фиксации" (broken commits). Испорченная фиксация
это commit, который недоступен из любого имени ссылки (reference tip), и таким образом ссылается, прямо
или косвенно, на отсутствующий commit, tree, или объект blob.
Это вычисление включает в себя обход всех доступных объектов, т. е. это имеет ту же стоимость, что и
git prune. Это главным образом предназначено для исправления повреждения, вызванного сборкой мусора
(см. git-gc) более старых версий Git, которые не защищают объекты, на которые ссылается reflogs.
-n, --dry-run
Не делает реальное удаление любых записей; просто покажет, какие записи могли быть удалены.
--verbose
Выводит дополнительную информацию.
Опции для delete:
Команда git reflog delete принимает опции --updateref, --rewrite, -n, --dry-run и --verbose, которые имеют
тоже самое значение, которое использовалось для субкоманды expire.
[git log --reflog]
--reflog
Работает так, как если бы все объекты, упомянутые в reflog, были перечислены в командной строке
как < commit>.
[Манипуляции с ветками (branch)]
Ветка это просто обособленная версия проекта, которая может храниться в репозитории независимо от остальных веток. Можно переключаться между ветками, и делать в каждой из них какую-либо экспериментальную работу.
Команда
Функция
git branch
Показать список всех веток, которые существуют в репозитории. По умолчанию в репозитории существует только одна основная ветка - master. Если веток несколько, то текущая ветка будет помечена звездочкой и её название выделена зеленым текстом.
git branch -a
Посмотреть список веток в локальном и сетевом репозитории. Текущая ветка в локальном репозитории будет выделена зеленым цветом, а ветки в сетевом репозитории будут выделены красным, и будут иметь префикс remotes/origin/.
git branch имяновойветки
Создать новую ветку в проекте без переключения на неё.
git checkout -b имяновойветки
Создать новую ветку и переключиться на неё.
git switch -c имяновойветки
Создать новую ветку от текущей фиксации, и сделать эту ветку текущей. Как переключаться между фиксациями, см. [9].
git branch -D имяветки
Удалить ветку.
git switch -
Отмена предыдущей операции переключения между ветками.
git checkout ссылканаветку
Переключение между ветками. Вместо ссылканаветку может быть указано либо имя ветки (master или любое другое имя), либо первые шесть HEX-символа хеша фиксации. Список фиксаций с хешами можно посмотреть командой git log --pretty=oneline.
git branch -m old new
Переименовать ветку. Ветка с именем old получит имя new.
Хороший стиль работы - не плодить слишком много веток, чтобы не запутаться, либо вести подробную документацию по каждой ветке. В ветке master должен быть основной результат работы над проектом, а в ветках какие-либо мало значимые эксперименты.
Создайте файл .gitignore, поместите его в корневую папку проекта (там же, где находится папка репозитория .git), и в этом файле создайте строки, обозначающие исключаемые файлы (см. выше описание работы с файлом .gitignore).
Для этого используйте группировку /**/. Например, следующая запись .gitignore исключит из репозитория все файлы *.pdf, которые находятся в папке util, и во всех её подкаталогах:
util/**/*.pdf
Групповые подстановки можно также использовать и в командной строке Git.
Файл .gitignore должен иметь кодировку UTF-8. Вместо стандартной консоли команд cmd.exe в Windows используйте командную строку MINGW64 bash (устанавливается вместе с Git).
Процесс по шагам (взято из замечательной статьи [6]):
1. Сначала надо создать на сервере пустой репозиторий. Обычно это делается в HTML-интерфейсе сервера. После этого нужно запомнить Git-ссылку на этот репозиторий. Предположим, ссылка такая:
http://git.netserver.ru/username/myproject.git
2. В папке локального репозитория выполнить команды:
git remote add server http://git.netserver.ru/username/myproject.git git push server master:master
Первая команда добавляет в конфигурацию репозитория новый сервер, вторая делает выгрузку репозитория на сервер.
3. Для того, чтобы команды git теперь работали с репозиторием на сетевом сервере git.netserver.ru, выполните команду:
Иногда надо дополнительно выполнить следующую команду, чтобы протолкнуть (push) текущую ветку репозитория (branch) на сетевой сервер, и установить его как приемник push:
git push --set-upstream origin master
После этой команды git push и git pull будут по умолчанию работать с репозиторием на сетевом сервере.
4. Чтобы сохранить наработанные изменения и протолкнуть их на сервер, используйте команды:
git add . git commit -a git push
Чтобы засинхронизировать текущий проект с сервером, используйте команду:
В репозитории (это был nRF5x SDK 12.3) множество проектов примеров содержат файлы Makefile, распределенные по разным каталогам. Простая команда с указанием имени файла не позволяет добавить в репозиторий эти файлы:
d:\asm\nRF5_SDK_12.3.0_d7731ad>git add Makefile
fatal: pathspec 'Makefile' did not match any files
Проблема в том, что тут указано полное имя, без шаблона wildcard. Чтобы команда сработала, нужно указать в качестве имени файла */Makefile, что будет соответствовать файлам Makefile в любом из подкаталогов репозитория:
Попытался сделать push ветки на сервер, не получилось, git выдает сообщение:
fatal: Вы сейчас не находитесь ни на одной из веток
В чем ошибка: перед внесением изменений в код не была установлена текущая ветка. Что надо сделать:
1. Копию всех исходников! 2. git checkout имя_той_ветки_котору_надо_выгрузить_на_сервер. Эта команда отменит все изменения, и вернет старое локальное состояние этой ветки. 3. Вернуть все исходники обратно из копии, сделанной на шаге 1. 4. git add *, git commit -m "bla-bla" 5. git push
Восстановить случайно удаленный файл можно командой git checkout имяфайла.
$ git status
Текущая ветка: main
Эта ветка соответствует « main ».
Изменения, которые не в индексе для коммита:
удалено: src/adcbatt.c
удалено: src/main.c
$ git checkout src/adcbatt.c
Updated 1 path from the index
$ git checkout src/main.c
Updated 1 path from the index
В чем ошибка: перед внесением изменений в код не была установлена текущая ветка. Что надо сделать:
1. Копию всех исходников! 2. git checkout имя_той_ветки_котору_надо_выгрузить_на_сервер. Эта команда отменит все изменения, и вернет старое локальное состояние этой ветки. 3. Вернуть все исходники обратно из копии, сделанной на шаге 1. 4. git add *, git commit -m "bla-bla" 5. git push
Подобная ошибка может произойти, если была переустановка операционной системы, и каталог репозитория был восстановлен с помощью внешнего диска с файловой системой FAT32.
$ git status
fatal: detected dubious ownership in repository at '/home/имяпользователя/каталог'
To add an exception for this directory, call:
Исправить ошибку можно либо командой git config --global, как советуется в этом сообщении об ошибке, либо если поменять владельца каталога репозитория на текущего пользователя:
Предположим, что вы сделали несколько изменений в проекте, и не хотите делать фиксацию (commit) этих изменений. И вам нужно переключиться на какую-то предыдущую фиксацию, сбросив все эти изменения. Для этого нужно сначала сбросить все изменения командой git reset --hard, а потом командой git checkout переключиться на нужную фиксацию, указав её контрольную сумму:
При переходе на новый SDK было удалено из локальной папки проекта множество файлов. После команд git add * и git commit -m "сообщение фиксации" эти файлы остались в локальном репозитории git, помеченные как "deleted". Как их быстро удалить, чтобы не удалять каждый файл по отдельности командой git rm?
Это можно сделать следующей последовательностью команд:
$ git add --all $ git commit -am "Удалил файлы из репозитория git." $ git status $ git push
Что означает -all. Опция --all команды add (можно применить вместо неё -A) добавит изменения всех отслеживаемых и не отслеживаемых в базе файлов, т. е. удалит из репозитория все удаленные в проекте файлы, и добавит не отслеживаемые, в том числе и те, которые начинаются на точку (такие как .gitignore или .config) (см. [1]).
Что означает -am. Из документации: "Команда git commit -a автоматически отразит в базе репозитория все отслеживаемые, модифицированные файлы перед применением фиксации. Если вы считаете, что стадия git add в рабочем процессе излишняя, Git позволит вам пропустить эту часть с помощью опции -a. Это в основном говорит Git запустить git add на любом файле, который "отслеживается" - т. е. на любом файле, который был в вашей последней фиксации, и который был изменен. Это позволит вам, если захотите, получить рабочий процесс больше похожим на стиль Subversion, когда после редактирования файлов вы просто запускаете git commit -a, когда хотите сделать снимок всего, что было изменено. Хотя вам все еще понадобится запустить команду git add, чтобы начать отслеживать новые файлы, так же как и в Subversion.
Таким образом, команда git commit -am позволит вам добавить изменения в базу репозитория и одновременно создать фиксацию с указанным сообщением [2].
[Pro Git]
Существует книга, которая может послужить замечательным введением в мир git - Pro Git, авторы Scott Chacon и Ben Straub. Эта книга переведена на многие языки, в том числе и на русский язык.
Книга на русском языке доступна в виде репозитория GitHub [13], а также доступна её онлайн-версия [14]. Получить книгу последней версии в популярных электронных форматах можно, если выполнить её компиляцию (см. врезку).
После выполнения этой команды в папке проекта progit2-ru появятся скомпилированные файлы progit.pdf, progit.mobi, progit-kf8.epub, progit.fb2.zip, progit.epub, progit.html.
При выполнении команды bundle install столкнулся с ошибкой:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory:
/home/user/asm/progit2-ru/.bundle/vendor/ruby/3.0.0/gems/racc-1.7.3/ext/racc/cparse
/usr/bin/ruby3.0 -I /usr/lib/ruby/vendor_ruby -r ./siteconf20240109-25035-tgyk07.rb extconf.rb
mkmf.rb can't find header files for ruby at /usr/lib/ruby/include/ruby.h
You might have to install separate package for the ruby development
environment, ruby-dev or ruby-devel for example.
extconf failed, exit code 1
Как исправить:
$ sudo apt install ruby-bundler
[Словарик]
branch ветвление проекта (создание его отдельной версии в репозитории).
commit легковесный снимок состояния файлов в определенный момент времени (когда был сделан коммит).
head самая последняя версия файлов в репозитории.
repository репозиторий, база данных, где хранится история изменений проекта. Git хранит репозиторий в папке .git, которая находится в корневом каталоге проекта.
staging area область файловой системы (список файлов), подготовленная к коммиту.
stash операция, которая поглощает грязное состояние рабочего каталога, то есть изменённые отслеживаемые файлы и изменения в индексе, и сохраняет их в стек незавершённых изменений, которые вы потом в любое время можете снова применить.
[Ссылки]
1. Downloads Git site:git-scm.com. 2. Learn Git site:atlassian.com. 3. Подробное введение в работу с Git site:tproger.ru. 4. A collection of useful .gitignore templates site:github.com. 5. git: быстрый старт. 6. Как перенести локальный GIT-репозитарий на сервер вместе со всей историей site:webhamster.ru. 7. Инструменты Git - Припрятывание и очистка site:git-scm.com. 8. jjjsmit / BluetoothBLEClient site:github.com. 9. Git: как переключаться между фиксациями. 10. How do I force "git pull" to overwrite local files? site:stackoverflow.com. 11. git: как создавать многострочный комментарий для commit. 12. git: как сравнивать фиксации и ветки. 13. Репозиторий Pro Git на русском языке. 14. Онлайн-версия Pro Git на русском языке. 15. 240109progit2-ru.zip - скомпилированная книга Pro Git на русском языке в форматах HTML, EPUB, FB2, Mobi (kf8), PDF. 16. Is there a way to cause git-reflog to show a date alongside each entry? site:stackoverflow.com. 17. Output of git branch in tree like fashion site:stackoverflow.com.