On branch master nothing to commit working tree clean как исправить

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

Запись изменений в репозиторий

Итак, у вас имеется настоящий 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 будут рассмотрены ветки и ссылки более детально.

Предположим, вы добавили в свой проект новый файл, простой файл 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 <file>..." 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, вы можете выполнить следующее:

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

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git restore --staged <file>..." 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 <file>..." to unstage)

    new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." 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 <file>..." 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 <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." 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 <file>..." 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 <file>..." to unstage)

    modified:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." 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 <file>..." to unstage)

    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." 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:

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

Примечание

Редактор устанавливается переменной окружения 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 <file>..." to update what will be committed)
  (use "git checkout -- <file>..." 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 <file>..." to update what will be committed)
  (use "git checkout -- <file>..." 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 <file>..." to unstage)

    deleted:    PROJECTS.md

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

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

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

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

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

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

В отличие от многих других систем контроля версий, 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 <file>..." to unstage)

    renamed:    README.md -> README

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

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

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

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

  • Создание репозитория git
  • Создание первого коммита

Создание репозитория

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

> mkdir repo

Теперь перейдем в этот каталог.

>cd repo

Создадим в нем пустой git репозиторий.

> git init

Создание первого коммита

Если мы посмотрим на список коммитов, которые были отправлены в репозиторий, то увидим, что он пустой – это правильно, т.к. мы пока только создали репозиторий и ничего ещё туда не отправляли.

> git log
fatal: your current branch 'master' does not have any commits yet

Для просмотра состояния рабочего каталога воспользуемся командой git status.

> git status
On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

Создадим в нашем каталоге пустой файл.

> touch README.md

Теперь, если мы выполним команду git status, то увидим, что в нашем каталоге появился один неотслеживаемый файл: README.md.

> git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README.md

nothing added to commit but untracked files present (use "git add" to track)

Добавим, созданный файл в stage. Stage (или cache) – это хранилище для файлов с изменениями, информация о которых попадет в единый коммит. Stage является элементом архитектуры трех деревьев, на базе которой построен git, более подробно смотрите здесь. Для добавления файла README.md в stage необходимо воспользоваться командой git add.

> git add README.md

Если изменение было произведено в нескольких файлах, и мы хотим их все отправить в stage, то вместо имени файла поставьте точку.

Выполним git status для того, чтобы посмотреть на то, что сейчас происходит в нашем каталоге.

> git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   README.md

Как видно, в stage был добавлен один файл с именем README.md и теперь представленный набор изменений готов к отправке в репозиторий – т.е. к коммиту. Сделаем это.

> git commit -m "[create repository]"
[master (root-commit) 500067c] [create repository]
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md

Проверим статус каталога.

> git status
On branch master
nothing to commit, working tree clean

Как видно с момента последнего коммита никаких изменений в рабочем каталоге не производилось.

Теперь взглянем на список коммитов.

> git log
commit 500067cc0b80643d38e2a24e9e0699031ada6be3
Author: Writer <writer@someserver.com>
Date:   Mon Feb 12 22:51:14 2018 +0500

    [create repository]

Из приведенной информации видно, что был отправлен один коммит, который имеет ID: 500067cc0b80643d38e2a24e9e0699031ada6be3, более подробно об идентификаторах будет рассказано в следующих уроках. Автор данного коммита Writer, он (коммит) был создан Mon Feb 12 22:51:14 2018 +0500, с сообщением:  [create repository]. Это довольно подробная информация, когда коммитов станет много, такой формат вывода будет не очень удобным, сокращенный вариант выглядит так.

> git log --oneline
500067c [create repository]

Подведем небольшое резюме вышесказанному.

Создание пустого репозитория.

> git init

Добавление файлов в stage.

> git add filename

Создание коммита.

> git commit -m “message”

Просмотр статуса каталога.

> git status

Просмотр коммитов в репозитории.

> git log

Просмотр коммитов в репозитории с сокращенным выводом информации.

> git log --oneline

Отличный курс по git  делают ребята из GeekBrains, найдите в разделе “Курсы” курс Git. Быстрый старт”, он бесплатный!

<<< Часть 4. Архитектура Git   Часть 6. Просмотр информации по коммитам >>>

When you have added all of the changes in a repository to a commit, the Git command line will classify your working directory as “clean”. You’ll see this description if you run git status to check the status of your repository.

In this guide, we’re going to discuss what the “nothing to commit, working directory clean” message means. We’ll also discuss why you see this message even when you have made changes to your local repository that have not been pushed to a remote repository.

Get offers and scholarships from top coding schools illustration

Find Your Bootcamp Match

  • Career Karma matches you with top tech bootcamps
  • Access exclusive scholarships and prep courses

Select your interest

First name

Last name

Email

Phone number

By continuing you agree to our Terms of Service and Privacy Policy, and you consent to receive offers and opportunities from Career Karma by telephone, text message, and email.

nothing to commit, working directory clean

Git is a distributed version control system. This means you can maintain multiple separate copies of a repository.

Because multiple copies of a repository can exist, different developers can work on their own version of a repository locally. Then, when they have finished making a change, they can push their changes to the main version of the repository.

The “nothing to commit, working directory clean” message tells us all of the changes we have made to a Git repository are committed. This means the current state of our project folder is exactly the same as that of the last commit.

When you add, remove, or delete a file, this message will change. You’ll see a list of the files you have changed and a description of whether you have created, modified, or deleted that file.

Let’s run the git status command on a repository to which we have made no changes:

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

The git status command tells us we are viewing the “master” branch. The command also tells us we have not made any changes to our repository since the last commit.

If you have set up your project with a remote, you should see a message telling you whether all of the changes you have made to your repository have been pushed to the remote. This is the “Your branch is up to date” message above.

nothing to commit, working directory clean Error

The “nothing to commit, working directory clean” message may appear in error. This happens if you have not set a branch on your repository upstream.

Let’s create a local copy of our demo Git repository, ck-git. To start, we’re going to initialize a new repository, add that repository as a remote, and pull the contents of the repo:

git init
git remote add origin https://github.com/career-karma-tutorials/ck-git
git pull origin master

These commands retrieve the code from the career-karma-tutorials/ck-git repository on GitHub. Next, let’s modify a file and add it to a commit:

echo "This project is a work in progress." >> README.md
git add README.md
git commit -m "docs: Add work in progress notice"

We have just added a line of text to the README.md file. Then, we added the README.md file into the staging area and all the files in the staging area to a commit.

Let’s run git status to make sure our changes have been made:

On branch master

nothing to commit, working tree clean

This command tells us that our working tree is clean even though we’ve made changes to our remote repository. There is no message to tell us that our local repository is different to our remote repository.

This is because we have not told Git to compare our local repository to our remote repository. This occurred because we did not clone our repository. We initialized a new repository and pulled the contents from an existing repository to our local machine.

We can fix this error by setting an upstream remote branch:

git branch -u origin/master

This tells Git to compare the contents of your current branch to the “master” branch on the “origin” remote. Now, let’s run the git status command again:

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

nothing to commit, working tree clean

The Git command line informs us that our local repository contains one more commit than our remote repository. To make this message go away, we must push our changes using the git push command:

Now that we’ve pushed our changes, our local and remote repositories will be the same:

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

We’ve fixed the issue!

Conclusion

The Git “nothing to commit, working directory clean” message tells us that we have not made any changes to our repository since the last commit.

If this message appears and the contents of your remote repository are different to your local repository, check to make sure you have correctly set up an upstream branch.

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

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

1. Основные термины Git

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

Индекс — это часть локального репозитория (ЛР), хранящая не зафиксированные с помощью команды git add изменения файлов. Еще ее называют областью подготовки файлов. Эту область можно сравнить с черновиком (промежуточным этапом), из которого разработчик по завершению своей работы выбирает, какие изменения нужно зафиксировать (добавить в тот или иной коммит).

Индексирование — добавление изменений в индекс. После этой операции файлы попадают под версионный контроль Git (если они для него были незнакомы). Если файлы уже были под контролем Git, то их изменения просто попадают очередной раз в черновик, чтобы потом быть зафиксированными.

Коммит (commit) — фиксация изменений, взятых из индекса. Это действие заносит изменения в репозиторий Git. Его можно сравнить со слепком текущего состояния вашего ЛР. Вы берете из черновика (индекса) нужные изменения и коммитите текущее состояние файлов и папок. Это действие похоже на создание точки восстановления в Windows. Каждый коммит также является итогом вашей работы.

Закоммитить/коммитить — зафиксировать изменения, сделать слепок текущего состояния файлов и папок.

Клонирование репозитория (clone) — процесс скачивания копии УР к себе на компьютер. При этом создание ЛР происходит автоматически, без явного ввода git init.

Подтягивание изменений (pull) — работать с одним УР могут как разные люди, так и один разработчик с разных устройств. При такой ситуации, перед тем, как приступить к изменению файлов, необходимо начинать свою работу с получения всех коммитов, которые есть на УР. Коммиты в ЛР всегда должны совпадать с коммитами на УР, а иначе будут проблемы, решение которых мы рассмотрим в следующей статье.

Если упрощенно объединить все, что было сказано в этом разделе, то процесс работы с Git сводится к следующим шагам:

Ветка (branch) — это одно из направлений развития вашего проекта. Git позволяет вести параллельную работу (в разных ветках), в рамках одного репозитория, над одними и теми же файлами. У каждой ветки есть имя. Имя основной ветки — master (main).

Например, вам необходимо реализовать какую-то фичу (или исправить баг в коде) и чтобы не испортить уже работающую программу, которая находится в основной ветке, вы можете создать дополнительную, где будет вестись ее разработка. Таким образом, вы ничего не сломаете в основном коде, а если фича (или исправление ошибок) окажется удачной, то ваши наработки можно будут перенести в master (сделать слияние). Таких веток можно создавать сколько угодно. При необходимости удалять, объединять между собой.

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

2. Создание локального репозитория

В предыдущей статье, с помощью команды git init, мы создали ЛР — место на компьютере для хранения файлов и отслеживания в них любых изменений. Именно с этого шага начинается работа с Git.

Выполните команду git init в корне вашего проекта, как показано в образце ниже, если не делали этого ранее:


D:JavaStartJava
> git init
Initialized empty Git repository in D:/Java/StartJava/.git/

В результате, в папке StartJava появится скрытая директория .git (с точкой в начале), где и будет в дальнейшем храниться информация обо всех изменениях, сделанных в репозитории.

3. Связывание удаленного и локального репозитория

На следующем шаге свяжем ЛР с УР, чтобы код, хранящийся на вашем компьютере, можно было размещать на GitHub (или брать с него).

URL на ваш УР скопируйте, зайдя на github.com и выбрав протокол, который вы настроили для взаимодействия с GitHub в прошлой статье.

В итоге команда будет выглядеть так (используйте ссылку на свой репозиторий!):


> git remote add origin https://github.com/ichimax/startjava2.git
  • git — используется приложение git
  • remote — управляет удаленным репозиторием
  • add — добавляет информацию об УР в ЛР
  • origin — общепринятый псевдоним для URL УР
  • https://github.com/ichimax/startjava2.git — ссылка на УР

Эту длинную команду можно трактовать так: Git, добавь к себе информацию о связи между УР github.com/ichimax/startjava2.git, которому я хочу дать псевдоним origin, с ЛР.

Проверим, что получилось, введя git remote -v:


> git remote -v
origin  https://github.com/ichimax/startjava2.git (fetch)
origin  https://github.com/ichimax/startjava2.git (push)

Взаимосвязь установлена успешно: напротив псевдонима origin размещается ссылка на УР.

4. Состояние репозитория

Одной из самых популярных и простых команд, которая используется постоянно, является git status. Она показывает в каком состоянии в текущий момент находится ЛР (какие файлы были изменены, что нового добавилось и т. д.).

Файлы в репозитории могут находиться в следующих состояниях:

  • не отслеживаемые (untracked) — находящиеся в ЛР, но еще не добавленные в индекс (под версионный контроль). Это могут быть новые файлы
  • индексированные (staged) — новые файлы, добавленные впервые в индекс
  • зафиксированные (committed) — попавшие в коммит
  • измененные (modified) — модифицированные после коммита

Файлы все время меняют свое состояние. Их жизненный цикл повторяется снова и снова.

Введем в консоли git status:


D:JavaStartJava (master)
> git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        about.txt
        src/

nothing added to commit but untracked files present (use "git add" to track)

Команда вывела сообщение, которое означает, что Git видит src и about.txt, но не отслеживает, вносимые в них изменения. В связи с этим, он предлагает добавить файлы в индекс. Тут следует запомнить одну важную деталь: добавленные в репозиторий новые файлы не попадают сразу под версионный контроль. Git их просто видит, но не фиксирует в них изменения.

Если бы файлы сразу попадали в индекс, то тогда любые случайные файлы (с настройками, class, временные и т. д.) попадали бы под версионный контроль — был бы хаос. Git защищает нас от этого, требуя, чтобы мы сами контролировали этот процесс.

А теперь разберем все, что вывела команда git status:

  1. On branch master — [находимся] в ветке master
  2. No commits yet — нет коммитов [которые можно запушить]
  3. Untracked files — [имеются] неотслеживаемые файлы
  4. (use «git add <file>…» to include in what will be committed) — используйте «git add <file> …» для включения файлов в коммит, состояние [изменения] которых нужно зафиксировать.
    Git увидел, что в ЛР есть не занесенные в индекс и незафиксированные изменения. Т.к. он src и about.txt видит впервые, то для него они по умолчанию являются измененными. Поэтому Git предлагает закоммитить (зафиксировать) их текущее состояние, чтобы уже от него учитывать все последующие изменения.
  5. nothing added to commit but untracked files present (use «git add» to track) — ничего не добавлено в коммит, но присутствуют не отслеживаемые файлы (для отслеживания используйте «git add»)

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

5. Добавление файлов в индекс

Добавим файлы в индекс, запустив команду git add . (с точкой в конце), а затем снова выполним git status.


D:JavaStartJava (master)
> git add .

D:JavaStartJava (master)
> git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   about.txt
        new file:   src/MyFirstApp.java

Точка, идущая после add означает, что в индекс будут добавлены все изменения, которые были сделаны в текущей папки и ее подпапках.

Если вам требуется добавить вообще все изменения, которые были сделаны в репозитории, начиная с его корня, то для этого нужно использовать параметр -A вместо точки.

В выводимом сообщении произошли изменения: src и about.txt перестали быть untracked, а позеленели и теперь находятся в индексе.

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

Ситуацию с игнорированием файлов мы разберем ниже, когда будем говорить про .gitignore.

6. Коммит файлов

Осталось зафиксировать изменения из индекса с помощью команды commit. Это можно сделать двумя основными способами.

6.1. Первый способ

Напишем в консоли команду git commit. Откроется указанный ранее при настройке (установке) текстовый редактор. В нашем случае откроется новая вкладка, содержащая следующий шаблонный текст:

При этом в консоли отобразится текст «hint: Waiting for your editor to close the file…» (благодаря параметру —wait, который мы установили в предыдущей статье).

Текст во вкладке COMMIT_EDITMSG частично напоминает то, что выводил git status. В начале каждой строки идет символ #, говорящий о том, что текст закомментирован и несет только информационную нагрузку. На него можно не обращать внимание (или удалить полностью), он все равно не попадет в коммит или его описание.

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

В многострочном описании первая строка является заголовком, включающим в себя общий смысл проделанных изменений. Она не должна превышать 50 символов и не имеет точку в конце. Далее обязательно должна идти пустая строка. А затем уже идет перечисление конкретных изменений.

Из заголовка видно, что данный коммит является первым (root-commit), т. к. в нем присутствует слово «Инициализация». Далее указаны пункты с теми изменениями, которые мы внесли в файлы проекта.

Сохраните, а затем закройте вкладку. Git создаст коммит, добавит к нему описание и выведет о нем информацию в консоль:


D:JavaStartJavasrc (master)
> git commit
[master (root-commit) 1e36e0f] Инициализация проекта
 2 files changed, 6 insertions(+)
 create mode 100644 about.txt
 create mode 100644 src/MyFirstApp.java

Сообщение содержит следующие данные о коммите:

  • master — для какой ветки он был выполнен
  • root-commit — является корневым (первым) коммитом
  • 1e36e0f — уникальный идентификатор (контрольная сумма)
  • Инициализация проекта — описание (заголовок). При этом другие пункты — не отображаются
  • 2 files changed — количество измененных файлов
  • 6 insertions(+) — количество добавленных в файлах строк
  • create mode 100644 — права доступа к файлам в Unix-стиле

6.2. Второй способ

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

Изменим название файла about.txt на README.md («Прочитай меня») и внесем в него изменения. В этом файле принято размещать описание проекта, который находится в репозитории.

GitHub позволяет форматировать текст в файлах, используя облегчённый язык разметки Markdown. Маркдаун-файлы как раз имеют расширение md.

Изменим имя файла с помощью Git и отобразим результат:


D:JavaStartJava (master)
> git mv about.txt README.md && ls
README.md  src/

Откроем README.md, написав в консоли его имя, и жмем Enter. Затем, используя маркдаун, внесем в него следующие изменения:


# [StartJava](https://topjava.ru/startjava) — курс на Java для начинающих

## Используемые на курсе инструменты и технологии

1. Java
1. Git/GitHub
1. Командная строка
1. Sublime Text
1. Intellij IDEA
1. SQL
1. PostgreSQL
1. psql

Отобразим данный файл в браузере. Для этого необходимо нажать Ctrl + Shift + P, написать preview и выбрать первую строку с надписью «MarkDown Preview: Preview in Browser» (при этом пакет Markdown Preview должен быть установлен):

Откроется страница в браузере с отформатированным текстом:

Далее проверим статус файла (вывод дан в сокращенном виде):


D:JavaStartJava (master)
> git status
Changes to be committed:
        renamed:    about.txt -> README.md

Changes not staged for commit:
        modified:   README.md

Видим, что Git сам переименовал about.txt в README.md, а также пометил README.md как измененный.

Добавим все изменения в индекс, выполнив команду git add README.md с явным указанием имени измененного файла.

Перед тем как выполнить коммит, посмотрим, какие изменения мы хотим зафиксировать. Для этого пишем git status -v (вывод дан в сокращенном виде):


> git status -v

Changes to be committed:
        new file:   README.md
        deleted:    about.txt

diff --git a/README.md b/README.md
+++ b/README.md

+# [StartJava](https://topjava.ru/startjava) — курс на Java для начинающих
+
+## Используемые на курсе инструменты и технологии
+
+1. Java
+1. Git/GitHub
+1. Командная строка
+1. Sublime Text
+1. Intellij IDEA
+1. SQL
+1. PostgreSQL
+1. psql

diff --git a/about.txt b/about.txt
--- a/about.txt
-Интенсив StartJava - программирование на Java для начинающих!

На этот раз информации отобразилось значительно больше. В сообщении используется результат работы команды diff, которая сравнивает текущее состояние файла с последним коммитом и отображает все изменения.

Плюсом обозначаются добавленные в файл строки (выделены зеленым), а минусом удаленные (красные).


> git commit -m "Переименовал about.txt в README.md и внес в него описание проекта"
[master 39ba195] Переименовал about.txt в README.md и внес в него описание проекта
 2 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 README.md
 delete mode 100644 about.txt

Очень важно запомнить, что текст к коммиту (описание) должен максимально точно и кратко отражать те изменения, которые были сделаны. Не пишите в него бессмыслицу, и не копируйте один и тот же текст из предыдущих коммитов.

В итоге мы имеем еще один коммит. В консоли отобразился уже знакомый нам текст. В нем новой для нас является информация об удаленном файле. Остальную часть сообщения мы уже разбирали.

В каких случаях и как часто необходимо делать коммит:

  • вы закончили создание нового функционала
  • вы завершили запланированное исправление ошибок в коде
  • в конце рабочего дня

Дополнительные правила создания коммита смотрите по ссылке.

7. Список коммитов

Чтобы посмотреть список (историю) всех имеющихся коммитов, воспользуемся командой git log (1, 2):


> git log
commit 39ba195cf96f555aaf2d9f0a2f3ffcfb37e0c536 (HEAD -> master)
Author: ichimax <myEmail>
Date:   Thu Sep 22 16:31:55 2022

    Переименовал about.txt в README.md и внес в него описание проекта

commit 1e36e0f6daf70d936627c444f8cb082bfffb9b17
Author: ichimax <myEmail>
Date:   Thu Sep 22 13:02:17 2022

    Инициализация проекта

    - добавил файл с описанием проекта
    - добавил реализацию первого класса
(END)

Команда отобразила информацию о каждом коммите, расположив их в обратном порядке: последний коммит всегда будет вверху.

Вывод заканчивается строкой с надписью (END), сообщающей, что список коммитов выведен в полном объеме. Для выхода из режима отображения — нажмите клавишу q (язык раскладки должен быть английским).

Информация к коммиту в себя включает следующие метаданные:

  • уникальный идентификатор коммита по которому можно его найти (длинный набор букв и цифр)
  • данные автора коммита, который его создал
  • дату создания коммита
  • краткое описание сделанных изменений

С помощью git log можно выводить информацию о конкретном количестве коммитов, а также видеть все изменения, содержащиеся в них:

Параметр -p позволяет отображать изменения (что добавили в файлы, что удалили), а -1 отвечает за количество отображаемых коммитов (в данном случае — один).

Если вам не требуется выводить подробную информацию по каждому коммиту, то можно воспользоваться сокращенным выводом с помощью опции —oneline, которая выводит каждый коммит в одну строку:


> git log --oneline
39ba195 (HEAD -> master) Переименовал about.txt в README.md и внес в него описание проекта
1e36e0f Инициализация проекта

8. Отправка коммитов на удаленный репозиторий

Сейчас оба наших коммита являются локальными — находятся в директории .git у вас на компьютере. Необходимо их загрузить (запушить) на УР на GitHub, используя команду push.

Предварительно введем git status:


> git status
On branch master
nothing to commit, working tree clean

Видим, что коммитить нам нечего, файлов, которые нужно добавить в индекс тоже нет. Выполним пуш, введя команду git push -u origin master:


> git push -u origin master
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 1.17 KiB | 238.00 KiB/s, done.
Total 8 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ichimax/startjava2.git
 * [new branch]      master -> master
branch 'master' set up to track 'origin/master'.

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

После пуша, зайдите на ваш репозиторий на GitHub и убедитесь, что src/MyFirstApp.java и README.md были загружены.

9. Подтягивание изменений с УР

А теперь представим ситуацию, что вы работаете с УР на разных компьютерах (на работе и дома). Внеся какие-то изменения в файлы и запушив их, вы идете домой, где планируете вечером еще немного поработать над проектом.

Или возможна другая ситуация, когда над проектом работает команда программистов, каждый из которых вносит изменения в файлы и пушит их на УР.

Дома, вы открываете свой проект и хотите продолжить над ним работу. И тут вам приходит в голову мысль, а как мне получить с УР все изменения, которые сделали как вы, так и другие программисты, чтобы ваш домашний ЛР был в актуальном состоянии?

Для этого в Git предусмотрена команда pull, которая скачивает с GitHub к вам на компьютер все коммиты, которых нет в вашем ЛР.

Для простоты эксперимента внесем изменения прямо на GitHub (да, это возможно) и подтянем их в свой ЛР.

Изменим код в файле MyFirstApp.java на следующий:


public class MyFirstApp {
    public static void main(String[] args) {
        System.out.print("Написано однажды, ");
        System.out.println("работает везде!");
    }
}

Пример того, как это можно сделать на GitHub, включая создание коммита:

Затем подтянем новый коммит в ЛР:


> git pull
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 942 bytes | 40.00 KiB/s, done.
From https://github.com/ichimax/startjava2
   39ba195..b59d871  master     -> origin/master
Updating 39ba195..b59d871
Fast-forward
 src/MyFirstApp.java | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Теперь количество коммитов в ЛР и УР совпадают — ЛР содержит данные в актуальном состоянии. Можно спокойно продолжить работу.

Выполняйте команду git pull всякий раз перед тем, как начинаете работать над своим проектом (пишите код, вносите какие-то изменения). Эта привычка защитит вас от множества проблем.

10. Клонирование репозитория

После того, как ваш (или чей-то) проект оказался на GitHub, любой желающий может скачать его копию с помощью git clone.

Для примера скачаем какой-нибудь другой репозиторий, но не в наш проект, а в любое место на жестком диске:


D:Java
> git clone https://github.com/ichimax/Java-Style-Guide.git
Cloning into 'Java-Style-Guide'...
remote: Enumerating objects: 69, done.
remote: Counting objects: 100% (69/69), done.
remote: Compressing objects: 100% (66/66), done.
Receiving objects:  33% (23/69)
Receiving objects: 100% (69/69), 22.24 KiB | 1.71 MiB/s, done.
Resolving deltas: 100% (19/19), done.

При этом новый ЛР создастся автоматически с уже прописанным УР и будет содержать всю историю изменения проекта.

Зайдем в новый репозиторий и введем уже известные нам команды:


> cd Java-Style-Guide && ls -a && git status && git remote -v
./  ../  .git/  guide.md  README.md
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
origin  https://github.com/ichimax/Java-Style-Guide.git (fetch)
origin  https://github.com/ichimax/Java-Style-Guide.git (push)

11. Игнорирование файлов и папок

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

Давайте поэкспериментируем, создав условия для использования данного файла. Самое простое, что мы можем сделать — это скомпилировать MyFirstApp.java, чтобы в репозитории появился class-файл. Делать это мы уже умеем (если кто-то пропустил, то данная тема разбиралась ранее).


> javac MyFirstApp.java && ls
MyFirstApp.class  MyFirstApp.java

Нужный нам class-файл появился. С этого момента все class-файлы для нас являются «мусорными». Ни при каких обстоятельствах их нельзя включать в коммит, а тем более пушить в удаленный репозиторий.

На GitHub нужно хранить только разные версии ваших файлов к которым в будущем можно вернуться (откатиться). class-файлы нужны только для запуска программ. Для версионного контроля они не представляют никакой ценности.

Создадим .gitignore в корне нашего проекта:


D:JavaStartJava (master -> origin)
> touch .gitignore

Отобразим все файлы и папки:


> tree /F
D:.
│   .gitignore
│   README.md
│
└───src
        MyFirstApp.class
        MyFirstApp.java

Не лишним будут посмотреть статус репозитория:


> git status
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        src/MyFirstApp.class

Репозиторий содержит два новых неотслеживаемых файла. Один из них нужно игнорировать (чтобы Git его даже не отображал).

Для этого откроем .gitignore и пропишем в нем правило (шаблон), которое позволит игнорировать любые class-файлы. Для этого воспользуемся маской и расширением *.class. Эта запись означает, что все файлы (не важно, как они названы), которые имеют расширение class, будут игнорироваться Git. Это максимально универсальный способ, который позволяет не писать явно имя каждого class-файла, который нужно игнорировать.

Если требуется добавить в него папку, которая находится в одной директории с .gitignore, достаточно написать ее имя. Например, .gitignore может содержать следующее:


*.class
*.DS_Store
*.iml
out/
lib/
.idea/

После имени директории можно указывать /, говорящий о том, что это директория, но так делать не обязательно.

В данный файл, по мере изучения Java, мы будем добавлять новые шаблоны. Не скачивайте из интернета универсальные шаблоны с множеством непонятных и не нужных вам записей. Добавляйте в .gitignore правила по мере необходимости.

Снова проверим статус репозитория:


> git status

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

Вуаля, class-файла, как не бывало (при этом он, конечно же, не удалился, а просто не отображается и игнорируется Git).

Осталось проделать привычные действия с новым файлом, которые уже не нуждаются в пояснении:


git add .
git commit -m "Добавил .gitignore с шаблоном *.class"
git push
git log --oneline

12. Список команд

Список команд, разобранных в статье, с кратким описанием.

Заключение

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

Оцените статью, если она вам понравилась!

Понравилась статья? Поделить с друзьями:

Читайте также:

  • On board parity error
  • Omvl ошибка е029 saver
  • Omsi ошибка при запуске приложения 0xc0000906
  • Omsi 2 ошибка fehler bei bereichsprufung
  • Omsi 2 ошибка d3dx9 dll

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии