I want to develop on top of Android using a local Android repository server. I need to add several new git repositories to the hierarchy of gits, and I need to modify existing android sources for a custom tailoring of Android.
What is the "correct" way to clone the entire Android source tree of git repositories, such that I can push/pull to/from a common local repository server, and still easily pull new changes from Android upstream?
I am specifically looking for advice on how to use the repo script for interaction with my own server, and how to set up the manifest git repository and managing branches therein.
On your git server
repo init -u https://android.googlesource.com/platform/manifest --mirror # --mirror is the key
repo sync
Because you specified --mirror, all repos created will be 'bare' repos, which is the git-correct way to create a mirror unless you are a git uberlord.
On your client:
repo init -u git#git.yourserver.com:platform/manifest.git # you may use a different means of accessing your git server; I have to assume something for this example.
no repo sync yet. Your manifest is probably wrong. Look at the symbolic linked .repo/manifest.xml... cat it and read at the top the <remote fetch=""... it probably points back to android.googlesource.com. but if it says '..' I think that means 'come back to my server', so you can skip to step 6). But if it does point back to another server (not yours), then go to step 3.
cd .repo/manifests
vim .repo/manifests/default.xml (or whatever your active manifest.xml is).
Fix default.xml's <remote fetch="CHANGE ME" to point back to your git server
attempt a repo sync. It should pull only from your repository. If it doesn't, stop the repo sync, and try to fix default.xml again.
Once you see repo sync work on your test machine, then commit default.xml back in (git commit; git push), so that others on the team will have 'no-manifest-edit' experience when they repo init; repo sync from your server.
Once you see a 'no manifest edit' repo init; repo sync work, then go to your default.xml again, and just start adding new XML elements along with the tons of other existing Android project elements; these new elements will point to your custom projects. For these new projects, just git init them as you normally would, and make sure they have a branch matching the same <default revision="whatever_branch_you_see_here" so that a repo sync will succeed when it encounters these new projects.
If you do indeed set a default branch in your manifest <default revision="" element, then just have everyone make a local branch set to follow the remote branch specified in the revision attribute. So, for example, if <default revision="branch_a" is in your manifest, after you do a repo sync, when you cd into a sub-project of interest, do a :
git checkout -b branch_a origin/branch_a
Then, if the user git push's (there is no repo command to push, as far as I'm aware), and if someone else does a ./repo sync after that push, they will get those changes from the original user... as long as you are using the same manifest and actually pushing to the default revision (branch) specified by that manifest.
That's the simplest recipe. If you want to make actual feature branches, then you'll have to edit your manifest more regularly if you want 'repo sync' to just work... and you will have to communicate to the rest of the team to grab your version of the manifest when you do that. Alternatively, if it's just one or two git repos you are touching, then you could just forego repo sync and git push/pull like normal on those repos and ignore the rest of the quiet tree for the times you are heavily iterating. This sounds, ultimately to me, like a simpler path. I'd ignore repo as much as you possibly can; only using it for 'all project' syncs and leaving it alone for the times you are focusing on 1 or 2 projects.
Regarding getting updates from upstream. I think the way to do that is to change your default.xml to point back to your original git location (like android.googlesource.com), do a repo sync to cause all the new stuff to merge in, and once done with the sync, commit back up to your repo. I haven't done this yet; so I can't be too specific, but this is how I plan to do it.
I'm ignoring server administration details above. For instance, you need to call the repo init in a certain directory on your git server to cause it to be an available git repository; I'm assuming you know how to administer your git server.
Related
I have an app with different version.
But every version have different Git repository.
So please let me know how we can manage that every build variant have different repository.
You should have different tags or branches per version, not different repositories.
From the same repo, you would then use git worktree in order to clone the repo once, but checkout the repo multiple times: see "Multiple working directories with Git?".
That way, you have different folders, each one with a different version of your project.
Since only the name/color/logo are changing, you would need:
one repo with all the common code
one configuration file with the right values for name/color/logo per environment
one way for your code to detect in which environment it is deployed: your code you then pick the right value from the config file.
The point is: one project, one Git repo: See the 12 factors app (in particular, the Config section).
I am working on Android Source Code, and I used mirror to let the time of sync faster.
$ mkdir mirror
$ cd mirror
$ repo init branchA --mirror
$ repo sync
Then, I can use this mirror when I need to sync branchA each time.
$ repo init branchA --reference=/.../mirror
$ repo sync
But now, I have a question, I have other branches which are related to branchA. For instance, branchB is based on branchA, and banchC is based on branchB. In this case, should I need three different mirror ?
If I only sync branchC's mirror, Can I use this mirror to sync branchA and branchB ?
If I only sync branchA's mirror, Can I use this mirror to sync branchB and branchC ?
You need only one mirror.
Repo's mirror repositories are fully cloned. They contain every git object reachable from all the branches, tags and other refs. repo sync's option -c, which downloads only the current ref and its objects, will take no effect in mirror repositories.
Even if the mirror has only one branch's data, you can still use it as reference to download other refs. The missing refs and objects, which can't be found in the mirror, will be downloaded from the remote server. You won't miss anything in the working repositories.
Using android studio 1.0 for my project, I plan to code a library module inside it. But I am wondering whether sharing only the library module (for example in its own github repository) is easy : I mean, someone fetching this repository, can integrate it as a library module in its own project easily. Also, does the library module has to define at least an activity, or can it just contain independents classes and resources ?
Of course, I also plan to share the global project on a github repository.
So what is the "safest" and easier way to proceed ?
Apologizing if the question may seem too obvious or bad explained.
The only real way to separate a project into multiple git repositories is through submodules. It's not a bad concept, but what it effectively means is that you have a git repository inside another. One the remote side, they are separate repositories with one being included via submodule.
More information, and the command line tools you'll need to get started can be found at: http://git-scm.com/book/en/v2/Git-Tools-Submodules
Note, there is a lot of hate for submodules, and some of it is earned. It's not intuitive and is often considered an expert Git feature. For that reason, I recommend you read it thoroughly and make sure you understand. Perhaps even throw together a couple of unrelated repositories to play with. BTW, you can have a git repository on your computer anywhere (git init --bare to create it). Then you can clone it anywhere else with git clone file:///<your-path-here> Thus your local and remote are on one computer so you can play/learn without having to create more repositories on git hub or some such.
Since you are using Android Studio, I assume you use Gradle as the build system. With that assumption, below are my answers:
Your library project needs not have Activity, but will need AndroidManifest.xml and a Gradle project layout (src, res folder etc).
If your library project is hosted on Github (or locally outside the root folder of the main project you plan to use it), then you can use Git submodule like lassombra suggested to bring it under root folder of main project.
Once you have the library under the root folder of your main project, you can use Gradle multi-project setup to link them.
I would like to create a local server for Android branch android-4.3_r1.1
I follow this thread:
Cloning Android sources to a local repository server
But I couldn't do the same thing for specific tag,
How can it be done ?
I would like to have a server, and then from the client do some work and push it to the server, so other client can do a sync and see my commits ...
On the server side this is what I did:
repo init -u https://android.googlesource.com/platform/manifest --mirror
repo sync
On the client side:
repo init -u git-server/android/platform/manifest.git/ -b android-4.3_r1.1
repo sync
I get many of some kind of these errors:
fatal: 'git-server/android/device/ti/panda' does not appear to be a git repository
fatal: The remote end hung up unexpectedly
And all the process is failed ... (error: Exited sync due to fetch errors)
I would like a client AOSP working on android-4.3_r1.1 then do some changes and commit them to the git server.
The repo init --mirror -u $URL/platform/manifest method is sane, but you'll only sync the gits listed in the manifest in question (the master branch, in this example). So, while all gits that are synced will contain all branches and tags needed, the manifest itself doesn't include all gits so subsequent attempts to initialize workspaces based on the created mirror will fail if the manifest branch you've chosen to sync points to gits not included in the master branch's manifest.
The AOSP team has set up special manifest, mirror/manifest, that isn't useful for building anything but lists all gits from all branches and therefore is highly useful for mirroring. In other words, initialize your mirror like this:
repo init --mirror -u https://android.googlesource.com/mirror/manifest
See the AOSP Downloading the Source documentation.
I'm looking reproducibility between android system (AOSP) daily builds against repo's collections of git repositories and the impact of using fast-forward merges.
The problem is that when doing daily builds you will get a tip-of-tree while development is happening elsewhere. If HEAD hasn't changed when the change is pushed, it will do a fast-forward merge and time will be re-written. So effectively the physical state of the repository 3 days ago will be different than asking git to go back three days.
The prime solution I can see is to use git with --no-ff to force merge commits. This injects a lot of noise for smaller commits, and seems to be considered bad practice in keeping a clean tree.
The background on this is trying to have reproducibility in an android build environment. For those that don't know, an android build is a collection of disparate git repositories. My ultimate use case is that I want to be able to say, put the code base in the state it was for developers 3 days ago. With fast-forward merges, we lose some critical information on how to correlate between changes on multiple repo projects (ie: git repositories).
As you've noticed, Git doesn't track the state of a branch over time. Two reasonable options are to either set tags for each build or to create a static manifest with the SHA-1s of all checked out commits at the time of the build:
repo manifest -r -o build_20131104.xml
Those files can either be checked into the manifest git and used like e.g.
repo init -u ... -m build_20131104.xml
to reproduce the prior state or you can save the files elsewhere.
Tagging all the gits litters the tag namespace if you're doing a lot of builds (and Git is currently fairly slow with thousands of tags) but is otherwise pretty convenient. Don't forget to tag the manifest git too.