Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Удаление и перемещение файлов Основы Git

Видео может быть заблокировано из-за расширений браузера. В статье вы найдете решение этой проблемы.

Рекомендуем перейти в курс Введение в Git

Мы обновили этот курс — добавили новые темы, самостоятельные задания и практические упражнения. Посмотрите этот урок по ссылке: https://ru.hexlet.io/courses/intro_to_git/lessons/working-directory/theory_unit


Здравствуйте!

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

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

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

У вас в проекте был файл, который при рефакторинге стал не нужен и вам нужно его удалить. Чаше всего получается так, что вы его сначала удаляете из рабочей директории, а потом уже добавляете в индекс информацию о том, что файл должен быть удален из репозитория. То есть это может быть описано следующими командами:

rm file.txt
git add file.txt

Результатом выполнения данных команд будет удаление файла из репозитория для коммита, который вы выполните на этом этапе и всех последующих коммитов. Это замечание важно тем, что для предыдущих коммитов этот файл будет находиться в репозитории. Аналогом этих двух команд является команда git rm file.txt. При этом в индекс сразу будет добавлена информация о том, что файл удален и не нужно будет выполнять команду git add.

Также вы можете не выполнять команду git add <pathspec>, а зафиксировать удаление файла непосредственно при выполнении коммита (git commit -a). Но я не советую вам использовать такой вариант (если вы действительно не хотите сделать именно это).

Если команде git rm в pathspec было указано название директории, то вам понадобится указать флаг -r для того, чтобы git рекурсивно удалил файлы, находящиеся в указанной директории.

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

git rm --cached readme.txt

В случае, если вам необходимо полностью удалить файл из истории git - вам потребуется выполнить совсем не простую команду, которая будет приведена в расшифровке видео:

git filter-branch --index-filter "git rm --cached --ignore-unmatch path/to/file" --prune-empty HEAD

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

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

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

Что касается перемещения файлов - то возможны 3 самых частых случая:

  • Файл был перемещен в другую директорию
  • Файл был переименован
  • Любое из предыдущих действий + при этом файл был отредактирован.

А теперь, давайте абстрагируемся от того, как бы git мог это обработать и опишем эти действия при помощи команд:

Перемещаем файл в новую директорию mv file.txt new_dir/ Теперь git видит, что у него один файл удален (file.txt) и один не отслеживается (new_dir/file.txt) Зафиксируем удаление файла file.txt git add file.txt Зафиксируем добавление файла new_dir/file.txt под версионный контроль git add new_dir/file.txt

То есть, мы выполнили 3 действия, для того, чтобы зафиксировать перемещение файла в другую директорию (в случае с переименованием файла будет то же самое). git предоставляет 1 команду взамен этим 3-м git mv file.txt new_dir/txt

Как в первом случае, так и во втором, git заметит то, что файл был перемещен (переименован) и будет опираться на эту информацию в будущем. Например, если кто-то отредактирует в будущем файл, который располагался по старому пути, при мерже или ребейзе git определит, что файл был перемещен и, если сможет - то автоматически применит изменения к новому файлу по новому пути. Если не сможет применить изменения автоматически - то в информации о конфликте он скажет, куда был перемещен файл и вы сможете проще разрешить конфликт.

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

На этом я закончу знакомство с этими операциями. Не забудьте прочесть справку по командам перед выполнением тестового задания.

Спасибо за внимание!


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

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

Об обучении на Хекслете

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

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