Поделиться через


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

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

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

Так как можно безопасно откатить центральный репозиторий?

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

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

диалоговое окно Изменения Team Explorer с большим видео в включенных изменениях

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

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

После коммита из локального репозитория сервер также будет содержать большой файл

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

Это важно

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

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

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

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

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

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

командная строка : разрешения git push --force.

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

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

git log

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

Основная ветвь Просмотреть историю

  1. Теперь откройте командную строку Git.

диалоговое окно синхронизации — открытие действия командной строки

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

командная строка — выбор коммита видео

  1. Вам потребуется SHA, которая начинается с "25b4".

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

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

Перебазировать для удаления видеофайла

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

  1. В нашем примере вы введете следующее:

git rebase -i 25b4

  1. После того как редактор появится, удалите все строки выбора, кроме ветви, которую вы хотите сохранить в качестве новой головы. Если все выглядит так, как это нужно, в viнаберите ":w<enter>", чтобы сохранить или "!q<введите>" для выхода без сохранения.

командная строка — git rebase -i 25b4 pick

Вы будете изменять те строки, которые больше не хотите

командная строка — git rebase -i 25b4 drop command

  1. Измените "pick" на "drop", как показано, а затем введите ":w" (в vi), чтобы сохранить и ":q!" для запуска повторной базы

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

git log

локальные и серверные репозитории после перебазирования

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

  1. Тип: git push --force

Командная строка — git push --force

Command Prompt — git push --force result

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

использовать с осторожностью, так как вы можете легко потерять данные на сервере!!

Принудительное отображение содержимого, которое нужно сохранить, без видеофайла

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

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

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

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

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

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

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

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

Рекомендации по лучшим практикам

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

Что нужно делать

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

Чего не следует делать

  • Не выполняйте rebase после отправки. Повторное перебазирование отправленных фиксаций в Git может быть плохим, потому что заставляет всех остальных в репозитории снова перебазировать свои локальные изменения - и они не будут счастливы, если им это придётся сделать. Перебазирование зафиксированных изменений в вашей личной ветке, даже если они пушились, не имеет большого значения, если другие люди не используют их.
  • Не добавляйте двоичные файлы в репозиторий. Git не сжимает двоичные файлы так, как это делает TFVC, и поскольку все репозитории содержат всю историю, фиксация двоичных файлов приводит к постоянному увеличению их объема.

Сводка

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

Авторы: Эдвард Фрей и Джесси Хоуинг | Свяжитесь с авторами и ALM | DevOps Rangers здесь

(c) Корпорация Майкрософт 2015 г. Все права защищены. Этот документ предоставляется "as-is". Сведения и представления, выраженные в этом документе, включая URL-адрес и другие ссылки на веб-сайты, могут изменяться без уведомления. Вы берете на себя все риски, связанные с использованием сведений, приводящихся в данном документе.

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