Перейти к содержимому

Everything up to date git push что это

  • автор:

Git для начинающих. Урок 6.
git push и git pull

Краткое содержание урока, основные инструкции для командной строки, полезные ссылки и советы.

Во втором уроке мы создавали репозитории на github и научились клонировать их. После этого мы работали только с локальным репозиторием, на своей машине. Сегодня мы рассмотрим взаимодействие с удаленным репозиторием.

Что такое push (пуш)

Это отправка данных на сервер, в удаленный репозиторий, на github. Данные — это коммиты и ветки.

Зачем пушить на сервер

  • для работы в команде, чтобы делиться своим кодом с коллегами
  • чтобы иметь резервную копию на случай потери данных на своей машине

Когда пушить на сервер

Когда сделали новый коммит или несколько коммитов

Как узнать, что есть незапушенные коммиты

В командной строке набрать git status

 $ git status On branch master $ git status On branch master Your branch is ahead of 'origin/master' by 5 commits. (use "git push" to publish your local commits) (use "git push" to publish your local commits) 

Ключевая фраза здесь «Your branch is ahead of ‘origin/master’ by 5 commits.». Это значит, что у нас есть 5 неотправленных на сервер коммитов. Если незапушенных коммитов нет, то картина будет такая

 $ git status On branch master Your branch is up-to-date with 'origin/master'. 

«is up-to-date» означает, что у нас нет незапушенных коммитов

В PhpStorm понять, есть ли неотправленные коммиты, можно посмотрев в окно Version Control — Log, где находятся метка master и origin/master. Если master выше, то есть незапушенные коммиты.

master и origin/master

Это ветки: локальная и удаленная (на сервере, в github). По умолчанию мы находимся в ветке master. Подробно работу с ветками мы рассмотрим в следующем уроке, а пока достаточно запомнить, что master — это то, что на нашей машине, а origin/master — в удаленном репозитории, на github.

git push в терминале

 $ git push origin master 
  • push — что сделать, отправить
  • origin — куда, на сервер
  • master — что, ветку master

Как пушить в PhpStorm

Правый клик — Git — Repository — Push. — Кнопка Push

Что такое pull (пулл)

Это скачивание данных с сервера. Похоже на клонирование репозитория, но с той разницей, что скачиваются не все коммиты, а только новые.

Зачем пулиться с сервера

Чтобы получать изменения от ваших коллег. Или от себя самого, если работаете на разных машинах

git pull в терминале

 $ git pull origin master 
  • pull — что сделать, получить данные
  • origin — откуда, с сервера
  • master — а точнее, с ветки master

Как пулить в PhpStorm

Правый клик — Git — Repository — Pull. — Кнопка Pull

Когда что-то пошло не так.

Иногда при работе в команде git push и git pull могут вести себя не так, как пишут в учебниках. Рассмотрим примеры

git push rejected

Вы сделали новый коммит, пытаетесь запушить его, а git в ответ выдает такое

 $ git push origin master To git@github.com:Webdevkin/site-git.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:Webdevkin/site-git.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull . ') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. 

Написано много, но суть в том, что коммит отклонен, пуш не прошел. Почему?

Git устроен так, что локально мы можем коммитить сколько угодно. Но прежде чем отправить свои коммиты на сервер, то есть запушить, нужно подтянуть новые коммиты с сервера. Те самые, которые успели сделать наши коллеги. То есть сделать git pull.

Когда мы делаем git push, git сначала проверяет, а нет ли на сервере новых коммитов. Если они есть, то git выдает то самое сообщение — git push rejected. Значит, нам нужно сначала сделать git pull, а затем снова запушить

 $ git pull origin master remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:Webdevkin/site-git * branch master -> FETCH_HEAD 239892a..383b385 master -> origin/master Merge made by the 'recursive' strategy. README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md 

Здесь нас подстерегает неожиданность — в терминале выскакивает окно редактирования коммита. Пока просто сохраним, что предложено по умолчанию и закроем редактор. Вот теперь можно пушить свои коммиты

 $ git push origin master Counting objects: 19, done. Delta compression using up to 4 threads. Compressing objects: 100% (17/17), done. Writing objects: 100% (19/19), 1.98 KiB | 0 bytes/s, done. Total 19 (delta 4), reused 0 (delta 0) remote: Resolving deltas: 100% (4/4), completed with 1 local object. To git@github.com:Webdevkin/site-git.git 383b385..f32b91e master -> master 

Все, наши коммиты на сервере. При этом появится странный коммит «Merge branch ‘master’ of github.com:Webdevkin/site-git». Это так называемый мердж-коммит, о нем чуть ниже.

Если же при попытке пуша новых коммитов на сервере нет, то git push пройдет сразу и отправит наши коммиты на сервер.

Как избавиться от мердж-коммита

Мердж-коммит появляется, когда вы сделали локальный коммит, а после этого подтянули новые коммиты с сервера. Мердж-коммит не несет смысловой информации, кроме самого факта мерджа. Без него история коммитов выглядит чище.

Чтобы избавиться от него, подтягивайте изменения командой git pull с флажком —rebase

 $ git pull --rebase origin master 

При этом ваш локальный коммит окажется «поверх» нового коммита с сервера, а мердж-коммита не будет. И не забудьте после этого запушить свой коммит на сервер.

