Подтвердить что ты не робот

Исходный код Android и репо - что именно происходит при получении кода

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

Init и sync repo:

repo init -u https://android.googlesource.com/platform/manifest
repo sync

После этого моя папка заполнена папками типа Android (bionic, bootable и т.д. и т.д.) и скрытой папкой .repo. Примечательно, что есть папка с именем ics-mr1, которая относится к определенной версии и содержит в основном те же папки в моем repodir внутри себя.

Вытащите конкретную ветвь:

repo init -u https://android.googlesource.com/platform/manifest -b gingerbread
repo sync

Это завершается относительно быстро, и основное изменение, которое я вижу, - это теперь папка с именем gingerbread (все исходные папки, похоже, остаются).

Теперь я попробую это, и он принимает AGES:

repo init -u https://android.googlesource.com/platform/manifest -b android_4.2.2_r1
repo sync

После этого он все еще содержит те же gingerbread и ics-mr1 и несколько новых случайных папок (например, abi), но ничего похожего на эту новую версию.

Вопрос

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

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

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

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

4b9b3361

Ответ 1

repo init

Поскольку вы выглядите довольно сообразительно, вы знаете, что репо - это просто python script, правильно? Вы можете прочитать его, чтобы посмотреть, как это работает. Я не прочитал все это, но, в основном, он обертывает git и обеспечивает поддержку для работы с несколькими репозиториями git. Идея заключается в том, что есть файл манифеста, который указывает требования для разных версий Android. Когда вы делаете repo init с аргументом, он смотрит, какие репозитории git он должен клонировать и какие git репозитории, которые вы уже синхронизировали, и какие ветки нужно извлечь, как только они получили правильные репозитории. Затем он обрабатывает все репозитории, которыми он управляет, на соответствующих ветвях. Подумайте о репо, добавив еще один уровень в стандартный рабочий процесс git (который, как я полагаю, вы знакомы).

В первый раз, когда вы используете репо, чтобы получить основную ветвь, вам нужно использовать

repo init -u https://android.googlesource.com/platform/manifest

И после этого вам нужно синхронизировать все файлы с сервера:

repo sync

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

repo init -b version_name

Это обновляет манифест до того, который содержит информацию о желаемой версии Android (также называемой веткой).

Не забудьте синхронизировать.

Чтобы переключиться на другую ветвь манифеста, repo init -b otherbranch может использоваться в существующем клиенте. Однако, поскольку это только обновляет манифест, последующий repo sync (или repo sync -d) необходим для обновить файлы рабочих каталогов.

Поведение, которое вы испытываете, может показаться странным, потому что вы, вероятно, не привыкли работать с системой, которая так легко перезаписывает ваше локальное состояние. При использовании git вы не должны init куча раз в том же каталоге. Другой вариант - создать новые каталоги для каждого проекта. Цель каталога .repo - хранить всю информацию, относящуюся к вашей текущей настройке репо (также как и каталог .git). Фактически, запуск repo init делает много вещей:

  • Загрузки манифеста из указанного URL.
  • пытается открыть или создать каталог .repo.
  • Устанавливает, что ваш ключ GPG настроен.
  • Clones указанная ветка (по умолчанию используется REPO_REV, если ни один не указан).
  • Проверяет его.
  • Проверяет соответствующую ветку для каждого из проектов.

Я бы предположил, что операция клонирования записывает информацию в папку .repo. Причина, по которой вам требуется возраст после первой команды, которую вы запускаете:

repo init -u https://android.googlesource.com/platform/manifest
repo sync

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

$ repo init -u https://android.googlesource.com/platform/manifest -b gingerbread
$ repo sync
...
.repo/manifests/: discarding 68 commits
...

Возврат обратно до android_4.2.2_r1 означает, что репо должно загрузить любую информацию, необходимую для этих коммитов, а также обновить текущие ветки во всех связанных проектах. Это займет много времени; Репо - это использование дискового пространства для обработки.

на самом деле?

Теперь возникает проблема: что, если вы хотите сравнить сразу две ветки репо? Это сложно, потому что, когда вы repo init && repo sync, вы теряете старую информацию, на которую вы смотрите. Ответ заключается в том, чтобы скопировать соответствующую информацию, а затем repo init && repo sync снова. Это очень раздражает очень быстро - к счастью, репо предоставляет способ ускорить этот процесс, если у вас есть дисковое пространство.

Одна из стратегий, позволяющая ускорить работу, - создать локальное зеркало в каталоге workspace/master. Затем выберете нужную ветку из зеркала в новом каталоге, например. workspace/gingerbread. Теперь вы можете переключаться между ветвями, просто перейдя в соответствующий каталог.

Зеркально локализовать AOSP:

cd workspace
mkdir master && cd master
repo init --mirror

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

mkdir ../gingerbread && cd ../gingerbread
repo init -b version_name --reference=../master

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

Другой вариант - просто инициализировать и синхронизировать желаемую ветку, затем скопировать папку в другое место и использовать копию для повторной инициализации и синхронизации. Repo должен загружать только то, что отсутствует.

Другое репо использует:

Помимо init, repo предоставляет поддержку для передачи команд, таких как branch, ко всем различным репозиториям git в данном манифесте, чтобы вам не приходилось беспокоиться об этом при работе с кодом. Это также облегчает сотрудничество, упрощая отправку локальных изменений в систему проверки кода gerrit. Я не уверен, что официальная причина разделения AOSP на несколько репозиториев git есть, но я бы предположил, что это было сделано для управления проблемами масштабирования управления версиями и для обеспечения устойчивости проекта и отказоустойчивости ( если кто-то тормозит один репозиторий git, он не уничтожает весь AOSP). Также необходимо предоставить способ, с помощью которого поставщики могут внести свой вклад в исходный код и позволить им управлять своими собственными репозиториями git, которые могут просто быть зарегистрированы с/в всеобъемлющем манифесте, имеет смысл. Я не ответил на ваши вопросы, но, надеюсь, я представил некоторые сведения.