Удаление большого двоичного файла из журнала Git для управления размером клонированных репозиториев

Сервисы Azure DevOps | Azure DevOps Server | Azure DevOps Server 2022

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

Как можно безопасно откатить изменения в центральном репозитории?

Сценарий проблемы

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

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

Снимок экрана, показывающий диалоговое окно Team Explorer с крупным видео среди внесенных изменений.

Добавьте большой файл в локальный репозиторий.

Снимок экрана: сервер и локальные репозитории с копией больших видеофайлов.

После фиксации изменений в локальном репозитории, большой файл появляется и на сервере.

Замораживание репозитория

Чтобы устранить проблему большого репозитория, необходимо начать с источника. В этом сценарии источником является репозиторий сервера. Попросите команду прекратить вносить изменения в репозиторий. Если во время этого процесса происходит больше push-уведомлений, необходимо учесть их, чтобы не потерять данные.

Это важно

Следующие шаги удаляют видео из истории ветки, но файл остается в истории репозитория при клонировании репозитория из Azure Repos. Удаление файлов из журнала ветвей предотвращает обновление файлов, которые создали другую версию большого файла в репозитории.

Дополнительные сведения об управлении большими файлами в Git. Объяснение этого поведения и способы его обхода при использовании репозиториев Git в Azure Repos см. в статье "Почему клонирование из Visual Studio Team Services возвращает старые нессылаемые объекты?".

Ребейз и форс-пуш

Если никто другой в команде не внес никаких изменений в репозиторий, которые обычно происходят через push, вы можете пойти по простому пути. По сути, вы приводите локальный репозиторий в тот вид, который вам нужен (т. е. без большого файла). Затем вы принудительно отправляете свои изменения на сервер.

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

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

Снимок экрана: командная строка — git push-force permissions.

Затем необходимо перебазировать репозиторий.

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

    git log

    Кроме того, хэш SHA можно получить из просмотра журнала ветвей в Visual Studio Team Explorer.

    Снимок экрана, на котором показан пункт меню

  2. Откройте командную строку Git.

    Снимок экрана: действие

  3. Найдите интересующее вас хэш-число SHA.

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

    Вам нужен SHA, который начинается с 25b4.

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

  4. Чтобы вернуться к времени и сделать предыдущее состояние новым текущим состоянием, используйте git rebase команду:

    git rebase -i <SHA hash of desired new current branch>

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

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

  5. В этом примере вы введите следующее:

    git rebase -i 25b4

  6. После того как редактор появится, удалите все строки pick, кроме ветви, которую вы хотите сохранить в качестве новой высшей. Когда все выглядит правильно, в vi введите :w\<enter\>, чтобы сохранить, или введите !q\<enter\>, чтобы выйти без сохранения.

    Снимок экрана, на котором показана командная строка - git rebase -i 25b4 pick.

    Измените строки, которые больше не нужны.

    Снимок экрана: командная строка — git rebase -i 25b4 drop command.

  7. Измените pick на drop как показано. Затем введите :w в vi, чтобы сохранить, и введите :q!, чтобы запустить перемещение.

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

    git log

    Снимок экрана, показывающий локальные и серверные репозитории после перебазировки.

    Коммит большого видео теперь удален из локального репозитория.

  8. Введите следующую команду:

    git push --force

    Снимок экрана: командная строка — git push-force.

    Снимок экрана, показывающий командную строку с результатом команды git push --force.

    Эта команда принуждает ваш репозиторий перезаписать содержимое репозитория на сервере.

    Используйте эту команду с осторожностью, так как вы можете легко потерять данные на сервере.

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

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

Если вы используете Azure Repos, может потребоваться настроить альтернативные учетные данные, которые не используют специальные символы. Примером является символ (@) в адресе электронной почты. Чтобы выполнить эту задачу, следуйте инструкциям в статье "Проверка подлинности с помощью Azure Repos".

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

Если у пользователей есть более новые коммиты

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

После перебазирования другим пользователям в команде также необходимо перебазироваться, чтобы у каждого была актуальная копия репозитория сервера. Эта работа мучена для всех, и вы хотите избежать этого. Если вам нужно удалить push-уведомление, необходимо согласовать действия с командой. Дополнительные сведения о перебазировании см. в разделе «Git ветвление - перебазирование».

Ключ состоит в том, чтобы убедиться, что вы знаете коммиты, которые хотите, и коммиты, которые не хотите. Изучите git log или историю в вашей интегрированной среде разработки (например, Visual Studio). Сделайте подробную запись хэшей SHA, которые нужно оставить, и тех, которые следует удалить.

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

Рассмотрение лучших практик

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

Вещи, которые нужно сделать

  • Часто фиксируйте изменения. Вы всегда можете исправить их позже с помощью squash или rebase.
  • Используйте ветви для изоляции изменений. Ветви дешевые и частные, и слияние просто. Вы также можете создать резервную копию изменений на ветке, отправив ее на сервер.
  • При публикации ветвей тем используйте соглашение об именовании. Назовите ветвь users/<alias>/<branchname>. Это имя помогает сгруппировать ваши ветви и облегчает другим пользователям идентификацию владельца.
  • Не забудьте отправить изменения. Использование Commit != Checkin и (Commit + Push) == Checkin.
  • Рекомендуется использовать .gitignore для больших двоичных файлов, чтобы они не добавлялись в репозиторий. Дополнительные сведения см. в разделе "Игнорируние файлов".
  • Рекомендуется использовать систему управления версиями, такую как NuGet или Team Foundation Server, для хранения больших двоичных файлов.

Чего следует избегать

  • Не выполняйте rebase после отправки. Повторное перемещение уже отправленных изменений в Git может быть плохой практикой, так как это заставляет всех остальных в репозитории перебазировать свои локальные изменения. Участники команды могут не быть счастливыми, если им нужно выполнить эту задачу. Перебазирование зафиксированных изменений в собственной ветке, даже если они отправлены, не проблема, если другие люди не извлекают эти изменения.
  • Не добавляйте двоичные файлы в репозиторий. Git не сжимает двоичные файлы так же, как это делает Team Foundation Version Control. Поскольку все репозитории содержат всю историю, фиксация двоичных файлов приводит к постоянному раздутию.

Сводка

Иногда нежелательные элементы, такие как большие файлы, добавляются в репозиторий и должны быть удалены, чтобы сохранить репозиторий чистым и упрощенным. Чтобы выполнить эту задачу, приведите свой локальный репозиторий в порядок. Используйте команду git rebase, а затем команду git push --force, чтобы перезаписать репозиторий сервера вашим локальным репозиторием.