Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, готовые к коммиту. Сразу после клонирования репозитория все файлы — отслеживаемые неизменённые.
После редактирования отслеживаемого файла он становится изменённым. Изменения файла (или нескольких) можно индексировать (подготовить к коммиту) и закоммитить. После коммита такие файлы становятся отслеживаемыми неизменёнными.
Проверить состояние репозитория можно командой git status. Она покажет ветку, изменённые файлы (если есть) с пометкой «modified», неотслеживаемые файлы в списке «Untracked files».
Указание неотслеживаемых файлов
Файлы и папки, которые не нужно включать в репозиторий, указываются в файле .gitignore. Обычно это устанавливаемые зависимости в папку node_modules, компоненты в папке bower_components, готовая сборка в папке build или dist и подобные, создаваемые при установке или запуске. Каждый файл или папка указываются с новой строки, возможно использование шаблонов.
- создать создать новый проект в текущей папке: git init
git init
- создать новый проект в указанной папке:
git init folder-name
- создать новый проект в текущей папке
git clone [email protected]:example/my-repository.git
- создать новый проект в текущей папке:
git clone [email protected]:example/my-repository.git foldername
- создать новый проект в текущей папке
git clone [email protected]:example/my-repository.git .
- добавить к отслеживанию этот существующий файл
git add text.txt
- добавить к отслеживанию все новые файлы из текущей папки и её подпапок, индексировать отслеживаемые файлы
git add .
- запуск оболочки интерактивного индексирования для добавления в индекс только выбранных файлов
git add -i
- поочередный просмотр файлов с показом изменений и задаваемым вопросом об отслеживании/индексировании (удобно для добавления в коммит только каких-то конкретных файлов)
git add -p
- удалить файл из отслеживаемых (файл останется на месте)
git rm --cached readme.txt
- удалить папку из отслеживаемых (папка останется на месте)
git rm --cached -r folder
- убрать из индекса все индексированные файлы
git reset HEAD
- убрать из индекса указанный файл
git reset HEAD text.txt
- посмотреть непроиндексированные изменения (если есть, иначе ничего не выведет)
git diff
- посмотреть проиндексированные изменения (если есть, иначе ничего не выведет)
git diff --staged
- ОПАСНО ! отменить все изменения, внесенные в отслеживаемый файл со времени предыдущего коммита (файл не добавлен в индекс)
git checkout -- text.txt
- ОПАСНО ! отменить изменения во всех непроиндексированных отслеживаемых файлах
git checkout -- .
- ОПАСНО ! отменить изменения в непроиндексированном файле
git checkout text.txt
- закоммитить отслеживаемые индексированные файлы (указано название коммита)
git commit -m "Name of commit"
- закоммитить отслеживаемые индексированные файлы (указано название коммита, не требует git add, не добавит в коммит неотслеживаемые файлы)
git commit -m -a "Name of commit"
- закоммитить отслеживаемые индексированные файлы (откроется редактор для введения названия коммита)
git commit
- изменить последний коммит (Insert — режим ввода, : — командный режим; в командном режиме: :wq — сохранить и выйти)
git commit --amend
- переименовать последний коммит (только если ещё не был отправлен в удалённый репозиторий)
git commit --amend -m "Новое название"
- создать новый коммит, отменяющий изменения последнего коммита без запуска редактора сообщения
git revert HEAD --no-edit
- создать новый коммит, отменяющий изменения указанного (b9533bb) коммита без запуска редактора сообщения
git revert b9533bb --no-edit
- вернуть репозиторий в состояние коммита с указанным хешем ОПАСНО! пропадет вся работа, сделанная после этого коммита
git reset --hard 75e2d51
- временно переключиться на коммит с указанным хешем
git checkout b9533bb
- вернуться к последнему коммиту в указанной ветке (master)
git checkout master
- Потребуется создание новой ветки, начинающейся с указанного коммита. Создать ветку new-branch, начинающуюся с коммита 5589877
git checkout -b new-branch 5589877
Просто удалить отслеживаемый файл из папки недостаточно, нужно сделать его неотслеживаемым и отправить коммит
- удалить из отслеживаемых неиндексированный файл (файл будет удален из папки)
git rm text.txt
- удалить из отслеживаемых индексированный файл (файл будет удален из папки)
git rm -f text.txt
- удалить из отслеживаемых всё содержимое папки log/ (папка будет удалена)
git rm -r log/
- удалить из отслеживаемых все файлы с именем, начинающимся на «ind» в текущей папке (файлы будут удалены из папки)
git rm ind*
- удалить из отслеживаемых индексированный файл (файл останется на месте)
git rm --cached readme.txt
Перемещение/переименование файлов (git не отслеживает перемещения/переименование, но пытается его угадать)
- переименовать файл «text.txt» в «test_new.txt»
git mv text.txt test_new.txt
- переместить файл readme_new.md в папку folder/ (должна существовать)
git mv readme_new.md folder/
- показать историю изменений файла index.html (выход из длинного лога: Q)
git log -p index.html
- показать историю изменений файла index.html (последние 5 коммитов, выход из длинного лога: Q)
git log -p -5 index.html
- показать последние 2 коммита
git log -2
- показать последние 2 коммита и статистику внесенных ими изменений
git log -2 --stat
- показать последние 22 коммита и внесенную ими разницу на уровне строк (выход из длинного лога: Q)
git log -p -22
- показать последние 4 коммита с форматированием выводимых данных
git log --pretty=format:"%h - %an, %ar : %s" -4
- показать последние 10 коммитов с ASCII-представлением ветвления
git log --graph -10
- показать коммиты за последние 2 недели
git log --since=2.weeks
- мой формат вывода, висящий на алиасе оболочки
git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
- показать коммиты из ветки branch_99, которые не влиты в master
git log master..branch_99
- показать коммиты из ветки master, которые не влиты в branch_99
git log branch_99..master
- показать изменения из коммита с указанным хешем
git show 60d6582
- показать данные о предыдущем коммите
git show HEAD^
- показать список веток
git branch
- показать список веток и последний коммит в каждой
git branch -v
- создать новую ветку с указанным именем
git branch new_branch
- перейти в указанную ветку
git checkout new_branch
- создать новую ветку с указанным именем и перейти в неё
git checkout -b new_branch
- влить в ветку, в которой находимся, данные из ветки hotfix
git merge hotfix
- удалить ветку hotfix (если её изменения уже влиты в главную ветку)
git branch -d hotfix
- показать ветки, уже слитые с активной (их можно удалять)
git branch --merged
- показать ветки, не слитые с активной
git branch --no-merged
- показать все имеющиеся ветки (в т.ч. на удаленных репозиториях)
git branch -a
- переименовать локально ветку old_branch_name в new_branch_name
git branch -m old_branch_name new_branch_name
- переименовать локально ТЕКУЩУЮ ветку в new_branch_name
git branch -m new_branch_name
- применить переименование в удаленном репозитории
git push origin :old_branch_name new_branch_name
- завершить процесс переименования
git branch --unset-upstream
- показать список удалённых репозиториев, связанных с этим
git remote -v
- убрать привязку удалённого репозитория с сокр. именем origin
git remote remove origin
- добавить удалённый репозиторий (с сокр. именем origin) с указанным URL
git remote add origin [email protected]:example/my-repository
- удалить привязку удалённого репозитория
git remote rm origin
- получить данные об удалённом репозитории с сокращенным именем origin
git remote show origin
- скачать все ветки с удаленного репозитория (с сокр. именем origin), но не сливать со своими ветками
git fetch origin
- то же, но скачивается только указанная ветка
git fetch origin master
- посмотреть ветку, скачанную с удалённого репозитория (локальной редактируемой копии не создаётся! если нужно редактировать, придётся влить)
git checkout origin/github_branch
- создать локальную ветку github_branch (данные взять из удалённого репозитория с сокр. именем origin, ветка github_branch) и переключиться на неё
git checkout --track origin/github_branch
- отправить в удалённый репозиторий (с сокр. именем origin) данные своей ветки master
git push origin master
- влить изменения с удалённого репозитория (все ветки)
git pull origin
- влить изменения с удалённого репозитория (только указанная ветка)
git pull origin master
- удалить из репозитория все неотслеживаемые папки и файлы (папки и файлы, добавленные в .gitignore останутся на месте)
git clean -f -d
- удалить все файлы и папки с именем .env из истории коммитов текущей ветки (HEAD)
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch .env" HEAD
Создание нового репозитория, первый коммит, привязка удалённого репозитория с gthub.com, отправка изменений в удалённый репозиторий.
- git init
- touch readme.md
- git add readme.md
- git commit -m "Первый коммит"
- git remote add origin [email protected]:example/my-repository
- git push origin master
- git clone АДРЕС_РЕПОЗИТОРИЯ ПАПКА_ПРОЕКТА
- cd ПАПКА_ПРОЕКТА
- редактируем файлы, добавляем файлы и/или папки (если удаляем файлы — см. секцию про удаление файлов)
- git add .
- git commit -m "НАЗВАНИЕ_КОММИТА"
- git push origin master
- снова вносим какие-то изменения (если удаляем файлы — см. секцию про удаление файлов)
- возвращаемся к шагу с git add . и проходим цикл заново
- nano index.html
- git add index.html
- git commit -m "Fix index.html"
- nano index.html
- git add index.html
- git commit --amend -m "Fix error 2"
-
редактируем и сохраняем разметку «шапки» nano inc/header.html
-
индексируем измененный файл
git add inc/header.html
- делаем коммит
git commit -m "Убрал телефон из шапки"
ВНИМАНИЕ: коммит пока не был отправлен в удалённый репозиторий сознаём, что нужно было еще что-то сделать в этом коммите вносим изменения
- индексируем измененный файл (можно git add .)
git add inc/header.html
- заново делаем коммит
git commit --amend -m "«Шапка»: выполнена задача №34 (вставить-вынуть)"
Есть master (публичная версия сайта), хотим масштабно что-то поменять (переверстать «шапку»), но по ходу работ возникает необходимость подправить критичный баг (неправильно указан контакт в «подвале»).
- создадим новую ветку для задачи изменения «шапки» и перейдём в неё
git checkout -b new_page_header
- редактируем и сохраняем разметку «шапки»
nano inc/header.html
- делаем первый коммит (работа еще не завершена)
git commit -a -m "Новая шапка: смена логотипа"
тут выясняется, что есть баг с контактом в «подвале»
- возвращаемся к ветке master
git checkout master
- создаём ветку (основанную на master) для решения проблемы
git checkout -b footer_hotfix
-
устраняем баг и сохраняем разметку «подвала» nano inc/footer.html
-
делаем коммит
git commit -a -m "Исправление контакта в подвале"
- переключаемся в ветку master
git checkout master
- вливаем в master изменения из ветки footer_hotfix
git merge footer_hotfix
- удаляем ветку footer_hotfix
git branch -d footer_hotfix
- переключаемся в ветку new_page_header для продолжения работ над «шапкой»
git checkout new_page_header
- редактируем и сохраняем разметку «шапки»
nano inc/header.html
- делаем коммит (работа над «шапкой» завершена)
git commit -a -m "Новая шапка: смена навигации"
- переключаемся в ветку master
git checkout master
- вливаем в master изменения из ветки new_page_header
git merge new_page_header
- удаляем ветку new_page_header
git branch -d new_page_header
Работа с ветками, конфликт слияния
Есть master (публичная версия сайта), в двух параллельных ветках (branch_1 и branch_2) было отредактировано одно и то же место одного и того же файла, первую ветку (branch_1) влили в master, попытка влить вторую вызывает конфликт.
- удаляем ветку new_page_header
git checkout master
- создаём ветку branch_1, основанную на ветке master
git checkout -b branch_1
-
редактируем и сохраняем файлы nano ...
-
коммитим (теперь имеем 1 коммит в ветке branch_1)
git commit -a -m "Правка 1"
- возвращаемся к ветке master
git checkout master
- создаём ветку branch_2, основанную на ветке master
git checkout -b branch_2
-
редактируем и сохраняем файлы nano ...
-
коммитим (теперь имеем 1 коммит в ветке branch_2)
git commit -a -m "Правка 2"
- возвращаемся к ветке master
git checkout master
- вливаем изменения из ветки branch_1 в текущую ветку (master), удача (автослияние)
git merge branch_1
- вливаем изменения из ветки branch_2 в текущую ветку (master), КОНФЛИКТ автослияния
git merge branch_2
Automatic merge failed; fix conflicts and then commit the result.
-
выбираем в конфликтных файлах те участки, которые нужно оставить, сохраняем nano ...
-
коммитим результат устранения конфликта
git commit -a -m "Устранение конфликта"
Есть некий репозиторий на github.com, он него нами был сделан форк, добавлены какие-то изменения. Оригинальный (мастер-) репозиторий был как-то обновлён. Задача: стянуть с мастер-репозитория изменения (которые там внесены уже после того, как мы его форкнули).
- добавляем удаленный репозиторий: сокр. имя — upstream, URL мастер-репозитория
git remote add upstream [email protected]:address.git
- качаем все ветки мастер-репозитория, но пока не сливаем со своими
git fetch upstream
- переключаемся на ветку master своего репозитория
git checkout master
- вливаем ветку master удалённого репозитория upstream в свою ветку master
git merge upstream/master
Ошибка в работе: закоммитили в мастер, но поняли, что нужно было коммитить в новую ветку (ВАЖНО: это сработает только если коммит еще не отправлен в удалённый репозиторий)
сделали изменения, проиндексировали их, закоммитили в master, но ЕЩЁ НЕ ОТПРАВИЛИ (не делали git push)
- создаём новую вертку из master
git checkout -b new-branch
- переключаемся на master
git checkout master
- жестоко сбрасываем состояние master
git reset HEAD~ --hard
- переключаемся обратно на новую ветку
git checkout new-branch
Нужно вернуть содержимое файла к состоянию, бывшему в каком-либо коммите (известна SHA коммита)
- указана SHA коммита, к состоянию которого нужно вернуть файл и имя файла
git checkout f26ed88 -- index.html
- изменения внесены в файл, файл сразу проиндексирован
git status
- показать изменения в файле
git diff --staged
- коммит
git commit -am "Navigation fixs"
- показать список удалённых репозиториев с адресами (у проблемного будет адрес по https), предположим, это origin
git remote -v
- добавляем удаленный репозиторий, сокр. имя — origin
git remote add origin [email protected]:address.git
если возникает ошибка добавления с сообщением о том, что origin «уже задан», то:
- удаляем привязанный удалённый репозиторий
git remote rm origin
- добавляем удаленный репозиторий, сокр. имя — origin
git remote add origin [email protected]:address.git