Skip to content

Instantly share code, notes, and snippets.

@artem78
Last active February 7, 2024 01:59
Show Gist options
  • Save artem78/33ff391b7788e37ac97ca477d541e1d9 to your computer and use it in GitHub Desktop.
Save artem78/33ff391b7788e37ac97ca477d541e1d9 to your computer and use it in GitHub Desktop.
Шпаргалка по командам GIT

Git-logo

Заметки по наиболее часто используемым командам GIT для себя и не только

Подтянуть новые коммиты из удалённого репозитория

Или в чём разница между git pull и git fetch? Если совсем коротко, то:

git pull = git fetch + git merge

fetch всего лишь получает изменения с удалённого сервера никак не изменяя локальные ветки. pull вливает эти изменения в текущую ветку по возможности методом "быстрой перемотки" (fast forward).

Влить изменения из одной ветки в другую

Например, из feature в master:

git checkout master
git merge feature

И удалить более ненужную ветку feature (опционально):

git branch -d feature

Не отслеживать изменения в файле без добавления его в .gitignore

git update-index --assume-unchanged settings.ini

Отменить игнорирование предыдущей коммандой:

git update-index --no-assume-unchanged settings.ini

Извлечение из stash-а

Извлечь из запрятанного и удалить оттуда:

git stash pop <commit hash>

Извлечь из запрятанного, но без удаления:

git stash apply <commit hash>

Если нужен последний элемент, <commit hash> можно не указывать.

Навести порядок в коммитах

Например, в последних пяти:

git rebase -i HEAD~5

Список команд:

  • p или pick - использовать коммит
  • r или reword - использовать коммит, но изменить текст сообщения
  • e или edit - использовать коммит, но приостановить для его изменения
  • s или squash - использовать коммит, но объединить его с предыдущим
  • f или fixup - то же что "squash", но отбрасывает сообщение коммита
  • x или exec - выполняет команду через командную оболочку (shell)
  • d или drop - отбросить коммит (удалить)

Также можно переупорядочивать коммиты.

Пример: объединим несколько коммитов в один:

pick e51ad80 Clean mess
squash 91d085c Move text constants to methods
squash 0ec8451 Replace _L macros to _LIT
squash c394739 Move code from MainL to CListener
squash 305d2c6 Main class rename
squash c614bc5 Add g prefix for globar variable
squash 20f7919 Fix
squash 0d824e5 Add TRAP_IGNORE macros

Здесь команда pick оставляет первый коммит в качестве базового, а squash объединяет остальные с первым.

Удаление последних коммитов в ветке

git reset --hard 89f6600

Здесь 89f6600 - это хеш коммита, после которого идут ошибочные коммиты.

Если нужно убрать только самый последний, то можно записать короче:

git reset --hard HEAD^

Метки (теги)

Создание простой (легковесной) метки:

git tag v5.6.7

Создание аннотированной метки:

git tag -a v5.6.7

Удаление метки:

  • локальной: git tag -d v5.6.7
  • на сервере: git push origin :refs/tags/v5.6.7

Перенос существующей метки на другой коммит (например, текущий) выполняется с флагом -f:

git tag -f v1.4

Просмотреть список всех тегов:

git tag -l

Отправка меток в удалённый репозиторий

Отправить вместе с коммитами ещё и метки:

git push --follow-tags

Отправить в удалённый репозиторий только определённую метку:

git push origin <tag name>

Начиная с Git 2.4 появилась возможность задать автоматическую отправку меток в настройках .gitconfig:

git config --global push.followTags true

Другой вариант - вручную добавить в файл .gitconfig строки:

[push]
	followTags = true

Примечание: Автоматически git отправляет только аннотированные метки, пропуская легковесные. Рекомендуется аннотированными метками отмечать релизы, а легковесные использовать только в локальном репозитории. (Подробности тут)

Сбросить изменения в определённом файле до коммита

git checkout -- myfile.txt

Перебазирование веток

Подтянуть последние изменения из ветки master в feature. Другими словами, нужно переместить feature на конец master:

git checkout feature
git rebase master

Поиск "проблемных" коммитов при помощи команды bisect

Допустим, что возникла ситуация, когда после внесения некоторых изменений в проект, что-то сломалось и нужно найти этот "бракованный" коммит. Включаем bisect:

git bisect start

Затем указываем плохой и хороший коммиты:

git bisect bad 71fefda
git bisect good fd62f67

Псле этого git будет циклически переключать коммиты между этими двумя. Проверяем, если проблема сохраняется, вводим:

git bisect bad

А если нет, то:

git bisect good

Таким образом рано или поздно будет найдет виновный коммит:

67c1fee5c245619df28a963cdb829d8911d891ad is the first bad commit
commit 67c1fee5c245619df28a963cdb829d8911d891ad
Author: artem78 <megabyte1024@ya.ru>
Date:   Tue Mar 31 19:32:50 2020 +0300

    Downloading tiles from OSM dafault layer

:040000 040000 99d4b7ff504abdcf10fdeb6ab5975f9ae5907ae6 75c522f62958fe3c0efb69069751d088cd7bcea8 M      group
:040000 040000 45a8bd89290124fd156aa76963ee2068422eecaf b53d023173d23d40766ee100366dc92ac3378d05 M      inc
:040000 040000 cb7d95e196d71d57264e3ed2f944e79197ded386 c8b06f81b93ab54bfd2d182b5599ec7035795da2 M      src