Мердж-коммит в PhpStorm

PhpStorm помогает избавиться от мердж-коммитов через меньшее количество действий. Если мы запушим локальные коммиты и получим rejected из-за того, что на сервере есть новые коммиты, то PhpStorm выдаст предупреждение, где предложит выбрать вариант: как подтянуть новые коммиты, с мерждем или ребейзом. Жмите кнопку «Rebase», мердж-коммита не будет и при этом локальный коммит сразу запушится на сервер.

Внимание
Объяснения в тексте не передают точно возникающие проблемы, это нужно видеть в динамике. Поэтому лучше смотрите видеоуроки и еще лучше пробуйте сами повторять их содержание.

Что могу посоветовать

Если мы работаем в одиночку, то удаленный репозиторий нужен только для сохранения резевной копии. Скорее всего, мы будем в него только пушить.

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

  • пушить коммиты почаще, чтобы коллеги быстрее получали доступ к новым изменениям
  • пулиться почаще — обратная ситуация, почаще получать свежие изменения
  • всегда пультесь с флажком ребейза — git pull —rebase origin master
  • не удивляйтесь, что при пуллах и пушах могут возникать подобные ситуации, как мы рассматривали выше
  • не стесняйтесь спрашивать коллег, если увидели незнакомую ситуацию
  • больше практикуйтесь. Посадите домашний проект на git и работайте с ним

Не переживайте, если иногда будете чувствовать себя, как друзья ниже. Это нормально, новый инструмент не осваивается за 5 минут. Немного практики, и мы будем понимать, почему иногда git ведет себя не так, как хочется, и главное, будем понимать, как это исправить.

git push pull whaaat

В следующем уроке мы узнаем, что такое ветки и будем активно работать с ними. Там мы будем активно использовать git push и git pull, и это поможет закрепить уже пройденный материал.

Спасибо за внимание и до встречи!

Все уроки курса

  • Вводный урок
  • 1. Установка и базовая настройка git
  • 2. Создание и клонирование репозитория git
  • 3. Делаем первые изменения, git status и git diff
  • 4. Коммиты и история коммитов, git commit, git log и git show
  • 5. Подробнее об истории коммитов. Путешествие по истории
  • 6. Работа с сервером, git push и git pull
  • 7. Ветки — главная фишка git, git branch и git checkout
  • 8. Работа с ветками на сервере, git fetch
  • 9. Слияния или мерджи веток, git merge
  • 10. Конфликты и их разрешение
  • Платная часть курса. Презентация
  • * 11. Работа с gitignore и git exclude
  • * 12. Буфер обмена git, git stash
  • * 13. Копирование коммитов, git cherry-pick
  • * 14. Отмена и редактирование последнего коммита
  • * 15. Отмена произвольного коммита, git revert
  • 16. Склеивание коммитов, git rebase —interactive и git reflog
  • * 17. Зачем склеивать коммиты. Плюсы и минусы сквоша
  • * 18. Работа с git rebase. Отличия от merge
  • * 19. Что такое git push —force и как с ним работать
  • * 20. Ищем баги с помощью git, git bisect
  • * 21. Как и зачем работать с тегами git
  • * 22. Процессы: github flow и git flow
  • * 23. Псевдонимы в git
  • 24. Мердж-реквесты
  • * 25. Форки

Помогите расколдовать проблему с веткой в git.

Значит такая ситуация. Создал я как то ветку, в своём простом локальном репозитории( от ветки master). Менял код, вёртску. Не помню чего страшного я сделал(git исп-ю не часто), появилась у меня такая вот ситуация:

fri8i@fri8i-VirtualBox:~/projects/portfolio$ git branch -a * (no branch) master remotes/origin/HEAD -> origin/master remotes/origin/master remotes/origin/registration 

Что за беда не понимаю. Мне нужно отправить изменения на bitbucket, а с него на хост. Причём я делал git push/git pull в ответ «Everything up-to-date»/«Already up-to-date» соответственно. Крайне не хочу потерять изменения. Помогите разобраться!

second_buddha
24.12.12 18:06:31 MSK

Ты видимо откатился на определенный коммит. Типа того:

git checkout 9e47ee691e1086c7764fe2d653ee5b15865364d4

Pavval ★★★★★
( 24.12.12 18:10:15 MSK )
Последнее исправление: Pavval 24.12.12 18:10:22 MSK (всего исправлений: 1)

Ответ на: комментарий от Pavval 24.12.12 18:10:15 MSK

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

Минус подхода — ты теряешь историю своих изменений.

Pavval ★★★★★
( 24.12.12 18:14:45 MSK )
Ответ на: комментарий от Pavval 24.12.12 18:14:45 MSK

Если предположить, что ты был в ветке xxxxx, а потом просто сделал git checkout и далее коммитил, то тебе будет достаточно сделать git merge xxx, чтобы вернуть изменения в xxx.

git checkout переводит тебя в detached head, т.е. ты как бы в неназванном бренче, который ты отделил от какого-то коммита. Твое состояние можно идентифицировать по номеру последнего коммита в git log (который в самом начале). Вернуться в это состояние всегда можно через git checkout с тем номером коммита. В такой бренч можно делать коммиты, но ты их потеряешь, если уйдешь с бренча и забудешь номер коммита.

Pavval ★★★★★
( 24.12.12 18:19:55 MSK )

появилась у меня такая вот ситуация:

Это detached state. Это означает то, что твой коммит находится вне бранча.

Причём я делал git push/git pull в ответ «Everything up-to-date»/«Already up-to-date» соответственно

Логично, потому как пушить нечего (HEAD’ы локальный бранчей не отличаются от HEAD’ов ремоутных бранчей).

Крайне не хочу потерять изменения. Помогите разобраться!

Нужно сделать следующее:
— застэшить изменения (ресетнуть коммит через git reset —soft, перевести из их в unstage, сделать git stash);
— перепрыгнуть на коммит, на который указывает HEAD интересующего бранча (git co master);
— git stash pop

Есть и другое решение.
— запомнить хэши коммитов
— перепрыгнуть в нужный бранч
— почерепикать коммиты друг за дружкой (man git-cherry-pick)

dmitry_malikov ★★
( 24.12.12 18:21:57 MSK )
Последнее исправление: dmitry_malikov 24.12.12 18:24:21 MSK (всего исправлений: 2)

Ответ на: комментарий от Pavval 24.12.12 18:19:55 MSK

Ох беда, руки у меня из ж.

second_buddha
( 24.12.12 18:31:30 MSK ) автор топика
Ответ на: комментарий от dmitry_malikov 24.12.12 18:21:57 MSK

Сижу перевариваю. Сначала почитаю про все команды, которые вы упомянули.

second_buddha
( 24.12.12 18:32:20 MSK ) автор топика
Ответ на: комментарий от second_buddha 24.12.12 18:31:30 MSK

Просто внимательно читай сообщения git. Он тебе писал про detached HEAD, пример:

valentine ~/soft/buildsand/sources/kdevplatform/repo $ git checkout 9e47ee691e1086c7764fe2d653ee5b15865364d4 Note: checking out '9e47ee691e1086c7764fe2d653ee5b15865364d4'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 9e47ee6. Merge branch 'master' of git.kde.org:kdevplatform

Pavval ★★★★★
( 24.12.12 18:40:04 MSK )
Ответ на: комментарий от Pavval 24.12.12 18:40:04 MSK

Уровень пока не тот, чтобы схватывать всё сразу, даже если и смотреть внимательно. Ладно, я пока поразбираюсь.

second_buddha
( 24.12.12 18:44:30 MSK ) автор топика
Ответ на: комментарий от dmitry_malikov 24.12.12 18:21:57 MSK
dmitry_malikov ★★
( 24.12.12 18:59:22 MSK )

У тебя сейчас указатель HEAD не указывает ни на какую ветку. Это происходит, когда ты делаешь checkout не самого последнего коммита в ветке. Тебе надо сейчас создать временную ветку (git branch, git тебе должен был подсказать это сделать), потом соединить её с нужной веткой (git merge). Потом временную ветку можно удалить. Так ничего не потеряешь.

yvv ★★☆
( 24.12.12 22:58:35 MSK )
Последнее исправление: yvv 24.12.12 22:59:40 MSK (всего исправлений: 1)

Ответ на: комментарий от Pavval 24.12.12 18:14:45 MSK

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

Ну и зачем так делать, если в git можно по-нормальному?

yvv ★★☆
( 24.12.12 23:03:28 MSK )
Ответ на: комментарий от yvv 24.12.12 23:03:28 MSK

Если не шаришь — возможно стоит именно так. По крайней мере гарантированно не просрешь текущее состояние, набрав не ту команду или еще где тупнув.

Pavval ★★★★★
( 24.12.12 23:06:40 MSK )
Ответ на: комментарий от Pavval 24.12.12 23:06:40 MSK

Не, я в git тоже новичок, но то что HEAD должен всегда ассоциироваться с коммитом (копией твоей рабочей директории в .git), мне подсказал сам git. Первое что ТСу надо делать

git branch

Потом уже смотреть, что и куда надо объединить.

yvv ★★☆
( 24.12.12 23:15:23 MSK )

это то, что нужно было делать перед созданием поста.

s9gf4ult ★★
( 24.12.12 23:36:41 MSK )
Ответ на: комментарий от Pavval 24.12.12 18:19:55 MSK

ты их потеряешь, если уйдешь с бренча и забудешь номер коммита.

anonymous
( 25.12.12 09:12:33 MSK )
Ответ на: комментарий от dmitry_malikov 24.12.12 18:21:57 MSK

Нужно сделать следующее: — застэшить изменения (ресетнуть коммит через git reset —soft, перевести из их в unstage, сделать git stash); — перепрыгнуть на коммит, на который указывает HEAD интересующего бранча (git co master); — git stash pop

git branch -l * (no branch) master git log --pretty=oneline 0bce21b6b1aecc82c828a0ea36327ad4c0c32c09 scaffolding complete e5d3d49ebb40a6cbfe3a4b30e7fd97a8cca82436 pre bootstrap 9eba77517368c2ca7d630a8b27259f15380e70d1 bookmark app ba068dc67f8ada13720eb929e38273fd2cf01f8d vse slomalos iz-za south . . 

1) Откатываю на предпоследний коммит

git reset --soft e5d3 Not currently on any branch. # Changes to be committed: # (use "git reset HEAD . " to unstage) # # modified: mybookmark/views.py # modified: myi18n/views.py # modified: myimages/views.py # modified: mynotes/views.py # deleted: portfolio/static/backgroundpage.png # new file: portfolio/static/bootstrap/css/bootstrap- . . 

2) Перевёл несколько файлов в unstaged(подскажите как сразу все файлы снять с индекса. )

git reset HEAD mybookmark/views.py # и так еще несколько файлов 

3) Стало лень вводить все файлы так(около 20 штук), спрятал все изменения как есть.

git stash 

4) Переключился на ветку master и принял на ней спрятанные изменения

git checkout master git stash apply 

Нарвался на конфликты! Как быть с ними.

Auto-merging portfolio/urls.py Auto-merging portfolio/templates/mynotes/show_notes.html Auto-merging portfolio/templates/mynotes/note.html CONFLICT (modify/delete): portfolio/templates/mybookmark/edit_bookmark.html deleted in Updated upstream and modified in Stashed changes. Version Stashed changes of portfolio/templates/mybookmark/edit_bookmark.html left in tree. CONFLICT (modify/delete): portfolio/templates/mybookmark/create_bookmark.html deleted in Updated upstream and modified in Stashed changes. Version Stashed changes of portfolio/templates/mybookmark/create_bookmark.html left in tree. CONFLICT (modify/delete): portfolio/templates/mybookmark/bookmarks_list.html deleted in Updated upstream and modified in Stashed changes. Version Stashed changes of portfolio/templates/mybookmark/bookmarks_list.html left in tree. Auto-merging portfolio/templates/base.html CONFLICT (content): Merge conflict in portfolio/templates/base.html Removing portfolio/static/backgroundpage.png Auto-merging myimages/views.py CONFLICT (modify/delete): mybookmark/views.py deleted in Updated upstream and modified in Stashed changes. Version Stashed changes of mybookmark/views.py left in tree. (envDjango141_2)fri8i@fri8i-VirtualBox:~/projects/portfolio$ git status # On branch master # Changes to be committed: # (use "git reset HEAD . " to unstage) # # modified: myi18n/views.py # modified: myimages/views.py # modified: mynotes/views.py # deleted: portfolio/static/backgroundpage.png # new file: portfolio/static/bootstrap/css/bootstrap-responsive.css # new file: portfolio/static/bootstrap/css/bootstrap-responsive.min.css # new file: portfolio/static/bootstrap/css/bootstrap.css # new file: portfolio/static/bootstrap/css/bootstrap.min.css # new file: portfolio/static/bootstrap/img/glyphicons-halflings-white.png # new file: portfolio/static/bootstrap/img/glyphicons-halflings.png # new file: portfolio/static/bootstrap/js/bootstrap.js # new file: portfolio/static/bootstrap/js/bootstrap.min.js # modified: portfolio/templates/base_with_change_lang.html # modified: portfolio/templates/myimages/albums.html # modified: portfolio/templates/myimages/images.html # modified: portfolio/templates/mynotes/create_note.html # modified: portfolio/templates/mynotes/note.html # renamed: portfolio/templates/mynotes/notes.html -> portfolio/templates/mynotes/show_notes.html # modified: portfolio/templates/myprofile/profile.html # modified: portfolio/templates/registration/activate.html # modified: portfolio/templates/registration/login.html # modified: portfolio/templates/registration/registration_form.html # modified: portfolio/urls.py # # Unmerged paths: # (use "git reset HEAD . " to unstage) # (use "git add/rm . " as appropriate to mark resolution) # # deleted by us: mybookmark/views.py # both modified: portfolio/templates/base.html # deleted by us: portfolio/templates/mybookmark/bookmarks_list.html # deleted by us: portfolio/templates/mybookmark/create_bookmark.html # deleted by us: portfolio/templates/mybookmark/edit_bookmark.html 

2.2 Основы Git — Запись изменений в репозиторий

Итак, у вас имеется настоящий Git-репозиторий и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать «снимки» состояния (snapshots) этих изменений в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить.

Запомните, каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (неотслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем снимке состояния проекта; они могут быть неизменёнными, изменёнными или подготовленными к коммиту. Если кратко, то отслеживаемые файлы — это те файлы, о которых знает Git.

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

Как только вы отредактируете файлы, Git будет рассматривать их как изменённые, так как вы изменили их с момента последнего коммита. Вы индексируете эти изменения, затем фиксируете все проиндексированные изменения, а затем цикл повторяется.

Жизненный цикл состояний файлов

Рисунок 8. Жизненный цикл состояний файлов

Определение состояния файлов

Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда git status . Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:

$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working tree clean

Это означает, что у вас чистый рабочий каталог, другими словами — в нём нет отслеживаемых изменённых файлов. Git также не обнаружил неотслеживаемых файлов, в противном случае они бы были перечислены здесь. Наконец, команда сообщает вам на какой ветке вы находитесь и сообщает вам, что она не расходится с веткой на сервере. Пока что это всегда ветка master , ветка по умолчанию; в этой главе это не важно. В главе Ветвление в Git будут рассмотрены ветки и ссылки более детально.

Примечание

В 2020 году GitHub изменил имя ветки по умолчанию с master на main , другие же git-хостинг платформы последовали этому примеру. Поэтому, вы можете обнаружить, что ветка по умолчанию для новых репозиториев — main , а не master . Более того, имя ветки по умолчанию можно изменить (как вы видели в Настройка ветки по умолчанию), поэтому вам может встретиться и другое имя. При этом Git продолжает использовать имя master , поэтому далее в книге мы используем именно его.

Предположим, вы добавили в свой проект новый файл, простой файл README . Если этого файла раньше не было, и вы выполните git status , вы увидите свой неотслеживаемый файл вот так:

$ echo 'My Project' > README $ git status On branch master Your branch is up-to-date with 'origin/master'. Untracked files: (use "git add . " to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)

Понять, что новый файл README неотслеживаемый можно по тому, что он находится в секции «Untracked files» в выводе команды status . Статус Untracked означает, что Git видит файл, которого не было в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить README, так давайте сделаем это.

Отслеживание новых файлов

Для того чтобы начать отслеживать (добавить под версионный контроль) новый файл, используется команда git add . Чтобы начать отслеживание файла README , вы можете выполнить следующее:

$ git add README

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

$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git restore --staged . " to unstage) new file: README

Вы можете видеть, что файл проиндексирован, так как он находится в секции «Changes to be committed». Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add , будет добавлена в историю снимков состояния. Как вы помните, когда вы ранее выполнили git init , затем вы выполнили git add (файлы) — это было сделано для того, чтобы добавить файлы в вашем каталоге под версионный контроль. Команда git add принимает параметром путь к файлу или каталогу, если это каталог, команда рекурсивно добавляет все файлы из указанного каталога в индекс.

Индексация изменённых файлов

Давайте модифицируем файл, уже находящийся под версионным контролем. Если вы измените отслеживаемый файл CONTRIBUTING.md и после этого снова выполните команду git status , то результат будет примерно следующим:

$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) new file: README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md

Файл CONTRIBUTING.md находится в секции «Changes not staged for commit» — это означает, что отслеживаемый файл был изменён в рабочем каталоге, но пока не проиндексирован. Чтобы проиндексировать его, необходимо выполнить команду git add . Это многофункциональная команда, она используется для добавления под версионный контроль новых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния. Вам может быть понятнее, если вы будете думать об этом как «добавить этот контент в следующий коммит», а не как «добавить этот файл в проект». Выполним git add , чтобы проиндексировать CONTRIBUTING.md , а затем снова выполним git status :

$ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) new file: README modified: CONTRIBUTING.md

Теперь оба файла проиндексированы и войдут в следующий коммит. В этот момент вы, предположим, вспомнили одно небольшое изменение, которое вы хотите сделать в CONTRIBUTING.md до коммита. Вы открываете файл, вносите и сохраняете необходимые изменения и вроде бы готовы к коммиту. Но давайте-ка ещё раз выполним git status :

$ vim CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) new file: README modified: CONTRIBUTING.md Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md

Что за чёрт? Теперь CONTRIBUTING.md отображается как проиндексированный и непроиндексированный одновременно. Как такое возможно? Такая ситуация наглядно демонстрирует, что Git индексирует файл в точности в том состоянии, в котором он находился, когда вы выполнили команду git add . Если вы выполните коммит сейчас, то файл CONTRIBUTING.md попадёт в коммит в том состоянии, в котором он находился, когда вы последний раз выполняли команду git add , а не в том, в котором он находится в вашем рабочем каталоге в момент выполнения git commit . Если вы изменили файл после выполнения git add , вам придётся снова выполнить git add , чтобы проиндексировать последнюю версию файла:

$ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) new file: README modified: CONTRIBUTING.md

Сокращённый вывод статуса

Вывод команды git status довольно всеобъемлющий и многословный. Git также имеет флаг вывода сокращённого статуса, так что вы можете увидеть изменения в более компактном виде. Если вы выполните git status -s или git status —short вы получите гораздо более упрощённый вывод:

$ git status -s M README MM Rakefile A lib/git.rb M lib/simplegit.rb ?? LICENSE.txt

Новые неотслеживаемые файлы помечены ?? слева от них, файлы добавленные в отслеживаемые помечены A , отредактированные файлы помечены M и так далее. В выводе содержится два столбца — в левом указывается статус файла, а в правом модифицирован ли он после этого. К примеру в нашем выводе, файл README модифицирован в рабочем каталоге, но не проиндексирован, а файл lib/simplegit.rb модифицирован и проиндексирован. Файл Rakefile модифицирован, проиндексирован и ещё раз модифицирован, таким образом на данный момент у него есть те изменения, которые попадут в коммит, и те, которые не попадут.

Игнорирование файлов

Зачастую, у вас имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых. К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т. п.). В таком случае, вы можете создать файл .gitignore . с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore :

$ cat .gitignore *.[oa] *~

Первая строка предписывает Git игнорировать любые файлы заканчивающиеся на «.o» или «.a» — объектные и архивные файлы, которые могут появиться во время сборки кода. Вторая строка предписывает игнорировать все файлы заканчивающиеся на тильду ( ~ ), которая используется во многих текстовых редакторах, например Emacs, для обозначения временных файлов. Вы можете также включить каталоги log, tmp или pid; автоматически создаваемую документацию; и т. д. и т. п. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.

К шаблонам в файле .gitignore применяются следующие правила:

  • Пустые строки, а также строки, начинающиеся с # , игнорируются.
  • Стандартные шаблоны являются глобальными и применяются рекурсивно для всего дерева каталогов.
  • Чтобы избежать рекурсии используйте символ слеш (/) в начале шаблона.
  • Чтобы исключить каталог добавьте слеш (/) в конец шаблона.
  • Можно инвертировать шаблон, использовав восклицательный знак (!) в качестве первого символа.

Glob-шаблоны представляют собой упрощённые регулярные выражения, используемые командными интерпретаторами. Символ ( * ) соответствует 0 или более символам; последовательность [abc] — любому символу из указанных в скобках (в данном примере a, b или c); знак вопроса ( ? ) соответствует одному символу; и квадратные скобки, в которые заключены символы, разделённые дефисом ( [0-9] ), соответствуют любому символу из интервала (в данном случае от 0 до 9). Вы также можете использовать две звёздочки, чтобы указать на вложенные каталоги: a/**/z соответствует a/z , a/b/z , a/b/c/z , и так далее.

Вот ещё один пример файла .gitignore :

# Исключить все файлы с расширением .a *.a # Но отслеживать файл lib.a даже если он подпадает под исключение выше !lib.a # Исключить файл TODO в корневом каталоге, но не файл в subdir/TODO /TODO # Игнорировать все файлы в каталоге build/ build/ # Игнорировать файл doc/notes.txt, но не файл doc/server/arch.txt doc/*.txt # Игнорировать все .txt файлы в каталоге doc/ doc/**/*.txt

GitHub поддерживает довольно полный список примеров .gitignore файлов для множества проектов и языков https://github.com/github/gitignore это может стать отправной точкой для .gitignore в вашем проекте.

Примечание

В простейшем случае репозиторий будет иметь один файл .gitignore в корневом каталоге, правила из которого будут рекурсивно применяться ко всем подкаталогам. Так же возможно использовать .gitignore файлы в подкаталогах. Правила из этих файлов будут применяться только к каталогам, в которых они находятся. Например, репозиторий исходного кода ядра Linux содержит 206 файлов .gitignore .

Детальное рассмотрение использования нескольких .gitignore файлов выходит за пределы этой книги; детали доступны в справке man gitignore .

Просмотр индексированных и неиндексированных изменений

Если результат работы команды git status недостаточно информативен для вас — вам хочется знать, что конкретно поменялось, а не только какие файлы были изменены — вы можете использовать команду git diff . Позже мы рассмотрим команду git diff подробнее; вы, скорее всего, будете использовать эту команду для получения ответов на два вопроса: что вы изменили, но ещё не проиндексировали, и что вы проиндексировали и собираетесь включить в коммит. Если git status отвечает на эти вопросы в самом общем виде, перечисляя имена файлов, git diff показывает вам непосредственно добавленные и удалённые строки — патч как он есть.

Допустим, вы снова изменили и проиндексировали файл README , а затем изменили файл CONTRIBUTING.md без индексирования. Если вы выполните команду git status , вы опять увидите что-то вроде:

$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) modified: README Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md

Чтобы увидеть, что же вы изменили, но пока не проиндексировали, наберите git diff без аргументов:

$ git diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ebb991..643e24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,8 @@ branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change -merged in. +merged in. Also, split your changes into comprehensive chunks if you patch is +longer than a dozen lines. If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's

Эта команда сравнивает содержимое вашего рабочего каталога с содержимым индекса. Результат показывает ещё не проиндексированные изменения.

Если вы хотите посмотреть, что вы проиндексировали и что войдёт в следующий коммит, вы можете выполнить git diff —staged . Эта команда сравнивает ваши проиндексированные изменения с последним коммитом:

$ git diff --staged diff --git a/README b/README new file mode 100644 index 0000000..03902a1 --- /dev/null +++ b/README @@ -0,0 +1 @@ +My Project

Важно отметить, что git diff сама по себе не показывает все изменения сделанные с последнего коммита — только те, что ещё не проиндексированы. Такое поведение может сбивать с толку, так как если вы проиндексируете все свои изменения, то git diff ничего не вернёт.

Другой пример: вы проиндексировали файл CONTRIBUTING.md и затем изменили его, вы можете использовать git diff для просмотра как проиндексированных изменений в этом файле, так и тех, что пока не проиндексированы. Если наше окружение выглядит вот так:

$ git add CONTRIBUTING.md $ echo '# test line' >> CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) modified: CONTRIBUTING.md Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md

Используйте git diff для просмотра непроиндексированных изменений

$ git diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 643e24f..87f08c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,3 +119,4 @@ at the ## Starter Projects See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md). +# test line

а так же git diff —cached для просмотра проиндексированных изменений ( —staged и —cached синонимы):

$ git diff --cached diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ebb991..643e24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,8 @@ branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change -merged in. +merged in. Also, split your changes into comprehensive chunks if you patch is +longer than a dozen lines. If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's

Примечание
Git Diff во внешних инструментах

Мы будем продолжать использовать команду git diff различными способами на протяжении всей книги. Существует ещё один способ просматривать эти изменения, если вы предпочитаете графический просмотр или внешнюю программу просмотра различий, вместо консоли. Выполнив команду git difftool вместо git diff , вы сможете просмотреть изменения в файле с помощью таких программ как emerge, vimdiff и других (включая коммерческие продукты). Выполните git difftool —tool-help чтобы увидеть какие из них уже установлены в вашей системе.

Коммит изменений

Теперь, когда ваш индекс находится в таком состоянии, как вам и хотелось, вы можете зафиксировать свои изменения. Запомните, всё, что до сих пор не проиндексировано — любые файлы, созданные или изменённые вами, и для которых вы не выполнили git add после редактирования — не войдут в этот коммит. Они останутся изменёнными файлами на вашем диске. В нашем случае, когда вы в последний раз выполняли git status , вы видели что всё проиндексировано, и вот, вы готовы к коммиту. Простейший способ зафиксировать изменения — это набрать git commit :

$ git commit

Эта команда откроет выбранный вами текстовый редактор.

Примечание

Редактор устанавливается переменной окружения EDITOR — обычно это vim или emacs, хотя вы можете установить любой другой с помощью команды git config —global core.editor , как было показано в главе Введение).

В редакторе будет отображён следующий текст (это пример окна Vim):

# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Your branch is up-to-date with 'origin/master'. # # Changes to be committed: # new file: README # modified: CONTRIBUTING.md # ~ ~ ~ ".git/COMMIT_EDITMSG" 9L, 283C

Вы можете видеть, что комментарий по умолчанию для коммита содержит закомментированный результат работы команды git status и ещё одну пустую строку сверху. Вы можете удалить эти комментарии и набрать своё сообщение или же оставить их для напоминания о том, что вы фиксируете.

Примечание

Для ещё более подробного напоминания, что же именно вы поменяли, можете передать аргумент -v в команду git commit . Это приведёт к тому, что в комментарий будет также помещена дельта/diff изменений, таким образом вы сможете точно увидеть все изменения которые вы совершили.

Когда вы выходите из редактора, Git создаёт для вас коммит с этим сообщением, удаляя комментарии и вывод команды diff .

Есть и другой способ — вы можете набрать свой комментарий к коммиту в командной строке вместе с командой commit указав его после параметра -m , как в следующем примере:

$ git commit -m "Story 182: fix benchmarks for speed" [master 463dc4f] Story 182: fix benchmarks for speed 2 files changed, 2 insertions(+) create mode 100644 README

Итак, вы создали свой первый коммит! Вы можете видеть, что коммит вывел вам немного информации о себе: на какую ветку вы выполнили коммит ( master ), какая контрольная сумма SHA-1 у этого коммита ( 463dc4f ), сколько файлов было изменено, а также статистику по добавленным/удалённым строкам в этом коммите.

Запомните, что коммит сохраняет снимок состояния вашего индекса. Всё, что вы не проиндексировали, так и висит в рабочем каталоге как изменённое; вы можете сделать ещё один коммит, чтобы добавить эти изменения в репозиторий. Каждый раз, когда вы делаете коммит, вы сохраняете снимок состояния вашего проекта, который позже вы можете восстановить или с которым можно сравнить текущее состояние.

Игнорирование индексации

Несмотря на то, что индекс может быть удивительно полезным для создания коммитов именно такими, как вам и хотелось, он временами несколько сложнее, чем вам нужно в процессе работы. Если у вас есть желание пропустить этап индексирования, Git предоставляет простой способ. Добавление параметра -a в команду git commit заставляет Git автоматически индексировать каждый уже отслеживаемый на момент коммита файл, позволяя вам обойтись без git add :

$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) modified: CONTRIBUTING.md no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m 'Add new benchmarks' [master 83e38c7] Add new benchmarks 1 file changed, 5 insertions(+), 0 deletions(-)

Обратите внимание, что в данном случае перед коммитом вам не нужно выполнять git add для файла CONTRIBUTING.md , потому что флаг -a включает все файлы. Это удобно, но будьте осторожны: флаг -a может включить в коммит нежелательные изменения.

Удаление файлов

Для того чтобы удалить файл из Git, вам необходимо удалить его из отслеживаемых файлов (точнее, удалить его из вашего индекса) а затем выполнить коммит. Это позволяет сделать команда git rm , которая также удаляет файл из вашего рабочего каталога, так что в следующий раз вы не увидите его как «неотслеживаемый».

Если вы просто удалите файл из своего рабочего каталога, он будет показан в секции «Changes not staged for commit» (изменённые, но не проиндексированные) вывода команды git status :

$ rm PROJECTS.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add/rm . " to update what will be committed) (use "git checkout -- . " to discard changes in working directory) deleted: PROJECTS.md no changes added to commit (use "git add" and/or "git commit -a")

Затем, если вы выполните команду git rm , удаление файла попадёт в индекс:

$ git rm PROJECTS.md rm 'PROJECTS.md' $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) deleted: PROJECTS.md

После следующего коммита файл исчезнет и больше не будет отслеживаться. Если вы изменили файл и уже проиндексировали его, вы должны использовать принудительное удаление с помощью параметра -f . Это сделано для повышения безопасности, чтобы предотвратить ошибочное удаление данных, которые ещё не были записаны в снимок состояния и которые нельзя восстановить из Git.

