[Galaxy S I9000 General] beekay201:
Hey guys, so this is post #1 on the repo/git/gerrit building and most common (and a few advanced ones) tasks for cm, and basically anything that you want to build from git (and keep track of what is being done, rather easily, without the need for a web browser, for instance).

I'll try to keep this as short and as straight forward as i can. Anything inside '' is to be interpreted as cli programs/scripts and correspondent options, and for more info, i always refer to 'man program_you_need_help_with', often it saves me a lot of time. If you're on windows, well... I'll leave that part for someone else, sorry.

1- Setting up build environment/Repo Sync

We all know this step, it's well described here, which we all have read, and although that's pretty much it if you want to just build with latest merges, but first I often find myself with the need to customize my paths (since I don't use Ubuntu) and check dependencies.

Following the cm wiki folder structure, inside your cm root dir (/path/to/android/system), there's a few things that some might need to do.

a) setting build/envsetup.sh environment variables.​

For example, $ANDROID_BUILD_TOP, $ANDROID_TOOLCHAIN, $ANDROID_EABI_TOOLCHAIN - you can set these before hand, with 'echo $VARIABLE=/path/to/right/folder', or, even better, track these with git, by editing build/envsetup.sh on a different branch than (local) master.. more info on that part later.

b) setting java (jdk) paths and installed version​

$JAVA_HOME and $ANDROID_JAVA_TOOLCHAIN can sometimes also need some customizing, remember that you need openjdk6 v1.6.0.x at least with CM (i was using 1.6.0b22.24, if i'm not mistaken, i currently have 1.6.0 because of aosp building), not sure about 1.6.1.x, but definately not 1.7.x last time i checked.

c) cleaning previous build environment​

i usually call 'make clean' if i locally changed anything (testing commits in review) or remote pushed updates on script files, for example build/envsetup.sh, Makefiles, project $ANDROID_BUILD_TOP/frameworks/base, etc etc. 'make clobber' will make sure that any binary files that were updated are taken into account in the new build.

If you don't clean your build env before building again, you'll be able to build faster, because some stuff, for example $ANDROID_BUILD_TOP/device/samsung/galaxysmtd/kernel and modules residing in the same dir are kept from build to build (you can also keep these files in a stash, by calling 'git stash' in a certain branch. Also, $ANDROID_BUILD_TOP/out/target/product/galaxysmtd/ has stuff from previous build, so when you 'brunch galaxysmtd', building process will check for those files and if they were not changed in some brutal way, just optimize and re-use them. Just remember that when you merge something and after building/testing it doesn't show up in the rom :) it happened to me once, with build.prop :D

d) 'repo sync'​

basically the same as 'git pull', it's great for re-syncing the work tree with master.

it's the only thing it's good at, and sometimes, it even fails there, because it is not aware of any outside changes you do to it, as it is not capable of tracking them. that is where git enters.

2- Enter git!

git is a great tool. it has many many features, but we'll get better at it, since we won't use them all (for now, anyway :cool:)

a) cloning​

'git clone $remote_git_url $local_dir' will clone (or download, if you prefer) a remote git repo to a $local_dir of your choice.

to make a small comparison, it's similar to repo sync, except repo sync only clones the first time your run it, after that it pulls (which in turn is similar to 'git pull $remote_git_repo_branch, that is a mix between two other git commands, 'git fetch' and 'git merge').

back to 'git clone', not only it downloads the files, but also the current active branches of the remote repo, which allow you to see commit/merge history of a said branch with 'git log branch_name', for example.

b) branching​

imagine having one tree. it has one main branch (the master branch). Then it has lot's of ramifications, the other branches, that have small differences from the master branch, but are still made of the same thing.

with branches, git allows for different changes (or commits, or merges, or inserted files, pictures, binaries, etc) to be kept seperately without interfering with your local master branch, thus tracking different goals in building, while always retaining a point in development to go back to, if your changes still don't satisfy or broke build, for example.

let's say of you want to review (or test) I86acf878 in project frameworks/base, but want to keep it in a different branch, to have stuff organized and ready for later use, branch that tracks repo/branch github/gingerbread.

for example.

'git branch I86acf878-fingerprint_lockscreen github/gingerbread' would create a local branch that tracks github/gingerbread, named "I86acf878-fingerprint_lockscreen".

we created the branch, but we need to switch to it, with 'git checkout I86acf878-fingerprint_lockscreen', before we actually save any work on it. or cherry picks.

it's good policy just to 'git branch' after checkout so that you are 100% certain that you're on desired branch. it also prints a list of branches in certain project.

let's suppose that you wanted to test another commit, I89bdbc11, which is in project frameworks/base as well.

instead of keeping it on the same branch, you can create another one, same way as before and it's ready to checkout to, and to pull that different commit.

another example:

if you wanted to customize build/envsetup.sh, so that everytime you run '. build/envsetup.sh && brunch galaxysmtd', env variables get set right before building, you could also create a branch in build/, checkout to that branch, edit envsetup.sh according your local setup, tell git to keep your changes in mind with 'git add envsetup.sh', and finally commit that into your own "local-config" branch.

and here's another thought: you can create as many branches as you need, merge your local branches, or better, you can merge your local branches inside one master-local-testing branch.

this leaves the highway ready for cherry-pick and rebasing functions, while still being able to track the commits and merges that you did or pulled in the past, which branches were merged in, with the help of 'git log'.

c) merging​

'git merge' is used, quite bluntly, when you want to merge branches inside one project.

You can only checkout one branch at a time. This way, merging several branches into another, allows for testing several commits in the same build.

using the same example as before, change dir to frameworks/base. 'git branch' will tell what branches are there:

to merge all first three branches into "user-local-testing", first checkout to that branch.

'git checkout user-local-testing'

then, start merging the other branches into the current one. i'll merge the first one:

'git merge I99830a55-MIUI-likeBatteryBar'

when merging, you may or may not encounter conflicts. most of the times you don't, but when you do face it, either you try to solve it, find help, or just leave it.

git tells you that you have conflicting files, which files are, and even marks the lines that are causing the merge conflicts, like this:

'git diff' will help here. you can use gerrit to help out, choosing Side-by-side view (old version and version in review), like this.

after resolving the conflicts, you need to tell git to start tracking the file(s) you edited. for example, if we had edited frameworks/base/packages/SystemUI/res/drawable/battery_bar.xml and

frameworks/base/packages/SystemUI/res/layout/status_bar.xml, we would need to

'git add packages/SystemUI/res/drawable/battery_bar.xml' and 'git add packages/SystemUI/res/layout/status_bar.xml'.

after, we commit those changes with 'git commit -a' - you'll be put inside your $EDITOR (set your favourite through env variables), where you can put a small description of what files were edited for conflict resolving. save the file, and git will add the change to those specific files, specific folders, time, to 'git log' of the branch you're working on.

Remember, solve the conflicts in the branch you are merging to, not in the branch you're merging with.

sorry guys, but i'll finish the rest on branches later

still to do:

d) cherrypicking

e) rebasing

3- Speeding up build times

4- ...

5- glossary