В заключение, чтобы завершить работу команды bisect и вернуться к исходному состоянию вводим:

git bisect reset

Переименовать локальную ветку

git branch -m old_branch new_branch

Перенос последнего коммита в другую ветку

Из ветки A в ветку B:

git checkout B
git cherry-pick A
git checkout A
git reset --hard HEAD^

Подмодули (submodules)

Добавление нового

git submodule add git@github.com:url_to/awesome_submodule.git path_to_awesome_submodule

Патчи

Для чего оно надо?

Например, у меня возникла такая ситуация - существуют два проекта с частично общей кодовой базой (в таком случае более логично было бы использовать подмодули, но мы сейчас не об этом). В первом проекте были внесены изменеия, которые также нужно внести и во второй репозиторий. Что же делать? На помощь нам приходят патчи.

Как использовать?

В первом репозитории на базе существующего коммита создаём патч командой:

git format-patch -1 <commit hash>

Или, если это самый последний коммит, то:

git format-patch -1

После выполнения команды, должен появиться файл с подобным названием:

0001-Fix-leaving-methods-in-destructor-E32USER-CBase-66-p.patch

Затем копируем его во второй репозиторий и выполняем:

git apply my-patch.patch

или:

git am --signoff < my-patch.patch

Статистика

Сгруппировать коммиты по авторам

git shortlog
Результат выполнения команды
$ git shortlog
0017031 (1):
      Enhance pluginsAdmin.h

A-R-C-A (10):
      Fixed crash issue due to unsigned variable
      Enhancement: add conflict detection to Shortcut Mapper
      Improved Single Line Comment
      Added more Change Case variants
      Add commands for moving the current file tab Forward/Backward
      Added new Option: Enable scrolling beyond last line
      Add Scroll Tab Bar with mouse wheel capacity
      Improve tab alignment in Shortcut Mapper
      Make margins dpi aware
      Make Task List dpi aware

Ach3r0n (1):
      translationsd: update dutch localization (closes #537)

Acheron (1):
      Update dutch.xml

Adam Stachowicz (1):
      Polish translation: Ampersand fix
:

Показать общее кол-во коммитов для каждого автора

git shortlog -s -e -n
Результат выполнения команды
$ git shortlog -s -e -n
  1144  Don Ho <don.h@free.fr>
   640  Don HO <don.h@free.fr>
   358  donho <donho@f5eea248-9336-0410-98b8-ebc06183d4e3>
    83  harrybharry <harrybharry@f5eea248-9336-0410-98b8-ebc06183d4e3>
    79  dail8859 <dail8859@yahoo.com>
    67  SinghRajenM <singh.rajen15@gmail.com>
    57  Christian Grasser <christian.grasser@live.de>
    56  Rajendra Singh <singh.rajen15@gmail.com>
    49  Andreas Jönsson <jonandr@hush.com>
    36  Damien GERARD <damien@iwi.me>
    30  Scott Sumner <30118311+sasumner@users.noreply.github.com>

Здесь флаг -n отвечает за сортировку кол-ва коммитов по убыванию.

Объединение псевдонимов автора

Может возникнуть ситуация, когда один и тот же человек сделал коммиты под разными именами, но с одинаковым адресом электронной почты. В этом случае вывод команлы shortlog будет похож на этот:

$ git shortlog -s -e
   5   John Doe <johndoe@email.xx>
   12  John D.  <johndoe@email.xx>
   27  jonny    <johndoe@email.xx>

Чтобы сгруппировать коммиты с одинаковым email-ом под одним автором нужно в корне репозитория (т.е. там, где находится папка .git) создать текстовый файл с именем .mailmap и содержимым:

Your Name <youremail@mail.xx>

Для примера выше он будет выглядеть так:

John Doe <johndoe@email.xx>

Теперь вывод комманды shortlog будет следующий:

$ git shortlog -s -e
   44   John Doe <johndoe@email.xx>

Замечание: правила, заданые в файле .mailmap не изменяют содержимое или историю коммитов и влияют исключительно на вывод команды shortlog.

Изменение автора и даты последнего коммита

Не все люди дружат с Гитом или ГитХабом и поэтому присылают свои изменения в виде отредактированных файлов ко мне на электронную почту. Я делаю коммит как обычно, а затем изменяю автора последнего коммита. Кроме того, письмо могло пролежать непрочитанным несколько суток, поэтому я, как правило, также меняю и дату создания коммита.

git commit --amend --no-edit --date="Sun, 17 Apr 2022 21:06:27 +0300" --author="John Doe <johndoe@example.com>"

Если вместо определённой даты нужно выставить текущую, то используем ключ --date=now.

Проверить можно следующим образом:

git log --pretty=fuller --max-count=1
commit 6264607de6053fa9b24a2c269fe2d93038bb01fa
Author:     John Doe <johndoe@example.com>
AuthorDate: Sun Apr 17 21:06:27 2022 +0300
Commit:     artem78 <********@ya.ru>
CommitDate: Mon Apr 18 21:11:16 2022 +0300

    [Localization] Update Polish translation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment