ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.12.2023
Просмотров: 370
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Создание репозитория Git на вашем компьютере
247
Игнорирование файлов в репозитории
Файлы, не отслеживаемые Git, отображаются как неотслеживаемые при выпол- нении команды git status
. Однако в процессе написания кода некоторые файлы можно исключить из системы контроля версий, чтобы предотвратить их случайное отслеживание. К этой категории относятся:
временные файлы в папке проекта;
файлы
.pyc
,
.pyo и
.pyd
, генерируемые интерпретатором Python при выпол- нении программ
.py
;
папки
.tox
, htmlcov и другие папки, генерируемые различными средствами разработчика;
другие откомпилированные или сгенерированные файлы, которые можно сгенерировать заново (потому что репозиторий предназначен для исход- ных файлов, а не для производных файлов, которые генерируются на их основе);
файлы с исходным кодом, содержащие пароли баз данных, маркеры аутентификации, номера кредитных карт или другие конфиденциальные данные.
Чтобы предотвратить включение этих файлов, создайте текстовый файл с именем
.gitignore и перечислите в нем файлы и папки, которые не должны отслеживаться
Git. Git автоматически исключает их из команд git add или git commit
, и они не будут отображаться при выполнении команды git status
Файл
.gitignore
, созданный шаблоном cookiecutter-basicpythonproject
, выглядит примерно так:
ates looks like this:
# Байт-компилируемые / оптимизированные / файлы DLL
__pycache__/
*.py[cod]
*$py.class
--snip--
В файле
.gitignore символ
*
используется для шаблонов, а
#
— для комментариев.
За дополнительной информацией обращайтесь к электронной документации по адресу https://git-scm.com/docs/gitignore.
Файл
.gitignore также следует добавить в репозиторий Git, чтобы он был у других программистов, клонировавших ваш репозиторий. Если вы хотите видеть, какие файлы в вашем рабочем каталоге игнорируются на основании настроек в
.gitignore
, выполните команду git ls-files --other --ignored --exclude-standard
248
Глава 12.Git и организация программных проектов
Сохранение изменений
После добавления новых файлов в репозиторий вы можете продолжить писать код для вашего проекта. Когда потребуется создать очередной коммит, выполните команду git add для индексирования всех измененных файлов и команду git commit
-m
<сообщение> для сохранения всех индексированных файлов. Впрочем, это проще делается одной командой git commit
-am
<сообщение>:
C:\Users\Al\wizcoin>git commit -am "Fixed the currency conversion bug."
[master (root-commit) e1ae3a3] Fixed the currency conversion bug.
1 file changed, 12 insertions(+)
Если вы хотите сохранить только некоторые (но не все) измененные файлы, не добавляйте ключ
-a в
-am и перечислите файлы после сообщения — например, git commit
-m
<сообщение> file1.py file2.py
Сообщение
Fixed the currency conversion bug (Исправлена ошибка конвертации валюты) содержит подсказку на будущее: оно напоминает, какие изменения были внесены в этом коммите. Не поддавайтесь искушению написать короткое обобщен- ное сообщение вида «Обновленный код», «Исправлены некоторые ошибки» или просто «x» (потому что пустые сообщения запрещены). Через три недели, когда вам захочется вернуться к более ранней версии вашего кода, подробные сообще- ния в каждом коммите сэкономят вам немало времени, когда вы будете выбирать, к какой именно версии следует вернуться.
Если вы забудете добавить аргумент командной строки
-m
"
<сообщение>
"
, Git от- кроет текстовый редактор Vim в окне терминала. Описание Vim выходит за рамки книги, поэтому нажмите клавишу
Esc и введите qa!
, чтобы безопасно завершить
Vim и отменить коммит. Затем снова введите команду git commit
, на этот раз с ар- гументом командной строки
-m
"
<сообщение>
"
Чтобы посмотреть примеры профессиональных сообщений коммитов, обращайтесь к истории коммитов веб-фреймворка Django (https://github.com/django/jango/
commits/master. Так как Django является большим проектом с открытым кодом, коммиты выполняются часто, а сообщения коммитов формализованы.
Редкие коммиты с невразумительными сообщениями могут неплохо работать в небольших персональных проектах, но над Django работает более 1000 участ- ников. Некачественные сообщения коммитов от любого участника создадут проблемы для всех.
Файлы были безопасно сохранены в репозитории Git. Еще раз выполните команду git status
, чтобы просмотреть их статус:
Создание репозитория Git на вашем компьютере
249
C:\Users\Al\wizcoin>git status
On branch master nothing to commit, working tree clean
Сохранив индексированные файлы, вы вернули их в сохраненное состояние, и Git говорит, что рабочее дерево чисто; другими словами, в нем нет измененных или индексированных файлов.
Напомню, что при добавлении файлов в репозиторий Git файлы перешли из неот- слеживаемого состояния в индексированное, а затем в сохраненное. Теперь файлы готовы к будущим изменениям.
Заметим, что в репозитории Git нельзя сохранять папки. Git автоматически вклю- чает папки в репозитории при сохранении хранящихся в них файлов, но сохранить пустую папку не получится.
Если вы допустили ошибку в последнем сообщении коммита, его можно переписать командой git commit
--amend
-m
"
<новое_сообщение>
"
Просмотр изменений перед коммитом
Прежде чем сохранять код, следует быстро просмотреть изменения, которые будут сохранены при выполнении команды git commit
. Для просмотра различий между рабочей копией кода и последним сохраненным кодом можно воспользоваться командой git diff command
Рассмотрим пример использования git diff
. Откройте файл
README.md в текстовом редакторе или IDE. (Вы должны были создать этот файл при запуске Cookiecutter.
Если он не существует, создайте пустой текстовый файл и сохраните его под именем
README.md
.) Это файл с разметкой Markdown, но, как сценарий Python, он должен быть записан в формате простого текста. Замените текст
TODO
- fill this in later в приведенном ниже тексте из раздела «Quickstart Guide» следующим фрагментом
(пока не исправляйте ошибку xample
; мы сделаем это позднее):
Quickstart Guide
----------------
Here's some xample code demonstrating how this module is used:
>>> import wizcoin
>>> coin = wizcoin.WizCoin(2, 5, 10)
>>> str(coin)
'2g, 5s, 10k'
>>> coin.value()
1141
250
Глава 12.Git и организация программных проектов
Прежде чем добавить и сохранить файл
README.md
, выполните команду git diff для просмотра внесенных изменений:
C:\Users\Al\wizcoin>git diff
diff --git a/README.md b/README.md index 76b5814..3be49c3 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,14 @@ To install with pip, run:
Quickstart Guide
----------------
-TODO - fill this in later
+Here's some xample code demonstrating how this module is used:
+
+ >>> import wizcoin
+ >>> coin = wizcoin.WizCoin(2, 5, 10)
+ >>> str(coin)
+ '2g, 5s, 10k'
+ >>> coin.value()
+ 1141
Contribute
----------
Результат показывает, что файл
README.md в рабочей копии изменился по сравне- нию с файлом
README.md
, существовавшим при последнем сохранении репозито- рия. Строки, начинающиеся со знака
-
, были удалены; строки, начинающиеся со знака
+
, были добавлены.
В процессе просмотра изменений также можно заметить опечатку — «xample» вместо «example». Исправим ее, а потом снова выполним команду git diff
, чтобы проверить изменения и сохранить их в репозитории:
C:\Users\Al\wizcoin>git diff
diff --git a/README.md b/README.md index 76b5814..3be49c3 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,14 @@ To install with pip, run:
Quickstart Guide
----------------
-TODO - fill this in later
+Here's some example code demonstrating how this module is used:
--snip--
C:\Users\Al\wizcoin>git add README.md
C:\Users\Al\wizcoin>git commit -m "Added example code to README.md"
[master 2a4c5b8] Added example code to README.md
1 file changed, 8 insertions(+), 1 deletion(-)
Исправление сохранено в репозитории.
Создание репозитория Git на вашем компьютере
251
Просмотр изменений в графическом приложении командой git difftool
Изменения проще просматривать в программе с графическим интерфейсом. Для
Windows можно загрузить WinMerge (https://winmerge.org/) — бесплатную програм- му с открытым кодом. В Linux можно установить либо Meld командой sudo apt-get install meld
, либо Kompare командой sudo apt-get install kompare
. В macOS для установки программы tkdiff начните с команд, которые устанавливают и настраива- ют Homebrew (менеджер пакетов для установки программ), а затем воспользуйтесь
Homebrew для установки tkdiff:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/
master/install.sh)"
brew install tkdiff
Чтобы настроить Git для использования этих программ, выполните команду git config diff.tool
<название>, где <название> — winmerge
, tkdiff
, meld или kompare
Затем выполните команду git difftool
<
имя_файла
>
для просмотра изменений, внесенных в файл, в графическом интерфейсе программы (рис. 12.5).
Рис. 12.5. Просматривать результаты в программе с графическим интерфейсом
(WinMerge в данном случае) удобнее, чем в текстовом выводе git diff
252
Глава 12.Git и организация программных проектов
Кроме того, выполните команду git config
--global difftool.prompt false
, чтобы система Git не запрашивала подтверждения каждый раз, когда вы хотите запустить программу просмотра изменений. Если вы установили Git-клиент с графическим интерфейсом, вы также можете настроить его для использования этих инструментов
(а может быть, он содержит собственные визуальные средства сравнения).
Частота сохранения изменений
Хотя системы контроля версий позволяют вернуть файлы к более раннему комми- ту, может возникнуть вопрос, насколько часто следует сохранять изменения. Если делать это слишком часто, вам придется пробиваться через множество незначи- тельных комментариев, чтобы найти нужную версию кода. Если делать редко, то каждый коммит будет содержать множество изменений и возврат к конкретной версии отменит больше изменений, чем вам хотелось бы. На практике программи- сты обычно выполняют коммиты реже, чем следовало бы.
Код следует сохранять при завершении блока функциональности, класса или ис- правления ошибки. Не сохраняйте код, содержащий синтаксические ошибки или очевидно неработоспособный. Коммиты могут состоять из нескольких строк или нескольких сотен строк измененного кода, но в любом случае вы должны иметь возможность вернуться к более ранней копии и все еще иметь в распоряжении рабочую программу. Всегда выполняйте все модульные тесты перед сохранением.
В идеале все тесты должны проходить (а если они не проходят, упомяните об этом в сопроводительном сообщении).
Удаление файлов из репозитория
Если вам не нужно, чтобы какой-либо файл отслеживался в Git, вы не можете про- сто удалить его из файловой системы. Это необходимо сделать через Git командой git rm
, которая также приказывает Git перестать отслеживать файл. Чтобы потре- нироваться в выполнении этой операции, выполните команду echo
"Test file"
>
deleteme.txt
, чтобы создать маленький файл с именем deleteme.txt и содержимым "Test file"
. Затем сохраните файл в репозитории следующими командами:
C:\Users\Al\wizcoin>
1 ... 22 23 24 25 26 27 28 29 ... 40
echo "Test file" > deleteme.txt
C:\Users\Al\wizcoin>git add deleteme.txt
C:\Users\Al\wizcoin>git commit -m "Adding a file to test Git deletion."
[master 441556a] Adding a file to test Git deletion.
1 file changed, 1 insertion(+)
create mode 100644 deleteme.txt
C:\Users\Al\wizcoin>git status
On branch master nothing to commit, working tree clean
Создание репозитория Git на вашем компьютере
253
Не удаляйте файлы командой del в Windows или командой rm в macOS и Linux.
(А если вы это сделаете, файл можно восстановить командой git restore
<имя_фай-
ла> или просто перейти к команде git rm
, чтобы удалить файл из репозитория.)
Вместо этого воспользуйтесь командой git rm
, чтобы удалить и проиндексировать файл deleteme.txt
, как это делается в следующем примере:
C:\Users\Al\wizcoin>git rm deleteme.txt
rm deleteme.txt'
Команда git rm удаляет файл из рабочей копии, но это еще не все. Как и git add
, команда git rm индексирует файл. Удаление файла необходимо закрепить точно так же, как любые другие изменения:
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
❶
deleted: deleteme.txt
C:\Users\Al\wizcoin>git commit -m "Deleting deleteme.txt from the repo to
finish the deletion test."
[master 369de78] Deleting deleteme.txt from the repo to finish the deletion test.
1 file changed, 1 deletion(-)
delete mode 100644 deleteme.txt
C:\Users\Al\Desktop\wizcoin>git status
On branch master nothing to commit, working tree clean
Хотя файл deleteme.txt был удален из рабочей копии, он все еще существует в исто- рии репозитория. В разделе «Восстановление старых изменений» этой главы рас- сказано, как восстановить удаленный файл или отменить изменение.
Команда git rm работает только с файлами, находящимися в чистом, сохраненном, состоянии без каких-либо изменений. В противном случае Git предложит сохранить изменения или отменить их командой git reset
HEAD
<имя_файла>. (Вывод git status напомнит вам об этой команде
❶
.) Такая процедура предотвращает случайное удаление несохраненных изменений.
Переименование и перемещение файлов из репозитория
Как и при удалении файлов, вы не должны переименовывать или перемещать файлы в репозитории в обход Git. В противном случае Git решит, что вы просто удалили файл, и создаст новый файл с прежним содержимым. Вместо этого используйте команду git mv с последующей командой git commit
254
Глава 12.Git и организация программных проектов
Переименуйте
README.md в
README.txt следующими командами:
C:\Users\Al\wizcoin>git mv README.md README.txt
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: README.md -> README.txt
C:\Users\Al\wizcoin>git commit -m "Testing the renaming of files in Git."
[master 3fee6a6] Testing the renaming of files in Git.
1 file changed, 0 insertions(+), 0 deletions(-)
rename README.md => README.txt (100%)
В этом случае история изменений
README.txt также включает историю
README.md
Также можно воспользоваться командой git mv для перемещения файла в новую папку. Введите следующие команды, чтобы создать новую папку с именем movetest и переместить в нее файл
README.txt
:
C:\Users\Al\wizcoin>mkdir movetest
C:\Users\Al\wizcoin>git mv README.txt movetest/README.txt
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: README.txt -> movetest/README.txt
C:\Users\Al\wizcoin>git commit -m "Testing the moving of files in Git."
[master 3ed22ed] Testing the moving of files in Git.
1 file changed, 0 insertions(+), 0 deletions(-)
rename README.txt => movetest/README.txt (100%)
Также можно совместить переименование файла с перемещением — для этого сле- дует передать git mv новое имя и местоположение файла. Вернем файл
README.txt в корневой рабочий каталог с восстановлением исходного имени:
C:\Users\Al\wizcoin>git mv movetest/README.txt README.md
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: movetest/README.txt -> README.md
C:\Users\Al\wizcoin>git commit -m "Moving the README file back to its original
place and name."
[master 962a8ba] Moving the README file back to its original place and name.
Просмотр журнала коммитов
255 1 file changed, 0 insertions(+), 0 deletions(-)
rename movetest/README.txt => README.md (100%)
Хотя файл
README.md вернулся в исходную папку и имеет исходное имя, репози- торий Git запоминает изменения имени и местоположения. Историю изменений можно вызвать командой git log
, о которой пойдет речь в следующем разделе.
Просмотр журнала коммитов
Команда git log выводит список всех коммитов:
C:\Users\Al\wizcoin>git log
commit 962a8baa29e452c74d40075d92b00897b02668fb (HEAD -> master)
Author: Al Sweigart
Date: Wed Sep 1 10:38:23 2021 -0700
Moving the README file back to its original place and name.
commit 3ed22ed7ae26220bbd4c4f6bc52f4700dbb7c1f1
Author: Al Sweigart
Date: Wed Sep 1 10:36:29 2021 -0700
Testing the moving of files in Git.
--snip--
Команда способна выводить большой объем текста. Если журнал не помещается в окне терминала, текст можно прокрутить клавишами
↑ и ↓. Чтобы завершить просмотр, нажмите клавишу q.
Если вы хотите вернуть файлы к более раннему коммиту, сначала следует найти
хеш коммита — строку из 40 шестнадцатеричных цифр (0–9 и буквы A–F), которая служит уникальным идентификатором коммита. Например, последний коммит в нашем репозитории представлен хешем
962a8baa29e452c74d40075d92b00897b026 68fb
. На практике обычно используются только первые семь знаков:
962a8ba
Со временем журнал может стать очень длинным. Ключ
--oneline усекает вывод до сокращенных хешей и первой строки каждого сообщения коммита. Введите команду git log
--oneline в командной строке:
C:\Users\Al\wizcoin>git log --oneline
962a8ba (HEAD -> master) Moving the README file back to its original place and name.
3ed22ed Testing the moving of files in Git.
15734e5 Deleting deleteme.txt from the repo to finish the deletion test.
441556a Adding a file to test Git deletion.
2a4c5b8 Added example code to README.md e1ae3a3 An initial add of the project files.
256
Глава 12.Git и организация программных проектов
Если вывод остается слишком длинным, используйте ключ
-n для ограничения вывода n последними коммитами. Введите команду git log
--oneline
-n
3
, чтобы просмотреть только три последних коммита:
C:\Users\Al\wizcoin>git log --oneline -n 3
962a8ba (HEAD -> master) Moving the README file back to its original place and name.
3ed22ed Testing the moving of files in Git.
15734e5 Deleting deleteme.txt from the repo to finish the deletion test.
Чтобы вывести содержимое файла на момент конкретного коммита, можно за- дать команду git show
<хеш>
:
<имя_файла>. Впрочем, графические средства Git предоставляют более удобный интерфейс для просмотра журнала, чем командная строка Git.
Восстановление старых изменений
Допустим, вы хотите вернуться к более ранней версии своего исходного кода, потому что в программе была допущена ошибка или вы случайно удалили файл.
Система контроля версий позволяет вернуть рабочую копию к состоянию более раннего коммита. Конкретная команда зависит от состояния файлов в рабочей копии.
Помните, что системы контроля версий только добавляют информацию. Даже при удалении файла из репозитория Git запомнит его, чтобы его можно было восстано- вить в будущем. Отмена изменения в действительности добавляет новое изменение, которое возвращает файл к его состоянию при предыдущем коммите. Подробная информация о различных видах отмены доступна на https://github.blog/2015-06-
08-how-to-undo-almost-anything-with-git/.
Отмена несохраненных локальных изменений
Если вы внесли в файл несохраненные изменения, но хотите вернуть его к версии в последнем коммите, выполните команду git restore
<имя_файла>. В следующем примере мы изменяем файл
README.md
, но не индексируем и не сохраняем его:
C:\Users\Al\wizcoin>git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
C:\Users\Al\wizcoin>git restore README.md
Восстановление старых изменений
257
C:\Users\Al\wizcoin>git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
После выполнения команды git restore
README.md содержимое файла
README.md становится таким, как в последнем коммите. Фактически это операция отмены из- менений, внесенных в файл (который еще не был проиндексирован или сохранен).
Но будьте внимательны: вы уже не сможете отменить эту «отмену», чтобы вернуть последние изменения. Также можно выполнить команду git checkout
, чтобы от- менить все изменения во всех файлах рабочей копии.
Деиндексирование проиндексированного файла
Если вы проиндексировали измененный файл командой git add
, а теперь хотите исключить его из индексированного состояния, чтобы он не был включен в следу- ющий коммит, выполните команду git restore
--staged
<имя_файла>:
C:\Users\Al>git restore --staged README.md
Unstaged changes after reset:
M spam.txt
Файл
README.md остается измененным, как это было до его индексирования ко- мандой git add
, но он не находится в индексированном состоянии.
Отмена последних коммитов
Допустим, вы сделали несколько бесполезных коммитов и теперь хотите вернуться к предыдущему коммиту. Чтобы отменить конкретное число последних коммитов
(например, 3), используйте команду git revert
-n
HEAD3..HEAD
. Вместо
3
можно указать любое количество коммитов. Предположим, вы отслеживаете изменения в детективном романе, который вы пишете, и у вас имеется следующий журнал Git со всеми коммитами и сообщениями:
C:\Users\Al\novel>git log --oneline
de24642 (HEAD -> master) Changed the setting to outer space.
2be4163 Added a whacky sidekick.
97c655e Renamed the detective to 'Snuggles'.
8aa5222 Added an exciting plot twist.
2590860 Finished chapter 1.
2dece36 Started my novel.
В какой-то момент вы решаете, что хотите начать заново с сюжетного поворота с хешем
8aa5222
. Это означает, что нужно отменить изменения трех последних коммитов: de24642
,
2be4163
и
97c655e
. Выполните команду git revert
-n
HEAD3..
258
Глава 12.Git и организация программных проектов
HEAD
, чтобы отменить эти изменения, а затем выполните команды git add и git commit
-m
"
<сообщение>
"
для сохранения контента, как и для любого другого изменения:
C:\Users\Al\novel>git revert -n HEAD3..HEAD
C:\Users\Al\novel>git add .
C:\Users\Al\novel>git commit -m "Starting over from the plot twist."
[master faec20e] Starting over from the plot twist.
1 file changed, 34 deletions(-)
C:\Users\Al\novel>git log --oneline
faec20e (HEAD -> master) Starting over from the plot twist.
de24642 Changed the setting to outer space.
2be4163 Added a whacky sidekick.
97c655e Renamed the detective to 'Snuggles'.
8aa5222 Added an exciting plot twist.
2590860 Finished chapter 1.
2dece36 Started my novel.
Репозитории Git обычно только добавляют информацию, поэтому при отмене ком- митов они остаются в истории коммитов. Если потребуется «отменить отмену», вы можете снова вернуться к нужному состоянию командой git revert
Возврат к конкретному коммиту для отдельного файла
Так как коммиты отражают состояние всего репозитория, а не отдельных файлов, то вам потребуется другая команда, если вы захотите отменить изменения для от- дельного файла. Допустим, я веду репозиторий Git для небольшого программного проекта. Я создал файл eggs.py
, добавил в него функции spam()
и bacon()
, а затем переименовал bacon()
в cheese()
. Журнал репозитория будет выглядеть примерно так:
C:\Users\Al\myproject>git log --oneline
895d220 (HEAD -> master) Adding email support to cheese().
df617da Renaming bacon() to cheese().
ef1e4bb Refactoring bacon().
ac27c9e Adding bacon() function.
009b7c0 Adding better documentation to spam().
0657588 Creating spam() function.
d811971 Initial add.
Но я решил, что я хочу вернуться к файлу до добавления функции bacon()
, но не изменять любые другие файлы в репозитории. Можно воспользоваться командой git show
<хеш>
:
<имя_файла> для вывода этого файла на момент последнего конкретного коммита. Команда выглядит примерно так:
Восстановление старых изменений
259
C:\Users\Al\myproject>git show 009b7c0:eggs.py
<содержимое eggs.py на момент сохранения 009b7c0>
При помощи команды git checkout
<хеш>
--
<имя_файла> можно вернуть со- держимое eggs.py к этой версии и сохранить измененный файл обычным способом.
Команда git checkout изменяет только рабочую копию. Вам останется только про- индексировать и сохранить эти коррективы, как и любые другие:
C:\Users\Al\myproject>git checkout 009b7c0 -- eggs.py
C:\Users\Al\myproject>git add eggs.py
C:\Users\Al\myproject>git commit -m "Rolled back eggs.py to 009b7c0"
[master d41e595] Rolled back eggs.py to 009b7c0 1 file changed, 47 deletions(-)
C:\Users\Al\myproject>git log --oneline
d41e595 (HEAD -> master) Rolled back eggs.py to 009b7c0 895d220 Adding email support to cheese().
df617da Renaming bacon() to cheese().
ef1e4bb Refactoring bacon().
ac27c9e Adding bacon() function.
009b7c0 Adding better documentation to spam().
0657588 Creating spam() function.
d811971 Initial add.
Файл eggs.py был возвращен к прежнему состоянию, а оставшаяся часть репози- тория осталась неизменной.
Перезапись истории коммитов
Если вы случайно сохранили файл, содержащий конфиденциальную информа- цию (пароли, ключи API, номера кредитных карт), недостаточно вычеркнуть эту информацию и создать новый коммит. Каждый, кто имеет доступ к репозиторию на вашем компьютере или к удаленному репозиторию, сможет вернуться к версии, содержащей эту информацию.
Удалить информацию из репозитория так, чтобы ее было невозможно вос- становить, непросто, но возможно. Подробно рассказывать об этом здесь я не буду, но вы можете воспользоваться либо командой git filter-branch or, либо программой BFG Repo-Cleaner (этот вариант считается предпочтительным).
Оба варианта описаны на https://help.github.com/en/articles/removing-sensitive-
data-from-a-repository.
Простейшая превентивная мера — разместить конфиденциальную информацию в файле с именем secrets.txt
, conidential.py или что-нибудь в этом роде. Файл включа- ется в
.gitignore
, чтобы он никогда не был сохранен в репозитории. Ваша программа
260
Глава 12.Git и организация программных проектов может прочитать конфиденциальную информацию из файла — это лучше, чем раз- мещать такую информацию непосредственно в исходном коде.
GitHub и команда git push
Хотя репозитории Git могут существовать на вашем компьютере, многие бесплат- ные веб-сайты позволяют размещать клоны ваших репозиториев в интернете, чтобы другие люди могли легко загрузить ваши проекты и участвовать в работе над ними.
Самый большой из таких сайтов — GitHub. Если вы сохраните клон своего проекта в интернете, коллеги смогут дополнять ваш код, даже когда компьютер, на котором вы работаете, отключен. Кроме того, клонированная копия фактически выполняет роль резервной копии.
ПРИМЕЧАНИЕ
Чтобы избежать путаницы с терминами: Git — система контроля версий, которая под- держивает репозиторий и включает команду git. GitHub — веб-сайт для размещения репозиториев Git в интернете.
Рис. 12.6. Создание нового репозитория на GitHub
GitHub и команда git push
261
Зайдите на сайт https://github.com и зарегистрируйтесь для получения бесплатной учетной записи. На домашней странице GitHub или на вкладке
Repositories страницы вашего профиля щелкните на кнопке
New
, чтобы создать новый проект. Введите имя репозитория wizcoin и описание проекта — об этом я рассказывал в разделе «Соз- дание новых проектов Python с использованием Cookiecutter» на с. 236 (рис. 12.6).
Пометьте репозиторий как общедоступный (
Public
) и снимите флажок
Initialize this repository with a README
, потому что мы импортируем существующий репозиторий.
Щелкните на кнопке
Create repository
. Все эти действия эквивалентны выполнению команды git init на веб-сайте GitHub.
Веб-страница для ваших репозиториев будет располагаться по адресу https://github.
com/<имя_пользователя>/<имя_репозитория>. Мой репозиторий wizcoin раз- мещается на https://github.com/asweigart/wizcoin.
Отправка существующего репозитория на GitHub
Чтобы отправить существующий репозиторий из командной строки, введите сле- дующие команды:
C:\Users\Al\wizcoin>git remote add origin https://github.com/<пользователь_github>/
wizcoin.git
C:\Users\Al\wizcoin>git push -u origin master
Username for 'https://github.com': <пользователь_github>
Password for 'https://@github.com': <пароль_github>
Counting objects: 3, done.
Writing objects: 100% (3/3), 213 bytes | 106.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/<ваш_github>/wizcoin.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Команда git remote add origin https://github.com/
<пользователь_github>
/
wizcoin.git добавляет GitHub как удаленный репозиторий, соответствующий ва- шему локальному репозиторию. После этого вы можете отправить все изменения, внесенные в локальном репозитории, в удаленный командой git push
-u origin master
. Следующие отправки из локального репозитория вы сможете осуществлять простой командой git push
. Отправка копий на GitHub после каждого коммита — хорошая тактика, гарантирующая синхронизацию удаленного репозитория на
GitHub с вашим локальным репозиторием, но она не обязательна.
Загрузив веб-страницу репозитория на GitHub, вы должны получить информацию о файлах и коммитах. Конечно, это далеко не все, что можно узнать о GitHub — включая и то, как принимать действия других людей в ваших репозиториях посред- ством pull-запросов. Эта тема, наряду с другими расширенными возможностями
GitHub, выходит за рамки книги.
262
Глава 12.Git и организация программных проектов
1 ... 23 24 25 26 27 28 29 30 ... 40
echo "Test file" > deleteme.txt
C:\Users\Al\wizcoin>git add deleteme.txt
C:\Users\Al\wizcoin>git commit -m "Adding a file to test Git deletion."
[master 441556a] Adding a file to test Git deletion.
1 file changed, 1 insertion(+)
create mode 100644 deleteme.txt
C:\Users\Al\wizcoin>git status
On branch master nothing to commit, working tree clean
Создание репозитория Git на вашем компьютере
253
Не удаляйте файлы командой del в Windows или командой rm в macOS и Linux.
(А если вы это сделаете, файл можно восстановить командой git restore
<имя_фай-
ла> или просто перейти к команде git rm
, чтобы удалить файл из репозитория.)
Вместо этого воспользуйтесь командой git rm
, чтобы удалить и проиндексировать файл deleteme.txt
, как это делается в следующем примере:
C:\Users\Al\wizcoin>git rm deleteme.txt
rm deleteme.txt'
Команда git rm удаляет файл из рабочей копии, но это еще не все. Как и git add
, команда git rm индексирует файл. Удаление файла необходимо закрепить точно так же, как любые другие изменения:
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
❶
deleted: deleteme.txt
C:\Users\Al\wizcoin>git commit -m "Deleting deleteme.txt from the repo to
finish the deletion test."
[master 369de78] Deleting deleteme.txt from the repo to finish the deletion test.
1 file changed, 1 deletion(-)
delete mode 100644 deleteme.txt
C:\Users\Al\Desktop\wizcoin>git status
On branch master nothing to commit, working tree clean
Хотя файл deleteme.txt был удален из рабочей копии, он все еще существует в исто- рии репозитория. В разделе «Восстановление старых изменений» этой главы рас- сказано, как восстановить удаленный файл или отменить изменение.
Команда git rm работает только с файлами, находящимися в чистом, сохраненном, состоянии без каких-либо изменений. В противном случае Git предложит сохранить изменения или отменить их командой git reset
HEAD
<имя_файла>. (Вывод git status напомнит вам об этой команде
❶
.) Такая процедура предотвращает случайное удаление несохраненных изменений.
Переименование и перемещение файлов из репозитория
Как и при удалении файлов, вы не должны переименовывать или перемещать файлы в репозитории в обход Git. В противном случае Git решит, что вы просто удалили файл, и создаст новый файл с прежним содержимым. Вместо этого используйте команду git mv с последующей командой git commit
254
Глава 12.Git и организация программных проектов
Переименуйте
README.md в
README.txt следующими командами:
C:\Users\Al\wizcoin>git mv README.md README.txt
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: README.md -> README.txt
C:\Users\Al\wizcoin>git commit -m "Testing the renaming of files in Git."
[master 3fee6a6] Testing the renaming of files in Git.
1 file changed, 0 insertions(+), 0 deletions(-)
rename README.md => README.txt (100%)
В этом случае история изменений
README.txt также включает историю
README.md
Также можно воспользоваться командой git mv для перемещения файла в новую папку. Введите следующие команды, чтобы создать новую папку с именем movetest и переместить в нее файл
README.txt
:
C:\Users\Al\wizcoin>mkdir movetest
C:\Users\Al\wizcoin>git mv README.txt movetest/README.txt
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: README.txt -> movetest/README.txt
C:\Users\Al\wizcoin>git commit -m "Testing the moving of files in Git."
[master 3ed22ed] Testing the moving of files in Git.
1 file changed, 0 insertions(+), 0 deletions(-)
rename README.txt => movetest/README.txt (100%)
Также можно совместить переименование файла с перемещением — для этого сле- дует передать git mv новое имя и местоположение файла. Вернем файл
README.txt в корневой рабочий каталог с восстановлением исходного имени:
C:\Users\Al\wizcoin>git mv movetest/README.txt README.md
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
renamed: movetest/README.txt -> README.md
C:\Users\Al\wizcoin>git commit -m "Moving the README file back to its original
place and name."
[master 962a8ba] Moving the README file back to its original place and name.
Просмотр журнала коммитов
255 1 file changed, 0 insertions(+), 0 deletions(-)
rename movetest/README.txt => README.md (100%)
Хотя файл
README.md вернулся в исходную папку и имеет исходное имя, репози- торий Git запоминает изменения имени и местоположения. Историю изменений можно вызвать командой git log
, о которой пойдет речь в следующем разделе.
Просмотр журнала коммитов
Команда git log выводит список всех коммитов:
C:\Users\Al\wizcoin>git log
commit 962a8baa29e452c74d40075d92b00897b02668fb (HEAD -> master)
Author: Al Sweigart
Date: Wed Sep 1 10:38:23 2021 -0700
Moving the README file back to its original place and name.
commit 3ed22ed7ae26220bbd4c4f6bc52f4700dbb7c1f1
Author: Al Sweigart
Date: Wed Sep 1 10:36:29 2021 -0700
Testing the moving of files in Git.
--snip--
Команда способна выводить большой объем текста. Если журнал не помещается в окне терминала, текст можно прокрутить клавишами
↑ и ↓. Чтобы завершить просмотр, нажмите клавишу q.
Если вы хотите вернуть файлы к более раннему коммиту, сначала следует найти
хеш коммита — строку из 40 шестнадцатеричных цифр (0–9 и буквы A–F), которая служит уникальным идентификатором коммита. Например, последний коммит в нашем репозитории представлен хешем
962a8baa29e452c74d40075d92b00897b026 68fb
. На практике обычно используются только первые семь знаков:
962a8ba
Со временем журнал может стать очень длинным. Ключ
--oneline усекает вывод до сокращенных хешей и первой строки каждого сообщения коммита. Введите команду git log
--oneline в командной строке:
C:\Users\Al\wizcoin>git log --oneline
962a8ba (HEAD -> master) Moving the README file back to its original place and name.
3ed22ed Testing the moving of files in Git.
15734e5 Deleting deleteme.txt from the repo to finish the deletion test.
441556a Adding a file to test Git deletion.
2a4c5b8 Added example code to README.md e1ae3a3 An initial add of the project files.
256
Глава 12.Git и организация программных проектов
Если вывод остается слишком длинным, используйте ключ
-n для ограничения вывода n последними коммитами. Введите команду git log
--oneline
-n
3
, чтобы просмотреть только три последних коммита:
C:\Users\Al\wizcoin>git log --oneline -n 3
962a8ba (HEAD -> master) Moving the README file back to its original place and name.
3ed22ed Testing the moving of files in Git.
15734e5 Deleting deleteme.txt from the repo to finish the deletion test.
Чтобы вывести содержимое файла на момент конкретного коммита, можно за- дать команду git show
<хеш>
:
<имя_файла>. Впрочем, графические средства Git предоставляют более удобный интерфейс для просмотра журнала, чем командная строка Git.
Восстановление старых изменений
Допустим, вы хотите вернуться к более ранней версии своего исходного кода, потому что в программе была допущена ошибка или вы случайно удалили файл.
Система контроля версий позволяет вернуть рабочую копию к состоянию более раннего коммита. Конкретная команда зависит от состояния файлов в рабочей копии.
Помните, что системы контроля версий только добавляют информацию. Даже при удалении файла из репозитория Git запомнит его, чтобы его можно было восстано- вить в будущем. Отмена изменения в действительности добавляет новое изменение, которое возвращает файл к его состоянию при предыдущем коммите. Подробная информация о различных видах отмены доступна на https://github.blog/2015-06-
08-how-to-undo-almost-anything-with-git/.
Отмена несохраненных локальных изменений
Если вы внесли в файл несохраненные изменения, но хотите вернуть его к версии в последнем коммите, выполните команду git restore
<имя_файла>. В следующем примере мы изменяем файл
README.md
, но не индексируем и не сохраняем его:
C:\Users\Al\wizcoin>git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
C:\Users\Al\wizcoin>git restore README.md
Восстановление старых изменений
257
C:\Users\Al\wizcoin>git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
После выполнения команды git restore
README.md содержимое файла
README.md становится таким, как в последнем коммите. Фактически это операция отмены из- менений, внесенных в файл (который еще не был проиндексирован или сохранен).
Но будьте внимательны: вы уже не сможете отменить эту «отмену», чтобы вернуть последние изменения. Также можно выполнить команду git checkout
, чтобы от- менить все изменения во всех файлах рабочей копии.
Деиндексирование проиндексированного файла
Если вы проиндексировали измененный файл командой git add
, а теперь хотите исключить его из индексированного состояния, чтобы он не был включен в следу- ющий коммит, выполните команду git restore
--staged
<имя_файла>:
C:\Users\Al>git restore --staged README.md
Unstaged changes after reset:
M spam.txt
Файл
README.md остается измененным, как это было до его индексирования ко- мандой git add
, но он не находится в индексированном состоянии.
Отмена последних коммитов
Допустим, вы сделали несколько бесполезных коммитов и теперь хотите вернуться к предыдущему коммиту. Чтобы отменить конкретное число последних коммитов
(например, 3), используйте команду git revert
-n
HEAD3..HEAD
. Вместо
3
можно указать любое количество коммитов. Предположим, вы отслеживаете изменения в детективном романе, который вы пишете, и у вас имеется следующий журнал Git со всеми коммитами и сообщениями:
C:\Users\Al\novel>git log --oneline
de24642 (HEAD -> master) Changed the setting to outer space.
2be4163 Added a whacky sidekick.
97c655e Renamed the detective to 'Snuggles'.
8aa5222 Added an exciting plot twist.
2590860 Finished chapter 1.
2dece36 Started my novel.
В какой-то момент вы решаете, что хотите начать заново с сюжетного поворота с хешем
8aa5222
. Это означает, что нужно отменить изменения трех последних коммитов: de24642
,
2be4163
и
97c655e
. Выполните команду git revert
-n
HEAD3..
258
Глава 12.Git и организация программных проектов
HEAD
, чтобы отменить эти изменения, а затем выполните команды git add и git commit
-m
"
<сообщение>
"
для сохранения контента, как и для любого другого изменения:
C:\Users\Al\novel>git revert -n HEAD3..HEAD
C:\Users\Al\novel>git add .
C:\Users\Al\novel>git commit -m "Starting over from the plot twist."
[master faec20e] Starting over from the plot twist.
1 file changed, 34 deletions(-)
C:\Users\Al\novel>git log --oneline
faec20e (HEAD -> master) Starting over from the plot twist.
de24642 Changed the setting to outer space.
2be4163 Added a whacky sidekick.
97c655e Renamed the detective to 'Snuggles'.
8aa5222 Added an exciting plot twist.
2590860 Finished chapter 1.
2dece36 Started my novel.
Репозитории Git обычно только добавляют информацию, поэтому при отмене ком- митов они остаются в истории коммитов. Если потребуется «отменить отмену», вы можете снова вернуться к нужному состоянию командой git revert
Возврат к конкретному коммиту для отдельного файла
Так как коммиты отражают состояние всего репозитория, а не отдельных файлов, то вам потребуется другая команда, если вы захотите отменить изменения для от- дельного файла. Допустим, я веду репозиторий Git для небольшого программного проекта. Я создал файл eggs.py
, добавил в него функции spam()
и bacon()
, а затем переименовал bacon()
в cheese()
. Журнал репозитория будет выглядеть примерно так:
C:\Users\Al\myproject>git log --oneline
895d220 (HEAD -> master) Adding email support to cheese().
df617da Renaming bacon() to cheese().
ef1e4bb Refactoring bacon().
ac27c9e Adding bacon() function.
009b7c0 Adding better documentation to spam().
0657588 Creating spam() function.
d811971 Initial add.
Но я решил, что я хочу вернуться к файлу до добавления функции bacon()
, но не изменять любые другие файлы в репозитории. Можно воспользоваться командой git show
<хеш>
:
<имя_файла> для вывода этого файла на момент последнего конкретного коммита. Команда выглядит примерно так:
Восстановление старых изменений
259
C:\Users\Al\myproject>git show 009b7c0:eggs.py
<содержимое eggs.py на момент сохранения 009b7c0>
При помощи команды git checkout
<хеш>
--
<имя_файла> можно вернуть со- держимое eggs.py к этой версии и сохранить измененный файл обычным способом.
Команда git checkout изменяет только рабочую копию. Вам останется только про- индексировать и сохранить эти коррективы, как и любые другие:
C:\Users\Al\myproject>git checkout 009b7c0 -- eggs.py
C:\Users\Al\myproject>git add eggs.py
C:\Users\Al\myproject>git commit -m "Rolled back eggs.py to 009b7c0"
[master d41e595] Rolled back eggs.py to 009b7c0 1 file changed, 47 deletions(-)
C:\Users\Al\myproject>git log --oneline
d41e595 (HEAD -> master) Rolled back eggs.py to 009b7c0 895d220 Adding email support to cheese().
df617da Renaming bacon() to cheese().
ef1e4bb Refactoring bacon().
ac27c9e Adding bacon() function.
009b7c0 Adding better documentation to spam().
0657588 Creating spam() function.
d811971 Initial add.
Файл eggs.py был возвращен к прежнему состоянию, а оставшаяся часть репози- тория осталась неизменной.
Перезапись истории коммитов
Если вы случайно сохранили файл, содержащий конфиденциальную информа- цию (пароли, ключи API, номера кредитных карт), недостаточно вычеркнуть эту информацию и создать новый коммит. Каждый, кто имеет доступ к репозиторию на вашем компьютере или к удаленному репозиторию, сможет вернуться к версии, содержащей эту информацию.
Удалить информацию из репозитория так, чтобы ее было невозможно вос- становить, непросто, но возможно. Подробно рассказывать об этом здесь я не буду, но вы можете воспользоваться либо командой git filter-branch or, либо программой BFG Repo-Cleaner (этот вариант считается предпочтительным).
Оба варианта описаны на https://help.github.com/en/articles/removing-sensitive-
data-from-a-repository.
Простейшая превентивная мера — разместить конфиденциальную информацию в файле с именем secrets.txt
, conidential.py или что-нибудь в этом роде. Файл включа- ется в
.gitignore
, чтобы он никогда не был сохранен в репозитории. Ваша программа
260
Глава 12.Git и организация программных проектов может прочитать конфиденциальную информацию из файла — это лучше, чем раз- мещать такую информацию непосредственно в исходном коде.
GitHub и команда git push
Хотя репозитории Git могут существовать на вашем компьютере, многие бесплат- ные веб-сайты позволяют размещать клоны ваших репозиториев в интернете, чтобы другие люди могли легко загрузить ваши проекты и участвовать в работе над ними.
Самый большой из таких сайтов — GitHub. Если вы сохраните клон своего проекта в интернете, коллеги смогут дополнять ваш код, даже когда компьютер, на котором вы работаете, отключен. Кроме того, клонированная копия фактически выполняет роль резервной копии.
ПРИМЕЧАНИЕ
Чтобы избежать путаницы с терминами: Git — система контроля версий, которая под- держивает репозиторий и включает команду git. GitHub — веб-сайт для размещения репозиториев Git в интернете.
Рис. 12.6. Создание нового репозитория на GitHub
GitHub и команда git push
261
Зайдите на сайт https://github.com и зарегистрируйтесь для получения бесплатной учетной записи. На домашней странице GitHub или на вкладке
Repositories страницы вашего профиля щелкните на кнопке
New
, чтобы создать новый проект. Введите имя репозитория wizcoin и описание проекта — об этом я рассказывал в разделе «Соз- дание новых проектов Python с использованием Cookiecutter» на с. 236 (рис. 12.6).
Пометьте репозиторий как общедоступный (
Public
) и снимите флажок
Initialize this repository with a README
, потому что мы импортируем существующий репозиторий.
Щелкните на кнопке
Create repository
. Все эти действия эквивалентны выполнению команды git init на веб-сайте GitHub.
Веб-страница для ваших репозиториев будет располагаться по адресу https://github.
com/<имя_пользователя>/<имя_репозитория>. Мой репозиторий wizcoin раз- мещается на https://github.com/asweigart/wizcoin.
Отправка существующего репозитория на GitHub
Чтобы отправить существующий репозиторий из командной строки, введите сле- дующие команды:
C:\Users\Al\wizcoin>git remote add origin https://github.com/<пользователь_github>/
wizcoin.git
C:\Users\Al\wizcoin>git push -u origin master
Username for 'https://github.com': <пользователь_github>
Password for 'https://@github.com': <пароль_github>
Counting objects: 3, done.
Writing objects: 100% (3/3), 213 bytes | 106.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/<ваш_github>/wizcoin.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Команда git remote add origin https://github.com/
<пользователь_github>
/
wizcoin.git добавляет GitHub как удаленный репозиторий, соответствующий ва- шему локальному репозиторию. После этого вы можете отправить все изменения, внесенные в локальном репозитории, в удаленный командой git push
-u origin master
. Следующие отправки из локального репозитория вы сможете осуществлять простой командой git push
. Отправка копий на GitHub после каждого коммита — хорошая тактика, гарантирующая синхронизацию удаленного репозитория на
GitHub с вашим локальным репозиторием, но она не обязательна.
Загрузив веб-страницу репозитория на GitHub, вы должны получить информацию о файлах и коммитах. Конечно, это далеко не все, что можно узнать о GitHub — включая и то, как принимать действия других людей в ваших репозиториях посред- ством pull-запросов. Эта тема, наряду с другими расширенными возможностями
GitHub, выходит за рамки книги.
262
Глава 12.Git и организация программных проектов
1 ... 23 24 25 26 27 28 29 30 ... 40
Создание репозитория Git на вашем компьютере
253
Не удаляйте файлы командой del в Windows или командой rm в macOS и Linux.
(А если вы это сделаете, файл можно восстановить командой git restore
<имя_фай-
ла> или просто перейти к команде git rm
, чтобы удалить файл из репозитория.)
Вместо этого воспользуйтесь командой git rm
, чтобы удалить и проиндексировать файл deleteme.txt
, как это делается в следующем примере:
C:\Users\Al\wizcoin>git rm deleteme.txt
rm deleteme.txt'
Команда git rm удаляет файл из рабочей копии, но это еще не все. Как и git add
, команда git rm индексирует файл. Удаление файла необходимо закрепить точно так же, как любые другие изменения:
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD
❶
deleted: deleteme.txt
C:\Users\Al\wizcoin>git commit -m "Deleting deleteme.txt from the repo to
finish the deletion test."
[master 369de78] Deleting deleteme.txt from the repo to finish the deletion test.
1 file changed, 1 deletion(-)
delete mode 100644 deleteme.txt
C:\Users\Al\Desktop\wizcoin>git status
On branch master nothing to commit, working tree clean
Хотя файл deleteme.txt был удален из рабочей копии, он все еще существует в исто- рии репозитория. В разделе «Восстановление старых изменений» этой главы рас- сказано, как восстановить удаленный файл или отменить изменение.
Команда git rm работает только с файлами, находящимися в чистом, сохраненном, состоянии без каких-либо изменений. В противном случае Git предложит сохранить изменения или отменить их командой git reset
HEAD
<имя_файла>. (Вывод git status напомнит вам об этой команде
❶
.) Такая процедура предотвращает случайное удаление несохраненных изменений.
Переименование и перемещение файлов из репозитория
Как и при удалении файлов, вы не должны переименовывать или перемещать файлы в репозитории в обход Git. В противном случае Git решит, что вы просто удалили файл, и создаст новый файл с прежним содержимым. Вместо этого используйте команду git mv с последующей командой git commit
254
Глава 12.Git и организация программных проектов
Переименуйте
README.md в
README.txt следующими командами:
C:\Users\Al\wizcoin>git mv README.md README.txt
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD
renamed: README.md -> README.txt
C:\Users\Al\wizcoin>git commit -m "Testing the renaming of files in Git."
[master 3fee6a6] Testing the renaming of files in Git.
1 file changed, 0 insertions(+), 0 deletions(-)
rename README.md => README.txt (100%)
В этом случае история изменений
README.txt также включает историю
README.md
Также можно воспользоваться командой git mv для перемещения файла в новую папку. Введите следующие команды, чтобы создать новую папку с именем movetest и переместить в нее файл
README.txt
:
C:\Users\Al\wizcoin>mkdir movetest
C:\Users\Al\wizcoin>git mv README.txt movetest/README.txt
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD
renamed: README.txt -> movetest/README.txt
C:\Users\Al\wizcoin>git commit -m "Testing the moving of files in Git."
[master 3ed22ed] Testing the moving of files in Git.
1 file changed, 0 insertions(+), 0 deletions(-)
rename README.txt => movetest/README.txt (100%)
Также можно совместить переименование файла с перемещением — для этого сле- дует передать git mv новое имя и местоположение файла. Вернем файл
README.txt в корневой рабочий каталог с восстановлением исходного имени:
C:\Users\Al\wizcoin>git mv movetest/README.txt README.md
C:\Users\Al\wizcoin>git status
On branch master
Changes to be committed:
(use "git reset HEAD
renamed: movetest/README.txt -> README.md
C:\Users\Al\wizcoin>git commit -m "Moving the README file back to its original
place and name."
[master 962a8ba] Moving the README file back to its original place and name.
Просмотр журнала коммитов
255 1 file changed, 0 insertions(+), 0 deletions(-)
rename movetest/README.txt => README.md (100%)
Хотя файл
README.md вернулся в исходную папку и имеет исходное имя, репози- торий Git запоминает изменения имени и местоположения. Историю изменений можно вызвать командой git log
, о которой пойдет речь в следующем разделе.
Просмотр журнала коммитов
Команда git log выводит список всех коммитов:
C:\Users\Al\wizcoin>git log
commit 962a8baa29e452c74d40075d92b00897b02668fb (HEAD -> master)
Author: Al Sweigart
Date: Wed Sep 1 10:38:23 2021 -0700
Moving the README file back to its original place and name.
commit 3ed22ed7ae26220bbd4c4f6bc52f4700dbb7c1f1
Author: Al Sweigart
Date: Wed Sep 1 10:36:29 2021 -0700
Testing the moving of files in Git.
--snip--
Команда способна выводить большой объем текста. Если журнал не помещается в окне терминала, текст можно прокрутить клавишами
↑ и ↓. Чтобы завершить просмотр, нажмите клавишу q.
Если вы хотите вернуть файлы к более раннему коммиту, сначала следует найти
хеш коммита — строку из 40 шестнадцатеричных цифр (0–9 и буквы A–F), которая служит уникальным идентификатором коммита. Например, последний коммит в нашем репозитории представлен хешем
962a8baa29e452c74d40075d92b00897b026 68fb
. На практике обычно используются только первые семь знаков:
962a8ba
Со временем журнал может стать очень длинным. Ключ
--oneline усекает вывод до сокращенных хешей и первой строки каждого сообщения коммита. Введите команду git log
--oneline в командной строке:
C:\Users\Al\wizcoin>git log --oneline
962a8ba (HEAD -> master) Moving the README file back to its original place and name.
3ed22ed Testing the moving of files in Git.
15734e5 Deleting deleteme.txt from the repo to finish the deletion test.
441556a Adding a file to test Git deletion.
2a4c5b8 Added example code to README.md e1ae3a3 An initial add of the project files.
256
Глава 12.Git и организация программных проектов
Если вывод остается слишком длинным, используйте ключ
-n для ограничения вывода n последними коммитами. Введите команду git log
--oneline
-n
3
, чтобы просмотреть только три последних коммита:
C:\Users\Al\wizcoin>git log --oneline -n 3
962a8ba (HEAD -> master) Moving the README file back to its original place and name.
3ed22ed Testing the moving of files in Git.
15734e5 Deleting deleteme.txt from the repo to finish the deletion test.
Чтобы вывести содержимое файла на момент конкретного коммита, можно за- дать команду git show
<хеш>
:
<имя_файла>. Впрочем, графические средства Git предоставляют более удобный интерфейс для просмотра журнала, чем командная строка Git.
Восстановление старых изменений
Допустим, вы хотите вернуться к более ранней версии своего исходного кода, потому что в программе была допущена ошибка или вы случайно удалили файл.
Система контроля версий позволяет вернуть рабочую копию к состоянию более раннего коммита. Конкретная команда зависит от состояния файлов в рабочей копии.
Помните, что системы контроля версий только добавляют информацию. Даже при удалении файла из репозитория Git запомнит его, чтобы его можно было восстано- вить в будущем. Отмена изменения в действительности добавляет новое изменение, которое возвращает файл к его состоянию при предыдущем коммите. Подробная информация о различных видах отмены доступна на https://github.blog/2015-06-
08-how-to-undo-almost-anything-with-git/.
Отмена несохраненных локальных изменений
Если вы внесли в файл несохраненные изменения, но хотите вернуть его к версии в последнем коммите, выполните команду git restore
<имя_файла>. В следующем примере мы изменяем файл
README.md
, но не индексируем и не сохраняем его:
C:\Users\Al\wizcoin>git status
On branch master
Changes not staged for commit:
(use "git add
(use "git restore
modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
C:\Users\Al\wizcoin>git restore README.md
Восстановление старых изменений
257
C:\Users\Al\wizcoin>git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
После выполнения команды git restore
README.md содержимое файла
README.md становится таким, как в последнем коммите. Фактически это операция отмены из- менений, внесенных в файл (который еще не был проиндексирован или сохранен).
Но будьте внимательны: вы уже не сможете отменить эту «отмену», чтобы вернуть последние изменения. Также можно выполнить команду git checkout
, чтобы от- менить все изменения во всех файлах рабочей копии.
Деиндексирование проиндексированного файла
Если вы проиндексировали измененный файл командой git add
, а теперь хотите исключить его из индексированного состояния, чтобы он не был включен в следу- ющий коммит, выполните команду git restore
--staged
<имя_файла>:
C:\Users\Al>git restore --staged README.md
Unstaged changes after reset:
M spam.txt
Файл
README.md остается измененным, как это было до его индексирования ко- мандой git add
, но он не находится в индексированном состоянии.
Отмена последних коммитов
Допустим, вы сделали несколько бесполезных коммитов и теперь хотите вернуться к предыдущему коммиту. Чтобы отменить конкретное число последних коммитов
(например, 3), используйте команду git revert
-n
HEAD3..HEAD
. Вместо
3
можно указать любое количество коммитов. Предположим, вы отслеживаете изменения в детективном романе, который вы пишете, и у вас имеется следующий журнал Git со всеми коммитами и сообщениями:
C:\Users\Al\novel>git log --oneline
de24642 (HEAD -> master) Changed the setting to outer space.
2be4163 Added a whacky sidekick.
97c655e Renamed the detective to 'Snuggles'.
8aa5222 Added an exciting plot twist.
2590860 Finished chapter 1.
2dece36 Started my novel.
В какой-то момент вы решаете, что хотите начать заново с сюжетного поворота с хешем
8aa5222
. Это означает, что нужно отменить изменения трех последних коммитов: de24642
,
2be4163
и
97c655e
. Выполните команду git revert
-n
HEAD3..
258
Глава 12.Git и организация программных проектов
HEAD
, чтобы отменить эти изменения, а затем выполните команды git add и git commit
-m
"
<сообщение>
"
для сохранения контента, как и для любого другого изменения:
C:\Users\Al\novel>git revert -n HEAD3..HEAD
C:\Users\Al\novel>git add .
C:\Users\Al\novel>git commit -m "Starting over from the plot twist."
[master faec20e] Starting over from the plot twist.
1 file changed, 34 deletions(-)
C:\Users\Al\novel>git log --oneline
faec20e (HEAD -> master) Starting over from the plot twist.
de24642 Changed the setting to outer space.
2be4163 Added a whacky sidekick.
97c655e Renamed the detective to 'Snuggles'.
8aa5222 Added an exciting plot twist.
2590860 Finished chapter 1.
2dece36 Started my novel.
Репозитории Git обычно только добавляют информацию, поэтому при отмене ком- митов они остаются в истории коммитов. Если потребуется «отменить отмену», вы можете снова вернуться к нужному состоянию командой git revert
Возврат к конкретному коммиту для отдельного файла
Так как коммиты отражают состояние всего репозитория, а не отдельных файлов, то вам потребуется другая команда, если вы захотите отменить изменения для от- дельного файла. Допустим, я веду репозиторий Git для небольшого программного проекта. Я создал файл eggs.py
, добавил в него функции spam()
и bacon()
, а затем переименовал bacon()
в cheese()
. Журнал репозитория будет выглядеть примерно так:
C:\Users\Al\myproject>git log --oneline
895d220 (HEAD -> master) Adding email support to cheese().
df617da Renaming bacon() to cheese().
ef1e4bb Refactoring bacon().
ac27c9e Adding bacon() function.
009b7c0 Adding better documentation to spam().
0657588 Creating spam() function.
d811971 Initial add.
Но я решил, что я хочу вернуться к файлу до добавления функции bacon()
, но не изменять любые другие файлы в репозитории. Можно воспользоваться командой git show
<хеш>
:
<имя_файла> для вывода этого файла на момент последнего конкретного коммита. Команда выглядит примерно так:
Восстановление старых изменений
259
C:\Users\Al\myproject>git show 009b7c0:eggs.py
<содержимое eggs.py на момент сохранения 009b7c0>
При помощи команды git checkout
<хеш>
--
<имя_файла> можно вернуть со- держимое eggs.py к этой версии и сохранить измененный файл обычным способом.
Команда git checkout изменяет только рабочую копию. Вам останется только про- индексировать и сохранить эти коррективы, как и любые другие:
C:\Users\Al\myproject>git checkout 009b7c0 -- eggs.py
C:\Users\Al\myproject>git add eggs.py
C:\Users\Al\myproject>git commit -m "Rolled back eggs.py to 009b7c0"
[master d41e595] Rolled back eggs.py to 009b7c0 1 file changed, 47 deletions(-)
C:\Users\Al\myproject>git log --oneline
d41e595 (HEAD -> master) Rolled back eggs.py to 009b7c0 895d220 Adding email support to cheese().
df617da Renaming bacon() to cheese().
ef1e4bb Refactoring bacon().
ac27c9e Adding bacon() function.
009b7c0 Adding better documentation to spam().
0657588 Creating spam() function.
d811971 Initial add.
Файл eggs.py был возвращен к прежнему состоянию, а оставшаяся часть репози- тория осталась неизменной.
Перезапись истории коммитов
Если вы случайно сохранили файл, содержащий конфиденциальную информа- цию (пароли, ключи API, номера кредитных карт), недостаточно вычеркнуть эту информацию и создать новый коммит. Каждый, кто имеет доступ к репозиторию на вашем компьютере или к удаленному репозиторию, сможет вернуться к версии, содержащей эту информацию.
Удалить информацию из репозитория так, чтобы ее было невозможно вос- становить, непросто, но возможно. Подробно рассказывать об этом здесь я не буду, но вы можете воспользоваться либо командой git filter-branch or, либо программой BFG Repo-Cleaner (этот вариант считается предпочтительным).
Оба варианта описаны на https://help.github.com/en/articles/removing-sensitive-
data-from-a-repository.
Простейшая превентивная мера — разместить конфиденциальную информацию в файле с именем secrets.txt
, conidential.py или что-нибудь в этом роде. Файл включа- ется в
.gitignore
, чтобы он никогда не был сохранен в репозитории. Ваша программа
260
Глава 12.Git и организация программных проектов может прочитать конфиденциальную информацию из файла — это лучше, чем раз- мещать такую информацию непосредственно в исходном коде.
GitHub и команда git push
Хотя репозитории Git могут существовать на вашем компьютере, многие бесплат- ные веб-сайты позволяют размещать клоны ваших репозиториев в интернете, чтобы другие люди могли легко загрузить ваши проекты и участвовать в работе над ними.
Самый большой из таких сайтов — GitHub. Если вы сохраните клон своего проекта в интернете, коллеги смогут дополнять ваш код, даже когда компьютер, на котором вы работаете, отключен. Кроме того, клонированная копия фактически выполняет роль резервной копии.
ПРИМЕЧАНИЕ
Чтобы избежать путаницы с терминами: Git — система контроля версий, которая под- держивает репозиторий и включает команду git. GitHub — веб-сайт для размещения репозиториев Git в интернете.
Рис. 12.6. Создание нового репозитория на GitHub
GitHub и команда git push
261
Зайдите на сайт https://github.com и зарегистрируйтесь для получения бесплатной учетной записи. На домашней странице GitHub или на вкладке
Repositories страницы вашего профиля щелкните на кнопке
New
, чтобы создать новый проект. Введите имя репозитория wizcoin и описание проекта — об этом я рассказывал в разделе «Соз- дание новых проектов Python с использованием Cookiecutter» на с. 236 (рис. 12.6).
Пометьте репозиторий как общедоступный (
Public
) и снимите флажок
Initialize this repository with a README
, потому что мы импортируем существующий репозиторий.
Щелкните на кнопке
Create repository
. Все эти действия эквивалентны выполнению команды git init на веб-сайте GitHub.
Веб-страница для ваших репозиториев будет располагаться по адресу https://github.
com/<имя_пользователя>/<имя_репозитория>. Мой репозиторий wizcoin раз- мещается на https://github.com/asweigart/wizcoin.
Отправка существующего репозитория на GitHub
Чтобы отправить существующий репозиторий из командной строки, введите сле- дующие команды:
C:\Users\Al\wizcoin>git remote add origin https://github.com/<пользователь_github>/
wizcoin.git
C:\Users\Al\wizcoin>git push -u origin master
Username for 'https://github.com': <пользователь_github>
Password for 'https://
Counting objects: 3, done.
Writing objects: 100% (3/3), 213 bytes | 106.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/<ваш_github>/wizcoin.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Команда git remote add origin https://github.com/
<пользователь_github>
/
wizcoin.git добавляет GitHub как удаленный репозиторий, соответствующий ва- шему локальному репозиторию. После этого вы можете отправить все изменения, внесенные в локальном репозитории, в удаленный командой git push
-u origin master
. Следующие отправки из локального репозитория вы сможете осуществлять простой командой git push
. Отправка копий на GitHub после каждого коммита — хорошая тактика, гарантирующая синхронизацию удаленного репозитория на
GitHub с вашим локальным репозиторием, но она не обязательна.
Загрузив веб-страницу репозитория на GitHub, вы должны получить информацию о файлах и коммитах. Конечно, это далеко не все, что можно узнать о GitHub — включая и то, как принимать действия других людей в ваших репозиториях посред- ством pull-запросов. Эта тема, наряду с другими расширенными возможностями
GitHub, выходит за рамки книги.
262
Глава 12.Git и организация программных проектов
1 ... 23 24 25 26 27 28 29 30 ... 40
Клонирование существующего репозитория GitHub
Также возможно и обратное: создать новый репозиторий на GitHub и клонировать его на ваш компьютер. Создайте новый репозиторий на веб-сайте GitHub, но на этот раз установите флажок
Initialize this repository with a README
Чтобы клонировать этот репозиторий на локальный компьютер, перейдите на стра- ницу репозитория на GitHub и щелкните на кнопке
Clone или
Download
; откроется окно с URL-адресом вида https://github.com/<пользователь_github>/wizcoin.git.
Используйте URL-адрес своего репозитория с командой git clone
, чтобы загрузить его на ваш компьютер:
C:\Users\Al>git clone https://github.com/<пользователь_github>/wizcoin.git
Cloning into 'wizcoin'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
Теперь вы сможете сохранять и отправлять изменения, используя этот репозиторий
Git, точно так же, как если бы он был создан командой git init
Команда git clone также пригодится в том случае, если ваш локальный репозиторий оказался в состоянии, когда вы просто не знаете, что с ним делать и как отказать- ся от последних изменений. И хотя такое решение далеко не идеально, вы всегда можете сохранить копию файлов в вашем рабочем каталоге, удалить локальный репозиторий и воспользоваться командой git clone для повторного создания репозитория. В такой ситуации порой оказываются даже опытные разработчики, и это легло в основу шутки https://xkcd.com/1597/.
Итоги
Системы контроля версий спасают программистов от многих бед. Сохранение кода упрощает анализ хода работы над проектом и в некоторых случаях позволяет отменять нежелательные изменения. Изучение основ работы с системой контро- ля версий — такой как Git — безусловно, сэкономит ваше время в долгосрочной перспективе.
Проекты Python обычно состоят из нескольких стандартных файлов и папок, и модуль cookiecutter помогает создать заготовки кода для многих таких фай- лов. Они станут первыми из сохраненных в вашем локальном репозитории Git.
Папка, содержащая весь этот контент, называется рабочим каталогом или папкой
проекта.
Итоги
263
Git отслеживает файлы в рабочем каталоге. Каждый файл может существовать в одном из трех состояний: сохраненном (или чистом), измененном или индекси- рованном. Командная строка Git поддерживает ряд команд (например, git status или git log
) для просмотра этой информации, но вы также можете воспользоваться сторонними средствами с графическим интерфейсом.
Команда git init создает новый пустой репозиторий на вашем локальном компью- тере. Команда git clone копирует репозиторий с удаленного сервера (например, с популярного веб-сайта GitHub). После создания репозитория вы можете восполь- зоваться командами git add и git commit для сохранения изменений в репозитории и командой git push для отправки коммитов в удаленный репозиторий GitHub.
В этой главе я рассказал и о командах для отмены внесенных изменений. Отмена позволяет вернуться к более ранней версии ваших файлов.
Git — сложный инструмент со множеством возможностей, и эта глава знакомит вас только с основами системы контроля версий. Существует множество ресурсов для изучения расширенной функциональности Git. Я рекомендую две бесплатные книги, которые можно найти в интернете: «Pro Git» Скотта Чаркона (Scott Charcon)
(https://git-scm.com/book/en/v2)
1
и «Version Control by Example» Эрика Синка (Eric
Sink) (https://ericsink.com/vcbe/index.html).
1
Существует версия этой книги на русском языке: http://git-scm.com/book/ru/v2. — Примеч.
ред.