9

Im building the Cyanogenmod 9 (Android ICS) system for a Nexus S phone (samsung crespo). The problem is that if I do:

repo init -u git://github.com/CyanogenMod/android.git -b ics  

The repo inits to the latest commit of ICS, in which the manifest does not include some device/samsung/ projects I need (specifically https://github.com/CyanogenMod/android_device_samsung_crespo).

How do I repo init to a particular commit? In my case I want the last commit using the google android-4.0.3_r1 branch. Is this one:

If I do

repo init -u git://github.com/CyanogenMod/android.git -b commit-hash

Does not work, seems that repo init -b only support the HEAD of a branch.

Thanks in Advance.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
renzoe
  • 145
  • 1
  • 3
  • 9

5 Answers5

12

I figured it out. If your have a tag in a manifest file (version.xml for example). You can repo init to a specific tag with the following command:

repo init -u <address> -b refs/tags/<tagname> -m version.xml
parsley72
  • 8,449
  • 8
  • 65
  • 98
Renaud Mathieu
  • 366
  • 2
  • 9
5

Long answer:

You can't specify a branch name (or SHA, or whatever else) to repo, it will not work. Here's why:

repo is a script that handles a collection of repository projects (which in fact are independent git's). Project list is located in .repo git, and contains a manifest file, which basically is a list of all repository git's and they branches. -b is relevant only for repo git during repo init.

Here is an example of .repo/manifests/default.xml:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote fetch="git://address.com/" name="origin"
          review="review.address.com"/>
  <default remote="origin" revision="ics-something" sync-j="4"/>
  <manifest-server url="http://manifests.address.com:8000"/>
  <!-- sniff -->
  <project name="platform/external/libxml2" path="external/libxml2"
           revision="ics-common"/>
  <project name="platform/external/zlib" path="external/zlib"
           revision="ics-common"/>
  <project name="platform/frameworks/base" path="frameworks/base"
           revision="ics-something"/>
  <project name="platform/packages/apps/Bluetooth" path="packages/apps/Bluetooth"
           revision="ics-common"/>
  <!-- sniff -->
</manifest>

So, the correct way of obtaining the sources of the repository for the particular build is to obtain it's manifest.
I.e., manifest, that will contain SHA's (or tags, which are practically the same, if they are present) instead of branch names. This way every git project within your repository will point into some commit, that is specified in the manifest file:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote fetch="git://address.com/" name="origin"
          review="review.address.com"/>
  <default remote="origin" revision="ics-something" sync-j="4"/>
  <manifest-server url="http://manifests.address.com:8000"/>
  <!-- sniff -->
  <project name="platform/external/libxml2" path="external/libxml2"
           revision="refs/tags/android-4.0.4_r1.1"/>
  <project name="platform/external/zlib" path="external/zlib"
           revision="refs/tags/android-4.0.4_r1.1"/>
  <project name="platform/frameworks/base" path="frameworks/base"
           revision="ecb41a77411358d385e3fde5b4e98a5f3d9cfdd5"/>
  <project name="platform/packages/apps/Bluetooth" path="packages/apps/Bluetooth"
           revision="621bae79f1a250e443eb83d1f473c533bea493dc"/>
  <!-- sniff -->
</manifest>

As you see, the only difference between these two manifests is the revision values of repository git's.

Short answer:

You need to obtain manifest_static.xml of the particular build.

Or, if you just missing some project git's, then you could create local_manifest.xml file in .repo git, add missing git's there, and then repo sync from the root of your repository. More info on local_manifest.xml usage is here.

Andrejs Cainikovs
  • 27,428
  • 2
  • 75
  • 95
  • 1
    Why are they not using `git submodule` instead of the .repo? Seems it was built for this... – Adam Dymitruk May 30 '12 at 18:53
  • 1
    `repo` can more than just syncing. It automates uploads to gerrit, creating branches, downloading changes without knowing the target git, etc. Sure, it's just the wrapper script, and literally everything can be done with the bare git. But since Google made `repo`, everyone sticks to that :) – Andrejs Cainikovs May 30 '12 at 19:37
  • - how do you obtain that static manifest? `repo manifest -r -o static_manifest.xml`? - what is particular `repo sync` command with a static_manifest? `repo sync -m static_manifest.xml` does not work ("fatal: static_manifest.xml not found") – Slava Apr 08 '22 at 08:47
  • @Slava It's up to your environment how manifest files are stored. Often, the manifest file is tagged in a git, which allows you to obtain it via `repo init -u -b refs/tags/ -m manifest.xml`, [as pointed by Renaud Mathieu](https://stackoverflow.com/a/19636869/147407). In my environment at my work place, manifest file was part of the build artifacts. – Andrejs Cainikovs Apr 08 '22 at 09:14
  • @AndrejsCainikovs , I have only the build ID. Dont, have the info address and tag name. Can we clone though build ID? – GNK May 24 '23 at 07:19
  • 1
    @GNK No. But your build server most likely saves manifest file which was used during the build, as an artifact. As I wrote already: _You need to obtain `manifest_static.xml` of the particular build._. – Andrejs Cainikovs May 25 '23 at 13:31
4

I don't have sufficient authority to submit a comment, but I just wanted to clarify Andrejs Cainikovs's answer.

Repo does accept a commit-id SHA in addition to a branch ref as an argument to the -b option.

As the answers suggest, this argument specifies the revision of the manifest that should be used by repo, not a revision in any of the projects that the manifest refers to.

Rob
  • 161
  • 2
0
  • Dump the state of your reference repo to a manifest file
  • copy the file to a copy repo's .repo/manifests/
  • do the sync in the copy repo using that static manifest.
[reference_repo]$ repo manifest -r -o static_manifest.xml
[copy_repo]$ rsync -a /path/to/reference_repo/static_manifest.xml /copy_repo/.repo/manifests/
[copy_repo]$ repo sync -m static_manifest.xml

Make sure in the copy-repo the static manifest is copied to the .repo/manifests/ directory and referred to by just file name in repo sync.

Slava
  • 1,528
  • 1
  • 15
  • 23
0

I didn't understand @Andrejs Cainikovs' answer - you can specify a branch name or SHA to repo, it works fine. The -b parameter takes either a branch name, a tag (see @Renaud Mathieu's answer) or a SHA.

I think what he's talking about is being able to specify a manifest itself on the command line. You can't do this but you can override an existing manifest by using a local manifest - see https://stackoverflow.com/a/75016579/264822. I've copied the example here:

mkdir -p .repo/local_manifests/
# Create .repo/local_manifests/local_manifest.xml

<manifest>
    <!-- add github as a new remote source -->
    <remote name="github" fetch="git://github.com" />

    <!-- remove project in default.xml -->
    <remove-project name="platform/bootable/recovery" />
  
    <!-- replace with new remote github -->
    <project path="bootable/recovery" name="CyanogenMod/android_bootable_recovery" remote="github" revision="cm-10.1" />

    <!-- add new project -->
    <project path="external/busybox" name="CyanogenMod/android_external_busybox" remote="github" revision="cm-10.1" />

</manifest>
parsley72
  • 8,449
  • 8
  • 65
  • 98