Git - andyceo/documentation GitHub Wiki
Данная страница посвящена системе управлением версиями Git
Начиная с Ubuntu 12.04, вы можете установить Git так:
sudo aptitude install git
Подробная статья на Github про установку Git: Set Up Git
Имейте в виду, что все настройки Git сохраняет для того пользователя, из-под которого вы запускаете эти команды, т.е. из-под текущего. Допустим, если пользователь - andyceo, то вся глобальная (для данного пользователя) конфигурация будет сохраняться в файл /home/andyceo/.gitconfig
Глобальная конфигурация (которая применяется по умолчанию для всех новых пользователей на данном хосте) хранится в /etc/gitconfig.
Посмотреть, откуда читается конфигурация Git для данного репозитория: git config --list --show-origin
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 -"
-
Извлечь репозиторий полностью в папку (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 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>
- Команда
git archiveигнорирует подмодули - в рабочей копии после
git checkoutнадо выполнятьgit submodule update –init
Добавим новый удаленный сервер и отправим туда все ветки, коммиты и теги:
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
Можно сделать временный коммит в специальный тайник, чтобы некоторые изменения не мешали проводить работу.
По умолчанию, в тайник добавляются и обычные, и staged изменения. Флаг --keep-index оставляет staged изменения.
-
git stash list: выводит список коммитов в тайнике, их может быть много -
git stash: добавить все изменения в тайник в виде нового коммита в тайнике -
git stash push --staged: добавляет толькоstaged(те, которые в индексе) изменения в тайник. Работает какgit commit, только коммитит в тайник, а не в текущую ветку -
git stash push --keep-index: добавить все изменения в тайник, но при этом оставитstagedизменения нетронутыми в рабочей папке. Полезно для последующегоrebase -
git stash pop: применить к текущей ветке последний из созданных временных коммитов и удалить его из тайника -
git stash pop stash@{n}: применить к текущей ветке коммит с именемstash@{n}и удалить его из тайника -
git stash apply: то же самое что иgit stash pop, но коммит не удаляется из тайника -
git stash save "My stash message": добавить описание к временному коммиту, что делает его более понятным -
git stash apply stash@{n}: гдеstash@{n}- нужный коммит изgit stash list -
git stash drop [stash@{n}]: удалить указанный коммит из тайника. Если коммит не указан, будет удален последний созданный коммит.
Способ с помощью git checkout:
# First, ensure you are on the target branch where you want the folder
git checkout target_branch
# Then, retrieve the specific folder from the source branch
git checkout source_branch -- path/to/your/folder
# Stage and commit the changes
git add path/to/your/folder
git commit -m "Merged specific folder from source_branch"
Способ с помощью git cherry-pick:
# First, ensure you are on the target branch
git checkout target_branch
# Find the commit hash(es) that contain the changes to the folder on the source branch
git log source_branch -- path/to/your/folder
# Cherry-pick the desired commit(s)
git cherry-pick <commit-hash-1>
git cherry-pick <commit-hash-2> # If multiple commits are involved
-
git checkout --theirs .: принять все новые изменения, отбросить старые. НЕДОПИСАНО!
-
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
Как дополнить не последний, а произвольный коммит: https://graphite.dev/guides/how-to-amend-commits-with-the-git-amend-command
# определить, на сколько коммитов идти назад при перестройке. 1 - это текущий коммит, и git commit --amend меняет именно его
git log --oneline
# идем назад на 2 коммита, выбрать в редакторе, какой коммит будем редактировать
git stash push
git rebase -i HEAD~2
# сделать работу и добавить изменения
git add .
git commit --amend
git rebase --continue
# удостовериться, что git вышел из режима перестройки (rebase) и вернуть изменения из тайника
git log --oneline
git stash pop
-
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 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.pmgit 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 blame file.txt: кто и когда редактировал файл
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.
Файл .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, через веб-интерфейс.
-
Создаем связь с upstream-репозиторием:
git remote add upstream [email protected]:USER_LOGIN/UPSTREAM_REPO_NAME.git -
Скачиваем данные из upstream-репозитория:
git fetch upstream -
Создаем локальную ветку
upstream, которая будет связана с веткойmasterupstream-репозитория и сразу переключимся на нее: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
Предположим, вы всю работу делали в своей ветке master, а для подготовки пулл реквеста намерены создать ветку clean_code.
Также, мы исходим из предположения, что вы настроили себе локальную ветку upstream, которая синхронизирована с master-веткой upstream-репозитория (репозитория, который вы форкнули) (см. Создание upstream-ветки).
-
Перед подготовкой пулл-реквеста, синхронизируйте ваш репозиторий с основным, разрешите все конфликты (если есть).
-
Выполните следующее:
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 -
В веб-интерфейсе Bitbucket (или Github) делаете пулл реквест из вашей ветки
clean_codeв основной репозиторий, веткуmaster -
Дальнейшую работу над замечаниями к данному пулл реквесту, производите в ветке
clean_code. В зависимости от того, насколько много будет сделано изменений и насколько они будут большими, ответственный за принятие пулл реквеста попросит создать новый пулл реквест с чистой историей коммитов (по той же процедуре из пункта 2), либо примет ваш пулл реквест с историей из веткиclean_code. -
После принятия пулл реквеста:
-
ветку
clean_codeудалить, как локально, так и удаленно:git branch -D clean_code git push origin --delete clean_code -
синхронизируйте ваш репозиторий с основным
-
Исходные данные: у вас должна быть настроена локальная копия для разработки, исходные коды проекта управляются Git, репозиторий лежит на Bitbucket. Для справки по Git-командам для подготовки Pull Request см. Работа с Git при подготовке Pull Request для Bitbucket без истории коммитов
- Взять задачу в работу (о чем в ней написать комментарий)
- [опционально] Создать в своем форкнутом репозитории ветку отдельно под задачу
- Как только достигнуто состояние кода, готовое к объединению с основным репозиторием, нужно создать Pull Request. Этот сценарий хорошо описан в документации Bitbucket: Fork a Repo, Compare Code, and Create a Pull Request. Перед созданием Pull Request необходимо провести подготовительные действия:
- Синхронизировать свой форкнутый репозиторий с основным. Если возникли конфликты, разрешить их в своем репозитории. См. Разрешение конфликтов форка с основным репозиторием
- Обновить Drupal 8, и если возникла такая необходимость после обновления, переустановить проект.
- Проверить работоспособность своего кода на актуальной версии Drupal 8 и основного (форкнутого) репозитория.
- Ответственным за принятие кода в основной репозиторий, проводится проверка вашей работы (вашего Pull Request) и оставляются комментарии о том, что нужно исправить. В случае фатальных ошибок, Pull request отклоняется насовсем (Decline). В случае, если по мнению проверяющего, Pull Request готов к вливанию в основной репозиторий, он принимается (Merge).
- В случае, если ваш Pull Request остался непринятым, и в нем присутствуют комментарии о том, что нужно исправить, то нужно исправить код и обновить Pull Request.
- Пункты 3-5 повторяются, пока ваш Pull Request не будет принят или отклонен.
- В случае принятия Pull Request, нужно прокомментировать задачу, в рамках которой он был сделан. В комментарии нужно:
- оставить ссылку на Pull Request
- кратко написать, что было сделано
- написать, что осталось сделать, чтобы закрыть задачу. Если задача сделана полностью в рамках этого Pull Request, то написать, что задачу можно закрыть.
- закрыть задачу (статус Resolved)
-
Скачать дистрибутив Git для Windows: https://git-scm.com/download/win
-
Сгенерировать SSH-ключ: https://help.github.com/articles/generating-ssh-keys/#platform-windows
-
В Git Bash, запустиь
ssh-agent:eval `ssh-agent -s` -
Добавить ключ в
ssh-agent:ssh-add ~/.ssh/id_rsa -
Скопировать ключ на все машины, куда с этой виндовой машины планируется заходить:
ssh-copy-id [email protected] -
По необходимости, настроить
~/.ssh/config:Host example Hostname example.com User your_login_on_example_com -
После этого, можно будет логиниться на сервера:
ssh example. Также, PhpStorm под виндой сможет выкачивать проекты, соединяясь по sftp по ключу.
Под Windows трудно проставить кооректные права на выполнение файлу. Обходной путь:
git update-index --chmod=+x foo.sh
Файл должен быть в индексе Git, поэтому, если файла там еще нет, добавьте:
git add foo.sh
- Установка git в Windows (на этот раз подробно)
- Делаем, чтобы git при pull/push не спрашивал пароли на ssh-ключ, искать "Auto-launching ssh-agent on msysgit"
- Доп. инфо: http://stackoverflow.com/questions/370030/git-cant-remember-my-passphrase
- Сначала скачиваем и распаковываем в какую-нибудь папку проект http://code.google.com/p/msysgit/downloads/list PORTABLE последнюю версию.
- Затем ставим http://code.google.com/p/tortoisegit/downloads/list последнюю версию.
- Затем перезагружаем комп
- Лезем в настройки TorotoiseGIT и настраиваем путь до проекта msysgit
Сервисы наподобие Github, Bitbucket:
- Git Wizardry - !!!
- Использование Git для разработки в Etersoft - !!
- Редактирование истории в git - !
- Git для начинающих: окончательное практическое руководство - машинный перевод с англ.?
- Линус Торвальдс о GIT на Google Talks
- Учебник введение в git (для версии 1.5.1 или более поздняя версия)
- 20 повседневных команд git
- Удачная модель ветвления для Git
- Интересная графическая штука вроде TortoiseSVN для Gnome
- Set Up Git