Другая полезная штука, которую вы можете захотеть сделать — это удалить файл из индекса, оставив его при этом в рабочем каталоге. Другими словами, вы можете захотеть оставить файл на жёстком диске, но перестать отслеживать изменения в нём. Это особенно полезно, если вы забыли добавить что-то в файл .gitignore и по ошибке проиндексировали, например, большой файл с логами, или кучу промежуточных файлов компиляции. Чтобы сделать это, используйте опцию —cached :

$ git rm --cached README

В команду git rm можно передавать файлы, каталоги или шаблоны. Это означает, что вы можете сделать что-то вроде:

$ git rm log/\*.log

Обратите внимание на обратный слеш ( \ ) перед * . Он необходим из-за того, что Git использует свой собственный обработчик имён файлов вдобавок к обработчику вашего командного интерпретатора. Эта команда удаляет все файлы, имеющие расширение .log и находящиеся в каталоге log/ . Или же вы можете сделать вот так:

$ git rm \*~

Эта команда удаляет все файлы, имена которых заканчиваются на ~ .

Перемещение файлов

В отличие от многих других систем контроля версий, Git не отслеживает перемещение файлов явно. Когда вы переименовываете файл в Git, в нём не сохраняется никаких метаданных, говорящих о том, что файл был переименован. Однако, Git довольно умён в плане обнаружения перемещений постфактум — мы рассмотрим обнаружение перемещения файлов чуть позже.

Таким образом, наличие в Git команды mv выглядит несколько странным. Если вам хочется переименовать файл в Git, вы можете сделать что-то вроде:

$ git mv file_from file_to

и это отлично сработает. На самом деле, если вы выполните что-то вроде этого и посмотрите на статус, вы увидите, что Git считает, что произошло переименование файла:

$ git mv README.md README $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD . " to unstage) renamed: README.md -> README

Однако, это эквивалентно выполнению следующих команд:

$ mv README.md README $ git rm README.md $ git add README

Git неявно определяет, что произошло переименование, поэтому неважно, переименуете вы файл так или используя команду mv . Единственное отличие состоит лишь в том, что mv — одна команда вместо трёх — это функция для удобства. Важнее другое — вы можете использовать любой удобный способ для переименования файла, а затем воспользоваться командами add или rm перед коммитом.

Ошибка git everything up-to-date или что не так?

Всем здравствуйте! Склонировал проект, на репозитории создал новую директорию проекта, в git на локальной машине соответственно переадресовал на новый репозиторий, внес изменения в шаблон и конфигурационные файлы проекта, при выполнении команды git push origin master выдает сообщение everything up-to-date .
P.S. Только начал изучение git, поэтому может что-то не так описываю или делаю
Поэтапно команды в git выполнял следующим образом:

git status git add . git commit -m "Комментарий" git push origin master

Путь к новому репозиторию проверил командой git remote -v , к пути вопросов нет.

  • Вопрос задан более года назад
  • 916 просмотров

Комментировать
Решения вопроса 1

sergey-kuznetsov

Сергей Кузнецов @sergey-kuznetsov Куратор тега Git
Автоматизатор

переадресовал на новый репозиторий

Не понимаю этой фразы. Какая команда такое выполняет?

выполнении команды git push origin master

Если локальный репозиторий склонирован из внешнего, то автоматически создаются связи между ветками.
Не нужно указывать в какой репозиторий (origin) и в какую ветку (master) отправлять текущую ветку.
Достаточно просто git push

выдает сообщение everything up-to-date

Это не ошибка. Сообщение говорит что как раз всё хорошо и текущая локальная ветка синхронизирована с той внешней веткой, в которую вы отправили коммиты.

Но вы точно уверены что текущая ветка называется master, а не main? Давайте узнаем.
Покажите вывод команд
git branch -vv
и
git status

Внизу кнопка комментиррвать, пишите уточнения туда, а не новым ответом на свой вопрос.

Ответ написан более года назад
Комментировать
Нравится Комментировать
Ответы на вопрос 1

Ballly

Михаил @Ballly Автор вопроса
Сергей Кузнецов, при выполнении команды git branch -vv выводит следующую информацию

* (no branch, rebasing master) 363fbce Изменения master 16b4053 Добавление директории в репозиторий

При выполнении git status

interactive rebase in progress; onto 90cda99 Last command done (1 command done): pick 592e37c Уроки ИМ ita-studio Next commands to do (2 remaining commands): pick 728f28f Без изменений pick 16b4053 Добавление директории в репозиторий (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch 'master' on '90cda99'. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) nothing to commit, working tree clean

«переадресовал на новый репозиторий»
Не понимаю этой фразы. Какая команда такое выполняет?

В файле .git/config отредактировал параметр url в секции [remote «origin»] указав новый адрес
Вывод команды git remote -v показывает новый адрес

origin https://myname@bitbucket.org/myname/yiishop.git (fetch) origin https://myname@bitbucket.org/myname/yiishop.git (push)

Ответ написан более года назад

sergey-kuznetsov

Сергей Кузнецов @sergey-kuznetsov Куратор тега Git

Это не ответ на ваш вопрос)) попутали кнопку.

interactive rebase in progress

Эта фраза говорит что вы начали интерактивный ребейз и не закончили.
Либо доведите до конца, либо отмените его командой git rebase —abort
Иначе в этом подвешенном состоянии больше ничего делать нельзя.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *