Изучаем Python — страница 60 из 61

Закрепление


Выполним первое закрепление:

(1) git_practice$ git commit -m "Started project."

(2)[master (root-commit) c03d2a3] Started project.

(3) 2 files changed, 1 insertion(+)

create mode 100644 .gitignore

create mode 100644 hello_world.py

(4)git_practice$ git status

# On branch master

nothing to commit, working directory clean

git_practice$

Команда git commit -m "сообщение" (1) создает «моментальный снимок» состояния проекта. Флаг -m приказывает Git сохранить следующее сообщение ("Started project.") в журнале проекта. Из вывода следует, что текущей является ветвь master (2), а в проекте изменились два файла (3).

Проверка статуса показывает, что текущей является ветвь master, а рабочий каталог чист (4). Это сообщение должно выводиться каждый раз, когда вы закрепляете рабочее состояние своего проекта. Если вы получите другое сообщение, внимательно прочитайте его; скорее всего, вы забыли добавить файл после закрепления.

Просмотр журнала


Git ведет журнал всех закреплений, выполненных в проекте. Проверим содержимое журнала:

git_practice$ git log

commit a9d74d87f1aa3b8f5b2688cb586eac1a908cfc7f

Author: Eric Matthes

Date: Mon Mar 16 07:23:32 2015 -0800


. .Started project.

git_practice$

Каждый раз, когда вы выполняете закрепление, Git генерирует ­уникальный идентификатор из 40 символов. Сохраняется информация о том, кто выполнил изменение, когда оно было выполнено, а также передаваемое сообщение. Не вся эта информация вам понадобится, поэтому Git предоставляет возможность вывести упрощенный вариант записи журнала:

git_practice$ git log --pretty=oneline

a9d74d87f1aa3b8f5b2688cb586eac1a908cfc7f Started project.

git_practice$

Флаг --pretty=oneline выводит два важнейших атрибута: идентификатор закреп­ления и сохраненное для этого закрепления сообщение.

Второе закрепление


Чтобы увидеть всю мощь системы контроля версий, следует внести в проект ­изменение и закрепить его. Добавим еще одну строку в hello_world.py:

hello_world.py

print("Hello Git world!")

print("Hello everyone.")

Проверяя статус проекта, мы видим, что изменение в файле было замечено Git:

git_practice$ git status

(1) # On branch master

# Changes not staged for commit:

# (use "git add ..." to update what will be committed)

# (use "git checkout -- ..." to discard changes in working directory)

#

(2)# modified: hello_world.py

#

(3)no changes added to commit (use "git add" and/or "git commit -a")

git_practice$

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

(1)

git_practice$ git commit -am "Extended greeting."

[master 08d4d5e] Extended greeting.

1 file changed, 1 insertion(+)

(2)git_practice$ git status

# On branch master

nothing to commit, working directory clean

(3)git_practice$ git log --pretty=oneline

08d4d5e39cb906f6cff197bd48e9ab32203d7ed6 Extended greeting.

be017b7f06d390261dbc64ff593be6803fd2e3a1 Started project.

git_practice$

Команда git commit с флагом -am выполняет новое закрепление. Флаг -a приказывает Git добавить все измененные файлы в репозитории в текущее закрепление. (Если вы создали новые файлы между закреплениями, просто снова выполните команду git add., чтобы включить новые файлы в репозиторий.) Флаг -m приказывает Git сохранить сообщение в журнале.

При проверке статуса проекта рабочий каталог снова оказывается чистым (2). Наконец, в журнале хранится информация о двух закреплениях (3).

Отмена изменений


А теперь посмотрим, как отменить изменение и вернуться к предыдущему работоспособному состоянию. Сначала добавьте в файл hello_world.py новую строку:

hello_world.py

print("Hello Git world!")

print("Hello everyone.")


print("Oh no, I broke the project!")

Сохраните и запустите этот файл.

Из информации статуса видно, что Git видит изменения:

git_practice$ git status

# On branch master

# Changes not staged for commit:

# (use "git add ..." to update what will be committed)

# (use "git checkout -- ..." to discard changes in working directory)

#

(1) # modified: hello_world.py

#

no changes added to commit (use "git add" and/or "git commit -a")

git_practice$

Git понимает, что файл hello_world.py был изменен (1) , и при желании мы можем закрепить изменения. Но на этот раз вместо закрепления мы хотим вернуться к последней операции закрепления, в которой проект был заведомо работоспособным. С hello_world.py ничего делать не нужно: ни удалять строку, ни использовать функцию отмены в текстовом редакторе. Вместо этого введите следующие команды в терминальном сеансе:

git_practice$ git checkout .

git_practice$ git status

# On branch master

nothing to commit, working directory clean

git_practice$

Команда git checkout позволяет работать с любым предшествующим закрепле­нием. Команда git checkout . отменяет все изменения, внесенные с момента последнего закрепления, и восстанавливает проект в последнем закрепленном состоянии.

Вернувшись в текстовый редактор, вы увидите, что файл hello_world.py вернулся к следующему состоянию:

print("Hello Git world!")

print("Hello everyone.")

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

примечание

Щелкните в окне редактора, чтобы обновить файл и увидеть предыдущую версию.

Извлечение предыдущих закреплений


Git позволяет извлечь из журнала любое закрепление, не только последнее. Для этого в команде вместо точки указываются первые 6 символов идентифи­катора. Выполняя извлечение, вы можете просмотреть более раннее закрепление и либо вернуться к своему последнему закреплению, либо отказаться от всей ­последней работы и продолжить разработку с более раннего закрепления:

git_practice$ git log --pretty=oneline

08d4d5e39cb906f6cff197bd48e9ab32203d7ed6 Extended greeting.

be017b7f06d390261dbc64ff593be6803fd2e3a1 Started project.

git_practice$ git checkout be017b

Note: checking out 'be017b'.

(1) 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 be017b7... Started project.

git_practice$

При извлечении предыдущего закрепления вы покидаете ветвь master и входите в состояние, которое Git называет отсоединенным состоянием HEAD (1) . HEAD — текущее состояние проекта; «отсоединенным» оно называется потому, что мы покинули именованную ветвь (master в данном случае).

Чтобы вернуться к ветви master, извлеките ее:

git_practice$ git checkout master

Previous HEAD position was be017b7... Started project.

Switched to branch 'master'

git_practice$

Вы снова возвращаетесь к ветви master. Не вносите изменения в проект при извлечении старого закрепления, если не хотите использовать использовать расширенные возможности Git. Но вы можете вернуться к предыдущему состоянию, если над проектом больше никто не работает. Работая в ­ветви master, введите следующую команду:

(1) git_practice$ git status

# On branch master

nothing to commit, working directory clean

(2)git_practice$ git log --pretty=oneline

08d4d5e39cb906f6cff197bd48e9ab32203d7ed6 Extended greeting.

be017b7f06d390261dbc64ff593be6803fd2e3a1 Started project.

(3)git_practice$ git reset --hard be017b

HEAD is now at be017b7 Started project.

(4)git_practice$ git status

# On branch master

nothing to commit, working directory clean

(5)git_practice$ git log --pretty=oneline

be017b7f06d390261dbc64ff593be6803fd2e3a1 Started project.

git_practice$

Сначала мы проверяем статус и убеждаемся в том, что текущей является ветвь master (1) . В журнале присутствуют оба закрепления (2). Затем выдается команда git reset --hard с первыми шестью символами идентификатора того закрепления, к которому нужно вернуться (3). Далее повторная проверка статуса показывает, что мы находимся в главной ветви, а закреплять нечего (4). Повторное обращение к журналу показывает, что проект находится в том состоянии, к которому мы решили вернуться (5).

Удаление репозитория


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