Как закоммитить все файлы
Перейти к содержимому

Как закоммитить все файлы

  • автор:

git add

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

Процессы сохранения в Git и SVN также отличаются. Коммиты, или «фиксации», в SVN — это операции передачи на централизованный удаленный сервер. Это означает, что для «сохранения» изменений в проекте коммитам SVN необходим доступ в Интернет. Коммиты Git можно создавать и выполнять локально, а затем по мере необходимости отправлять на удаленный сервер с помощью команды git push -u origin main . Различие этих двух методов объясняется фундаментальными отличиями в архитектуре. В Git реализована модель распределенного приложения, а в SVN — модель централизованного приложения. Обычно распределенные приложения более устойчивы, поскольку не имеют единой точки отказа, такой как централизованный сервер.

Чтобы сохранить снимок текущего состояния для проекта Git, используется комбинация команд git add, git status и git commit.

В Git имеется дополнительный механизм сохранения, который называется «stash». Stash — это временная область для хранения изменений, не готовых к коммиту. Команда stash работает с рабочим каталогом (первым из трех деревьев) и имеет множество вариантов применения. Подробнее см. на странице с описанием команды git stash.

Репозиторий Git можно настроить на игнорирование определенных файлов или каталогов. В этом случае Git не будет сохранять изменения в игнорируемом контенте. В Git имеется несколько способов настройки для управления списком игнорирования. Более подробно настройка игнорирования в Git рассматривается на странице git ignore.

git add

Команда git add добавляет изменение из рабочего каталога в раздел проиндексированных файлов. Она сообщает Git, что вы хотите включить изменения в конкретном файле в следующий коммит. Однако на самом деле команда git add не оказывает существенного влияния на репозиторий: изменения регистрируются в нем только после выполнения команды git commit.

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

Порядок действий

Команды git add и git commit составляют основу рабочего процесса Git. Эти две команды должен изучить и понимать каждый пользователь Git, независимо от модели совместной работы, принятой в его команде. Эти команды используются для записи версий проекта в историю репозитория.

Работа над проектом ведется по стандартной схеме «редактирование — индексирование — коммит». Сначала вы редактируете файлы в рабочем каталоге. Когда вы будете готовы сохранить копию текущего состояния проекта, вы индексируете изменения командой git add . Затем вы вызываете команду git commit , которая добавляет проиндексированный снимок состояния в историю проекта. Для отмены коммита или проиндексированного снимка состояния используется команда git reset.

Для полноценного процесса совместной работы в Git помимо git add и git commit необходима третья команда — git push. git push используется для отправки подтвержденных изменений в удаленные репозитории для совместной работы, чтобы к набору сохраненных изменений могли получить доступ другие участники команды.

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

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

$ git add README

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

$ cat .gitignore *.[oa] *~

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

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

$ git commit

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

Примечание

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

$ git rm --cached README

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

$ git rm log/\*.log

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

$ git rm \*~

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

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

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

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

$ git mv file_from file_to

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

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

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

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

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

В чем разница между git add ., add -A, add -u и add *?

Есть разные способы добавить все измененные файлы в индекс репозитория Git. В чем разница и зачем столько способов?

git add . git add * git add -u git add -A git add --all git add --no-all 

Отслеживать
Nick Volynkin
задан 25 июн 2015 в 3:38
Nick Volynkin ♦ Nick Volynkin
33.9k 25 25 золотых знаков 130 130 серебряных знаков 222 222 бронзовых знака
ассоциация: stackoverflow.com/questions/572549/…
– user181100
25 фев 2017 в 16:36

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Давайте обозначим категории файлов, которые вообще можно добавлять. Будем использовать те же обозначения, что и в выводе команды git status -s :

M — (modified) отслеживаемые, изменились с прошлого коммита, еще не добавлены
D — (deleted) отслеживаемые, удалены после прошлого коммита, еще не добавлены
? — (untracked) неотслеживаемые, не запрещены к добавлению
! — (ignored) неотслеживаемые, запрещены к добавлению (например, в .gitignore )

Параметры и аргументы

Первое различие — в том, что . — это путь (аргумент), а всё остальное — параметры. Те и другие не исключают друг друга и возможны их сочетания.

Использование абсолютных :/ и относительных . путей с командой add

Путь . обозначает текущую директорию, т.е. ту, в которой была запущена команда.

Начиная с Git версии 2.0, поведение команды add приведено в соответствие с поведением commit и других комманд. Теперь . обозначает не всю рабочую область (working tree), а текущий путь в этой области.

Таким образом, если вы выполняете команду add не в корневой директории проекта (той, где лежит .git/ ), то будет обработано содержимое только текущей директории.

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

# работает одинаково из любой директории, добавляет всю рабочую область git add :/ # путь относительно корневой директории git add :/path/to/files/ # работает только в текущей директории cd test git add . # эквивалентно этому: git add :/test # путь относительно текущей директории cd test git add ./path # эквивалентно этому: git add :/test/path 

Если не указан никакой путь к добавляемым файлам, то большинство команд работает во всей рабочей области, а git add и git add —no-all просто не работают.

Сводная таблица

сводная таблица

О функционале команд подробно

git add . git add '*' 

Git версии 2.0+ просматривает текущую папку и добавляет файлы M , D , ? .
Git версии 1.х просматривает всю рабочую область и добавляет файлы M , D .

Если ‘*’ дается в кавычках, то обрабатывать его будет Git и это эквивалентно git add . . Исключение: из-под cmd.exe git add ‘*’ не сработает, используйте git add . или git add * .

git add --no-all :/ git add --ignore-removal :/ 

Эта команда в Git v. 2.0+ работает как git add . в Git v. 1.x, то есть добавляет измененные и новые файлы M , ? во всей рабочей области. Для этой команды обязательно указывать путь.

git add --no-all . #добавляет измененные и новые файлы в *текущей директории* git add --no-all path1/ path2/ # добавляет измененные и новые файлы в путях *относительно текущей директории* 
git add -u git add -update 

Git обновляет (update) статус уже отслеживаемых файлов т.е. M , D .

git add -A git add --all git add --no-ignore-removal 

Эти варианты эквивалентны и добавляют M , D , ? .

Без точки — из всей рабочей области:

git add -A = git add -A :/ = git add :/ + git add -u

С точкой — только текущий путь:

git add -A . = git add . + git add -u .

 git add * 

Этот синтаксис лучше не использовать, и вот почему:

При этой команде shell (или bash или другая командная оболочка) просматривает рабочую область и отдает Git список файлов на добавление. Система сработает таким образом, что будут найдены абсолютно все не-скрытые файлы, находящиеся в заданном корне. Вы можете посмотреть на этот список, выполнив echo * . ( Исключение: из-под cmd.exe git add * работает так же как git add ‘*’ на shell/bash. )

Произойдет следующее (здесь мы видим сразу несколько причин не использовать add * ):

  1. Добавятся не изменившиеся с прошлого коммита файлы. Git спокойно и молча «прожует» этот запрос, не влияющий на индекс.
  2. Будут добавлены в индекс файлы в не-скрытых папках M , ? .
  3. Не будут добавлены файлы в скрытых папках. .M , .?
  4. Не будут добавлены удаленные файлы D .
  5. Если будут захвачены игнорируемые файлы ! , то будет попытка их добавить. Git отменит всю операцию и покажет сообщение об ошибке.

Зачем столько способов

Разнообразие параметров ( -u , -A , —no-all ) нужно для того, чтобы можно было добавлять разные группы файлов. Конкретно —no-all . было добавлено для того, чтобы реализовывать старое поведение add . в версиях 1.х.

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

Тонкости в использовании . и :/ нужны для того, чтобы каждую команду можно было выполнять как на всю рабочую область, так и на конкретную подпапку.

Полезные команды для работы с Git

Работа с Git через терминал — это обязательная часть практики каждого современного фронтенд-специалиста. Однако, для начинающих это может показаться сложным. Чтобы упростить процесс обучения, мы собрали для вас все самые необходимые команды, которые пригодятся в работе с Git на первое время.

Первоначальная настройка Git

Работа с любой программой всегда начинается с её настройки. Git можно настроить один раз и менять что-то только по мере необходимости.

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

git config --global user.name

Установка адреса электронной почты. Обратите внимание, что адрес должен совпадать с тем, на который зарегистрирован аккаунт в Гитхабе.

git config --global user.email mail@gmail.com

Установка текстового редактора, в котором будут открываться файлы для решения конфликтов.

git config --global core.editor editor

С помощью команды git config —list можно посмотреть список всех установленных настроек.

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

Для клонирования репозитория нужно ввести команду git clone и указать его адрес. Репозиторий клонируется в текущую выбранную папку в консоли.

Работа с изменениями

Любая работа с изменениями начинается с получения последней версии удалённого репозитория. Получить последнюю версию можно с помощью команды git pull . Будьте внимательны, вызов этой команды сотрёт все незафиксированные изменения.

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

Чтобы добавить отслеживание новых файлов, необходимо использовать команду git add для добавления нескольких файлов по имени.

В случае если у вас много файлов для добавления, можно воспользоваться командой git add . , которая добавляет отслеживание для всех новых файлов из текущей директории. А команда git add -A добавляет ещё и удалённые файлы, не только из текущей директории, но и из всего локального репозитория.

Помимо добавления файлов, их также необходимо удалять. Для этого существует команда git rm , которая удаляет файлы по их имени.

После того как добавлены все новые и удалены старые файлы, можно делать фиксацию изменений. Фиксация изменений или коммит, очень важна, так как до выполнения этой команды ваши локальные изменения никуда не запишутся. Чтобы добавить коммит, необходимо ввести команду git commit -m «Комментарий к коммиту» .

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

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

По умолчанию, эта команда удаляет только из индекса. А команда git reset —hard безвозвратно удаляет незафиксированные текущие изменения из локального репозитория и из индекса.

Поскольку все вышеописанные действия производятся в локальной копии репозитория, эту копию необходимо отправить на сервер, чтобы другие участники процесса смогли получить актуальную версию. Для этого есть команда git push , которая отправляет все зафиксированные изменения на удалённый репозиторий.

Работа с ветками

Работая с Git, приходится постоянно создавать и перемещаться по веткам.

Команда git checkout -b branch-name создаст ветку с указанным именем и автоматически переключится на неё.

После создания ветку можно отправить на сервер с помощью команды git push origin branch-name .

Аналогично можно забрать себе на компьютер ветку с удалённого репозитория командой git checkout origin/branch-name -b branch-name .

Чтобы не хранить названия веток в памяти или не искать названия веток, существуют две специальные команды, которые позволяют посмотреть все существующие ветки локального репозитория git branch или все существующие ветки удалённого репозитория git branch -r .

Переключиться на любую локальную ветку можно с помощью команды git checkout branch-name .

Прочее

После работы в репозитории могут оставаться различные ненужные, неотслеживаемые файлы и прочий мусор. Чтобы удалить всё лишнее, воспользуйтесь командой git clean -f -d .

Больше статей

  • Как склеить коммиты и зачем это нужно
  • Шпаргалка по Git
  • Как работать с GitHub в большой команде

«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

Читать дальше

5 частых ошибок при работе с Git

5 частых ошибок при работе с Git

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

  • 27 августа 2023

Работа с Git через консоль

Работа с Git через консоль

Задача: форкнуть репозиторий в GitHub, создать ветку и работать с кодом.

Сразу появляется много вопросов — что такое GitHub, какие для этого нужны команды, зачем, а главное, как всем этим пользоваться? Давайте разберёмся.

Когда мы пишем код, мы постоянно туда что-то добавляем, удаляем, и иногда всё может ломаться. Поэтому перед любыми изменениями стоит сделать копию проекта. Если собирать проекты в папки с именами проект1 , проект1_финал и проект2_доделка , вы быстро запутаетесь и точно что-нибудь потеряете. Поэтому для работы с кодом используют системы контроля версий.

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

Git — самая популярная система контроля версий. С Git можно работать через командную строку (или терминал). В каждой системе своя встроенная программа для работы с командной строкой. В Windows это PowerShell или cmd, а в Linux или macOS — Terminal. Вместо встроенных программ можно использовать любую другую — например, Git Bash в Windows или iTerm2 для macOS.

Как работает терминал: мы вводим команду и получаем ответ компьютера — или всё получилось, или где-то ошибка, или нужно ввести что-то ещё — например, пароль. Поэтому большая часть этой инструкции состоит из команд для терминала. Сначала будет непривычно, но вам понравится.

Но давайте по порядку — установим Git на компьютер.

  • 7 августа 2023

GitHub Desktop: обзор и первая настройка

GitHub Desktop: обзор и первая настройка

Самая короткая инструкция о том, как сохранить файлы в GitHub и ничего не сломать. И самое главное — никакой консоли, всё через окошки и с помощью мышки. Для этого используем GitHub Desktop.

Внимание! GitHub Desktop не работает на Windows 7×32, поэтому если у вас эта версия системы, обновитесь до Windows 10 или воспользуйтесь программой GitKraken.

В этой статье идёт рассказ о системах контроля версий. Если вы совсем ничего о них не знаете, прочитайте статьи «Словарь терминов для Git и GitHub» и «Введение в системы контроля версий», чтобы понять терминологию и разобраться, зачем мы вообще это делаем.

  • 7 августа 2023

Как склеить коммиты и зачем это нужно

Как склеить коммиты и зачем это нужно

Когда вы открываете пулреквест и ваш код смотрят и комментируют другие, бывает нужно что-то исправить. Обычно такие изменения мы комментируем сообщением вроде «Увеличил шрифт на 2px » или «Поменял оттенок фона в шапке». Такие маленькие изменения интересны, только пока они в пулреквесте. Ревьювер (человек, который смотрит ваш код), может легко узнать, что и когда вы изменили, а не читать весь diff заново, а вы можете легко откатить коммит, если он не нужен. Но когда приходит время вливать пулреквест, эти маленькие коммиты теряют свою ценность. Поэтому лучше их склеить в один.

  • 14 июня 2023

Основные команды для работы с Git

Основные команды для работы с Git

Работа с Git через терминал — это обязательная часть практики фронтендера. Однако для начинающих разработчиков этот инструмент может показаться сложным. Чтобы вам было проще учиться, мы собрали основные команды для работы с Git.

☝ В некоторых командах мы будем писать URL-адрес удалённого репозитория и название проекта в квадратных скобках, вот так — [ссылка на удалённый репозиторий] . Мы делаем это только для наглядности. Вам квадратные скобки ставить не нужно.

  • 22 февраля 2023

Как бесплатно залить сайт на GitHub Pages

Как бесплатно залить сайт на GitHub Pages

Допустим, вы сделали какой-то проект, например, собрали себе портфолио по шаблону, и теперь хотите выложить его в интернет. Если вы использовали только HTML и CSS, то необязательно платить деньги, чтобы загрузить сайт куда-то. Вы можете бесплатно выложить сайт на сервис GitHub Pages. Всё, что нужно — аккаунт на Гитхабе.

  • 29 ноября 2022

Регистрация на GitHub

Регистрация на GitHub

Создание нового аккаунта на GitHub состоит всего из 10 шагов — и вся регистрация занимает меньше пяти минут.

�� Обратите внимания, что интерфейс Гитхаба регулярно меняется, так что внешне он может отличаться, когда вы читаете эту статью.

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

Ввод почты. На следующем шаге начинается регистрация. Подтвердите свою почту с прошлого шага и нажмите Continue (Продолжить).

Пароль. Придумайте сложный пароль, чтобы его никто не взломал. Например, Гитхаб просит, чтобы в пароле было не меньше 15 символов или 8 символов, но тогда должны быть и латинские буквы, и цифры.

Имя профиля. Теперь выберите имя вашего профиля — оно будет использоваться в интерфейсе, в коммитах и комментариях. То есть именно так вас будет видеть любой пользователь Гитхаба. Для разработчика Гитхаб вместо визитки, так что выбирайте что-нибудь приличное, лучше, если ник будет совпадать с вашими никнеймами на других сайтах.

Если имя недоступно, Гитхаб вам об этом скажет. А если доступно — жмите Continue.

Рассылки. Дальше Гитхаб спросит, хотите ли вы подписаться на рассылку об обновлениях. Впечатайте латинскую У, если хотите, или n, если письма вам не нужны. Готовы спорить, мы знаем, что вы выберете.

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

Подтверждение почты. После капчи вам придёт письмо с кодом на почту. Введите его на следующей странице.

Вот здесь. Главное — не ошибайтесь.

Общая информация о вас и вашей команде. Если вы регистрируете аккаунт для себя, выбирайте Just me. Второй пункт — студент вы или учитель. Выбирайте «Студент», если вы не учитель.

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

  • Совместная разработка и код ревью.
  • Автоматизация. CI/CD, API и другие админские вещи.
  • Безопасность. Двухфакторная аутентификация, ревью, сканирование кода и списки зависимостей.
  • Приложения. Выбирайте, если будете использовать GitHub Mobile, CLI, Desktop.
  • Управление проектами. Проекты, метки, ишьи, вики и другие управленческие дела.
  • Управление командами. Организации, приглашения, роли, домены.
  • Сообщество. Выбирайте, если Гитхаб интересен вам как соцсеть.

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

Выбор тарифа. На выбор бесплатный тариф или платный GitHub Pro. Практика показывает, что для большинства личных проектов хватит бесплатного тарифа. В сентябре 2022 в него входили:

  • Безлимитное количество репозиториев.
  • 2000 минут CI/CD в месяц.
  • 500 мегабайт места в хранилище пакетов.
  • Поддержка сообщества.

Выбор тоже можно пропустить, тогда у вас будет бесплатный тариф.

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

  • 28 сентября 2022

Работа с Git в Visual Studio Code

Работа с Git в Visual Studio Code

Если вы вёрстаете сайты или пишете код в редакторе Visual Studio Code, то Git за пять минут настраивается прямо внутри редактора. Не нужно запоминать команды для консоли, не нужно тыкать в лишние приложения.

Следуйте инструкции и всё получится.

  • 16 сентября 2022

Markdown за 5 минут

Markdown за 5 минут

Маркдаун, он же markdown — удобный и быстрый способ разметки текста. Маркдаун используют, если недоступен HTML, а текст нужно сделать читаемым и хотя бы немного размеченным (заголовки, списки, картинки, ссылки).

Главный пример использования маркдауна, с которым мы часто сталкиваемся — файлы readme.md , которые есть в каждом репозитории на Гитхабе. md в имени файла это как раз сокращение от markdown.

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

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

  • 5 октября 2021

Шпаргалка по Git. Решение основных проблем

Шпаргалка по Git. Решение основных проблем

Поговорим о решении проблем с Git.

  • 11 декабря 2020

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

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