Git - andyceo/documentation GitHub Wiki

Git

Данная страница посвящена системе управлением версиями Git

Установка Git

Начиная с Ubuntu 12.04, вы можете установить Git так:

sudo aptitude install git

Подробная статья на Github про установку Git: Set Up Git

Настройка Git

Имейте в виду, что все настройки Git сохраняет для того пользователя, из-под которого вы запускаете эти команды, т.е. из-под текущего. Допустим, если пользователь - andyceo, то вся глобальная (для данного пользователя) конфигурация будет сохраняться в файл /home/andyceo/.gitconfig

Глобальная конфигурация (которая применяется по умолчанию для всех новых пользователей на данном хосте) хранится в /etc/gitconfig.

Посмотреть, откуда читается конфигурация Git для данного репозитория: git config --list --show-origin

Подпишем GIT под определенного пользователя (запишем в настройки)

git config --global user.name "andyceo"
git config --global user.email [email protected]

Настройка цветного вывода

git config --global color.ui auto

Настройка других параметров

git config --global color.diff no
git config --global color.status auto
git config --global color.branch auto
git config --global core.editor vim
git config --global core.pager "vim -"

Основные команды GIT

Извлечение (клонирование) репозитория: git clone

  • Извлечь репозиторий полностью в папку (latest development version): git clone путь-к-репозиторию папка-куда-извлечь.

    git clone /home/alice/project myrepo
    
  • Извлечь последний код без извлечения всего репозитория:

    git clone --depth 1 your_repo_url
    git clone --depth 1 git://phpmyadmin.git.sourceforge.net/gitroot/phpmyadmin/phpmyadmin pma.ruware.com
    

Обновление репозитория: git pull

  • Обновить (находясь в папке репозитория): git pull

Переключение между ветками, тегами, коммитами и т.п.

  • Извлечь определенную метку: git checkout имя_метки

  • Извлечь из ветки:

    git checkout origin/MAINT_3_3_5</code>или:<code bash>
    git branch --track MAINT_3_3_5 origin/MAINT_3_3_5
    git checkout MAINT_3_3_5
    

Работа с логами

  • Выводим ASCII-репрезентацию истории коммитов: git log --graph

Отменить последний коммит

  • удаляем только коммит (изменения останутся): git reset HEAD~
  • удаляем коммит и изменения: git reset --hard HEAD~
  • делаем коммит, отменяющий другой коммит (нужно передать хеш коммита, который мы отменяем): git revert aa600
  • удаление последнего коммита, даже если он был запушен: Git HowTo: revert a commit already pushed to a remote repository

Отмена незакоммиченных изменений

  • Отменить все изменения, которые произошли с файлами, находящимися под управлением Git:

    git checkout -f
    
  • Удалить все изменения (удалить файлы), которые произошли с файлами, НЕ находящимися под управлением Git (папки при этом не удаляются):

    git clean -f
    
  • Отменить все изменения (удалить файлы и папки), которые произошли с файлами И папками, НЕ находящимися под управлением Git:

    git clean -f -d
    
  • Удалить только игнорируемые файлы:

    git clean -f -X
    
  • Удалить игнорируемые и неигнорируемые файлы (обратите внимание на различие в последнем x в этом и предыдущем примерах!):

    git clean -f -x
    

Работа с удаленным репозиторием

  • Создание новой ветки на сервере: ```bash # Создание удаленной ветки git push origin origin:refs/heads/new_branch

    # Проверяем, создана ли удаленная ветка
    git pull origin
    git branch -r
    
    # Создаем локальную ветку, и закрепляем ее за удаленной
    git checkout -b new_branch origin/new_branch
    ```
    
  • Удалить ветку на сервере: git push origin :heads/new_branch

  • Сделать diff между незакомиченными локальными изменениями и последним коммитом, исключая все .info файлы в репозитории (полезно для выяснения, патчено ли ядро Drupal, например): bash git diff -- `git ls-files | grep -v '.info'`

Проверка целостности репозитория и очистка мусора

  • проверка целостности репозитория: git fsck
  • очистка мусора: git gc, git gc --prune=now

Работа с субмодулями

submodule позволяет добавлять посторонние репозитории в отдельную папку проекта. Подробности: git help submodule.

Показать все субмодули текущего репозитория:

git submodule

Добавление субмодуля

Добавить подмодуль в текущий репозиторий (выполнять в папке репозитория):

git submodule add -b master [email protected]:andyceo/ansible-role-letsencrypt.git roles/andyceo.letsencrypt

Затем:

git submodule init

Скачаем подмодуль:

git submodule update

Обновим все подмодули:

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"

Удаление субмодуля:

Начиная с 2022 года, это можно сделать одной командой:

git rm <path-to-submodule>

и закоммитить. Однако файлы субмодуля не удаляются из подпапки .git, чтобы, согласно документации, "to make it possible to checkout past commits without requiring fetching from another repository". Также субмодуль не удаляется из конфигурации. Убрать файлы и настройки субмодуля можно командами:

rm -rf .git/modules/<path-to-submodule>
git config --remove-section submodule.<path-to-submodule>

Полезная ссылка: https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule

Другие возможности

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

  • cat .gitmodules - этот файл читает команда git submodule init
  • git submodule status - показать список и статус всех субмодулей в репозитории
  • git submodule status --recursive - то же самое, но рекурсивно. Упадет с ошибкой, если какой-то подмодуль не был извлечен

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

git submodule update --init --force --remote <module-name>

Недостатки субмодулей

  1. Команда git archive игнорирует подмодули
  2. в рабочей копии после git checkout надо выполнять git submodule update –init

Работа с несколькими удаленными серверами (git remote) в одном репозитории

Добавим новый удаленный сервер и отправим туда все ветки, коммиты и теги:

git remote add ANOTHER_REMOTE ssh://[email protected]:10022/user/project.git
git push ANOTHER_REMOTE --all
git push ANOTHER_REMOTE --tags

Не использовать опцию --mirror, а то она переподключит все локальные ветки к новому репозиторию.

А также можно сделать через опцию --mirror:

git clone --mirror <URL to my OLD repo location>
cd <New directory where your OLD repo was cloned>
git remote set-url origin <URL to my NEW repo location>
git push --mirror origin

Основные команды GIT - продолжение

  • git init: новый репозиторий
  • git status: состояние: что было редактировано, что добавлено в индекс для коммита
  • git add .: добавить в индекс все изменения. git add file.txt - добавить содержимое файла в индекс git add -i - интерактивное добавление, позволяет выбирать файлы, которые надо добавить. Для каждого файоа можно добавить некоторые изменения, другие оставить для следующего коммита. git add -p - про каждое изменение в файле спрашивает, добавить его в индекс или нет -p==patch
  • git commit -m «Initial commit»: сделать первый commit (некоторые команды криво работают, пока не сделать первый коммит)
  • git commit -am «comment»: add + commit, но новые файлы не будут добавлены
  • git commit –amend - докоммитить предыдущий коммит. если что еще надо в него добавить или изменить текст коммита: git commit –amend -m «new comment» git commit –amend -C HEAD - не менять текст коммита. Вместо HEAD может быть любая ссылка на коммит, например: - HEAD - последний коммит текущей ветки - sha1_hash коммита - имя ветки - имя_ветки2 - два коммита назад от HEAD'a ветки - тег - HEAD^2 - два коммита назад от HEAD - HEAD1 - тоже два коммита назад от HEAD
  • git log: логи коммитов
  • git log –all: лог со всех веток
  • git log –graph –all –oneline: все ветки, показать связь между ветками. информация об одном коммите должна влезать на одну строку
  • git log -p - патчи
  • git shortlog -sne -- - показать статистику в текущем репозитории. Можно указать папку, для которой соберется статистика: git shortlog -sne -- folder
  • git branch: список веток
  • git branch newfeature: создать ветку newfeature
  • git checkout newfeature или тоже самое одной командой: git checkout -b newfeature …редактирование (программирование фичи)
  • git commit -am «new feature done»: ее commit
  • git checkout master: переход в ветку master
  • git merge newfeature: объединение ветки newfeature с master теперь в master работает новая фича. Если при слиянии возникли конфликты, то посмотреть на них можно:
  • git status edit Press.pm: поправить git add Press.pm git commit - завершает процесс слияния Если надоело разрешать конфликты, то можно вернуть обе ветки в исходное состояние: git reset –hard HEAD А если commit завершен, то вернуть обратно можно так: git reset –hard ORIG_HEAD
  • git checkout -f: откатить незакоммиченные изменения
  • git checkout – file.txt: вынимает версию файла, подготовленную к коммиту (после git add file.txt)
  • git checkout <commit> file.txt: из указанного коммита
  • git tag v4.2: простой тег
  • git tag -a v4.2 -m «stable v4.2»: аннотированный тег (более подробный, вроде commit'a)
  • git tag -d v4.2: удалить тег
  • git tag - список тегов
  • git tag -l <pattern>: поиск по шаблону
  • git log v4.2: показать все коммиты, начиная с тега v4.2
  • git log v4.2 Press.pm - все коммиты, начиная с тега v4.2, включающие изменения файла Press.pm
  • git branch –contains v4.2: ветки с данным тегом
  • git show v4.2: на какой commit указывает тег, когда и кем был сделан
  • git describe: показывает сколько коммитов было с последнего тега: v4.2-g[хэш последнего коммита]
  • git reset: undo
  • git reset –hard <commit>: отменить самым радикальным и не поправимым образом все, что было сделано и закоммичено после коммита . Рабочая папка тоже будет содержать проект из этого коммита.
  • git reset –soft <commit> - делает последним коммитом (HEAD'ом). Рабочая папка остается не тронутой.

git giu - оконный интерфейс в windows gitk - оконный интерфейс в linux gitk –all - все ветки

git update-index - обновить индекс содержимого файлов git update-index –add - добавлять файлы с диска git update-index –remove - удалять файлы, если их нет на диске

git diff - все изменения от последнего commit'a git diff file.txt - изменения в одном файле git diff –cached - сравнение последнего commit'a и того, что подготовлено для нового коммита git diff - сравнение commit'a и рабочей папки, например git diff HEAD^2 file.txt git diff –stat sha1old..sha2new - список файлов и количество измененных строк между двумя коммитами Сравнение двух веток: git diff master..newfeature - сравнение двух последних коммитов веток git diff master…newfeature - показывает разницу между последним коммитом в newfeature и его последнего предка в master. Полезно, если ветка newfeature была объединена с master, а потом в ней еще что-то изменилось. Тогда эта команда покажет разницу с последнего merga.

git blame file.txt - кто и когда редактировал файл

Временные коммиты git stash - сделать временный коммит рабочей папки … поправить что-нибудь в другой ветке, переключиться обратно и git stash apply - вернуть рабочую папку обратно. git status list - выводит список стешей, их может быть много, например:

git stash save «comment» git stash apply stash@{1} - где stash@{1} - нужный стеш из git status list

Файл .gitignore - список шаблонов файлов, история по которым не ведется. То есть файлы, которые не попадают в репозиторий Например: #пароли к бд MyConfig.pm #temp files: .~ #все логи, кроме ошибок *.log !error.log

Или можно запретить все, кроме избранных файлов: . !.pl !.pm

Удаленные repo: git branch -a - список веток, включая удаленные (т.е. с исходного репозитория) git remote add remoteName remoteURL - добавить удаленную ветку. Все удаленные репозитории показываются в файле .git/config [remote «origin»] fetch = +refs/heads/:refs/remotes/origin/ - связи между ветками url = http://sn:@192.168.0.2/project/projectname.git

Забрать изменения с удаленного компьютера можно двумя способами: 1) git fetch origin master - забирает с удаленного компьютера изменения в ветке master git diff master..origin/master - посмотреть, что изменилось git checkout -b testbranch и git merge origin/master - объединить изменения с удаленного компьютера с веткой master …протестировать git checkout master git merge testbranch 2) все это одной командой (если не надо тестировать): git pull origin master

git push origin master - пихает изменения из текущей ветки в origin master. Желательно делать push только в bare репозитории, т.к. команда push портит содержимое рабочей папки.

git rebase master - на master накладывается текущая ветка (сначала будут идти все коммиты master, потом все коммиты текущей ветки). Если просто объединить, то коммиты будут перемешаны и получится не красиво. если возникли конфликты, их надо разрешить и запустить git rebase –continue Если надоест: git rebase –abort - отменить все git rebase –skip - пропустить один коммит

git rebase -i HEAD~10 - почистить историю последних 10 коммитов в текстовом редакторе (из переменной окружения EDITOR) откроется список коммитов в формате: pick hash message Чтобы удалить коммит - удалить строку, Поменять порядок коммитов - поменять порядок строк объединить коммит с предыдущим - pick поменять на squash для внесения изменений в коммит - pick на edit После этого, если отметили коммиты, то git commit –ament если нет, то git commit –continue Подробности в git help rebase

git filter-branch –tree-filter 'rm cgi-bin/MyConfig.pm' HEAD Удалить файлы из всех коммитов подробности в git help filter-branch

поиск коммита, в котором возникла ошибка: git bisect start git bisect bad sha1_bad_commit git bisect good sha1_good_commit git извлечет состояние по середине между хорошей и плохой версиями. Если в этом состоянии по прежнему есть ошибка: git bisect bad Если работает, то git bisect good После окончания изменения надо выполнить git bisect reset Можно автоматизировать процесс тестирования командой: git bisect run «perl testrun.pl» Скрипт testrun.pl должен возвращать 0, если все хорошо.

импорт-экспорт истории: git fast-import </tmp/history git fast-export >/tmp/history

subtree История коммитов из внешнего проекта перенаправляется в подпапку с использованием стандартного механизма работы с внешними ветками. git remote add -f creocms /path/to/creocms git merge -s ours –no-commit creocms/master git read-tree –prefix=creocms/ -u creocms/master git commit -m «Merge creocms» Изменения из creocms вытягиваются командой: git pull -s subtree creocms master В каждой рабочей копии надо выполнять git remote add -f creocmms /path/to/creocms И в каждой новой ветке: git fetch creocms

Источник: http://wiki.hasanov.ru/web-dev/git-help Также можно посмотреть: http://help.github.com/git-cheat-sheets/

Работа с Bitbucket & Github сервисами и форки

Предполагается, что вы уже форкнули какой-либо репозиторий на Bitbucket или Github, через веб-интерфейс.

Создание upstream-ветки

  • Создаем связь с upstream-репозиторием:

      git remote add upstream [email protected]:USER_LOGIN/UPSTREAM_REPO_NAME.git
    
  • Скачиваем данные из upstream-репозитория:

      git fetch upstream
    
  • Создаем локальную ветку upstream, которая будет связана с веткой master upstream-репозитория и сразу переключимся на нее:

      git checkout -b upstream upstream/master
    

Разрешение конфликтов форка с основным репозиторием

Предполагается, что вы ведете работу в ветке master, и у вас есть ветка upstream (см. Создание upstream-ветки)

# Обновим upstream до актуального состояния
git checkout upstream
git pull

# Сольем свой master с upstream
git checkout master
git merge upstream

# смотрим и решаем конфликты
git status
<<<Разрешить конфликт в редакторе, например PHPStorm>>>

# заканчиваем слияние
git add FILE_WITH_RESOLVED_CONFLICT
git commit
git push

Работа с Git при подготовке Pull Request для Bitbucket без истории коммитов

Предположим, вы всю работу делали в своей ветке master, а для подготовки пулл реквеста намерены создать ветку clean_code.

Также, мы исходим из предположения, что вы настроили себе локальную ветку upstream, которая синхронизирована с master-веткой upstream-репозитория (репозитория, который вы форкнули) (см. Создание upstream-ветки).

  1. Перед подготовкой пулл-реквеста, синхронизируйте ваш репозиторий с основным, разрешите все конфликты (если есть).

  2. Выполните следующее:

     git checkout master
     git pull
    
     git checkout -b clean_code upstream
    
     # удостоверьтесь, что изменения именно те, которые вы хотите отослать
     git diff clean_code..master
    
     git merge --squash master
     git commit
    
     git push -u origin clean_code
    
  3. В веб-интерфейсе Bitbucket (или Github) делаете пулл реквест из вашей ветки clean_code в основной репозиторий, ветку master

  4. Дальнейшую работу над замечаниями к данному пулл реквесту, производите в ветке clean_code. В зависимости от того, насколько много будет сделано изменений и насколько они будут большими, ответственный за принятие пулл реквеста попросит создать новый пулл реквест с чистой историей коммитов (по той же процедуре из пункта 2), либо примет ваш пулл реквест с историей из ветки clean_code.

  5. После принятия пулл реквеста:

    • ветку clean_code удалить, как локально, так и удаленно:

      git branch -D clean_code
      git push origin --delete clean_code
      
    • синхронизируйте ваш репозиторий с основным

Порядок работы над задачей (для разработчика)

Исходные данные: у вас должна быть настроена локальная копия для разработки, исходные коды проекта управляются Git, репозиторий лежит на Bitbucket. Для справки по Git-командам для подготовки Pull Request см. Работа с Git при подготовке Pull Request для Bitbucket без истории коммитов

  1. Взять задачу в работу (о чем в ней написать комментарий)
  2. [опционально] Создать в своем форкнутом репозитории ветку отдельно под задачу
  3. Как только достигнуто состояние кода, готовое к объединению с основным репозиторием, нужно создать Pull Request. Этот сценарий хорошо описан в документации Bitbucket: Fork a Repo, Compare Code, and Create a Pull Request. Перед созданием Pull Request необходимо провести подготовительные действия:
    1. Синхронизировать свой форкнутый репозиторий с основным. Если возникли конфликты, разрешить их в своем репозитории. См. Разрешение конфликтов форка с основным репозиторием
    2. Обновить Drupal 8, и если возникла такая необходимость после обновления, переустановить проект.
    3. Проверить работоспособность своего кода на актуальной версии Drupal 8 и основного (форкнутого) репозитория.
  4. Ответственным за принятие кода в основной репозиторий, проводится проверка вашей работы (вашего Pull Request) и оставляются комментарии о том, что нужно исправить. В случае фатальных ошибок, Pull request отклоняется насовсем (Decline). В случае, если по мнению проверяющего, Pull Request готов к вливанию в основной репозиторий, он принимается (Merge).
  5. В случае, если ваш Pull Request остался непринятым, и в нем присутствуют комментарии о том, что нужно исправить, то нужно исправить код и обновить Pull Request.
  6. Пункты 3-5 повторяются, пока ваш Pull Request не будет принят или отклонен.
  7. В случае принятия Pull Request, нужно прокомментировать задачу, в рамках которой он был сделан. В комментарии нужно:
    • оставить ссылку на Pull Request
    • кратко написать, что было сделано
    • написать, что осталось сделать, чтобы закрыть задачу. Если задача сделана полностью в рамках этого Pull Request, то написать, что задачу можно закрыть.
    • закрыть задачу (статус Resolved)

Git под Windows

Установка и настройка Git в Windows

  1. Скачать дистрибутив Git для Windows: https://git-scm.com/download/win

  2. Сгенерировать SSH-ключ: https://help.github.com/articles/generating-ssh-keys/#platform-windows

  3. В Git Bash, запустиь ssh-agent:

     eval `ssh-agent -s`
    
  4. Добавить ключ в ssh-agent:

     ssh-add ~/.ssh/id_rsa
    
  5. Скопировать ключ на все машины, куда с этой виндовой машины планируется заходить:

     ssh-copy-id [email protected]
    
  6. По необходимости, настроить ~/.ssh/config:

     Host example
     Hostname example.com
     User your_login_on_example_com
    
  7. После этого, можно будет логиниться на сервера: ssh example. Также, PhpStorm под виндой сможет выкачивать проекты, соединяясь по sftp по ключу.

Под Windows трудно проставить кооректные права на выполнение файлу. Обходной путь:

git update-index --chmod=+x foo.sh

Файл должен быть в индексе Git, поэтому, если файла там еще нет, добавьте:

git add foo.sh

Полезные ссылки про установку Git в Windows

Установка TorotoiseGIT под Windows XP

Разное

Сервисы наподобие Github, Bitbucket:

Дополнительная информация на русском

⚠️ **GitHub.com Fallback** ⚠️