= Chimera 2 Revision Control = [[PageOutline]] We will use '''git''' and '''git flow''' for revision control to manage Chimera 2 source code. Development will follow the [http://nvie.com/posts/a-successful-git-branching-model/ Vincent Driessen's branching model] where the '''master''' branch is the release branch and the '''develop''' branch is the daily build branch. A ''team repository'' is the repository that is used to create release and daily builds, ''i.e.'', changes committed in developer repositories but not pushed to the team repository will not appear in either release or daily builds. The remainder of this document describes some common tasks using '''git'''. ''plato'' refers to the Linux cluster on which the team repository is stored. ''franklin'' is the name of a node in the plato cluster. == Cloning a Developer Repository == To make changes to the source code, a developer must have a working repository. The repository may be on the same host as the team repository, or it may be on a separate host. The following example shows the steps for creating a repository in the same directory, ''/usr/local/projects/chimera/git'', as the team repository. Developer repositories do not need to be the the same directory as the team repository. The last argument to '''git clone''' specifies the location where the developer repository will be created and it may be a full path. However, the web server on plato is configured to simplify accessing files below ''/usr/local/projects/chimera/git'' (see NotYetWritten), for example, for viewing changes to HTML files; so it may be more convenient to have developer repositories there than elsewhere. After cloning the repository, it is necessary to initialize it for '''git flow''', the tool for managing branches. The '''-d''' flag specifies that the default branch names for development and feature branches be used. Even if there is no plan to use '''git flow''' operations, executing this command is useful since it checks out the '''develop''' branch rather than leaving the repository on the '''master''' branch, which should only be modified during releases. {{{#!html
franklin:~ conrad$ cd /usr/local/projects/chimera2/git franklin:git conrad$ git clone chimera2.git myrepo Initialized empty Git repository in /usr/local/projects/chimera2/git/myrepo/.git/ franklin:git conrad$ cd myrepo /usr/local/projects/chimera2/git/myrepo franklin:myrepo conrad$ git flow init -d Using default branch names. Which branch should be used for bringing forth production releases? - master Branch name for production releases: [master] Branch name for "next release" development: [develop] How to name your supporting branch prefixes? Feature branches? [feature/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] franklin:myrepo conrad$ ls -l total 36 drwxrwxr-x 4 conrad ferrin 3864 May 3 11:01 docs/ -rw-rw-r-- 1 conrad ferrin 183 May 3 11:01 index.html -rw-rw-r-- 1 conrad ferrin 657 May 3 11:01 Makefile drwxrwxr-x 2 conrad ferrin 3864 May 3 11:01 mk/ drwxrwxr-x 28 conrad ferrin 3864 May 3 11:01 prereqs/ -rw-rw-r-- 1 conrad ferrin 1262 May 3 11:01 README.rst drwxrwxr-x 7 conrad ferrin 3864 May 3 11:01 src/ -rwxrwxr-x 1 conrad ferrin 3589 May 3 11:01 vsvars.sh* drwxrwxr-x 3 conrad ferrin 3864 May 3 11:01 webdemo/}}} Alternatively, a developer may use a repository on his own workstation rather than plato. Below is an example of creating a clone on the remote host, loft, running Cygwin on Windows 7. The ssh agent has already been initialized, so no passwords are required. The steps after '''git clone''' are effective the same as the example above. {{{#!html
[loft - /e]$ git clone \ ssh://conrad@plato.cgl.ucsf.edu/usr/local/projects/chimera2/git/chimera2.git \ chimera2 Cloning into 'chimera2'... remote: Counting objects: 556, done. remote: Compressing objects: 100% (533/533), done. remote: Total 556 (delta 170), reused 275 (delta 16) Receiving objects: 100% (556/556), 311.17 MiB | 621 KiB/s, done. Resolving deltas: 100% (170/170), done. [loft - /e]$ cd chimera2 /e/chimera2 [loft - /e/chimera2]$ git flow init -d Using default branch names. Which branch should be used for bringing forth production releases? - master Branch name for production releases: [master] Branch name for "next release" development: [develop] How to name your supporting branch prefixes? Feature branches? [feature/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] [loft - /e/chimera2]$ ls -l total 26 -rw-r--r--+ 1 conrad None 657 May 3 10:51 Makefile -rw-r--r--+ 1 conrad None 1262 May 3 10:51 README.rst drwxr-xr-x+ 1 conrad None 0 May 3 10:51 docs/ -rw-r--r--+ 1 conrad None 183 May 3 10:51 index.html drwxr-xr-x+ 1 conrad None 0 May 3 10:51 mk/ drwxr-xr-x+ 1 conrad None 0 May 3 10:51 prereqs/ drwxr-xr-x+ 1 conrad None 0 May 3 10:51 src/ -rwxr-xr-x+ 1 conrad None 3589 May 3 10:51 vsvars.sh* drwxr-xr-x+ 1 conrad None 0 May 3 10:51 webdemo/}}} == Use ''develop'' Branch Directly for Development == == Use Feature Branch for Development == == Stash Modified Files before Switching Branches == == Use plato Repository to Coordinate Development on Multiple Hosts == Sometimes, a developer may use several hosts for development, ''e.g.'', a home machine, an office desktop and a laptop. '''git''' may be used to coordinate the changes made on different hosts. Rather than cloning directly from the team repository, the developer can create a plato clone first, ''e.g.'', ''myrepo''; then local repositories on each host may be cloned from ''myrepo''. Changes may then be pushed and pulled from the remote host to ''myrepo'' without making any changes to the team repository. For example, one can - make and commit a change at the office, - push the change to ''myrepo'' for pick up from home, - go home and pull the change from ''myrepo'', - continue development at home, - commit changes and push to ''myrepo'' so that they can be pulled from the office. Obviously, the coordinating repository does not need to reside on plato. However, it should be on a host that remains accessible from the network at all times so that changes may be pushed or pulled. The main thing to remember is that any branch that is being used in this coordinated fashion should be set up properly using - '''git push''' ''remote_name branch_name'' and - '''git branch --set-upstream''' ''branch_name remote_name/branch_name'' where ''remote_name'' is the '''git''' name for the coordinating repository. If the remote repositories are cloned from the coordinating repository, then the standard name ''origin'' may be used. == Create Team Repository == In this section, examples refer to ''/var/tmp/conrad/example'' since the actual path ''/usr/local/projects/chimera2/git'' is already in use. Examples in other sections of this document refer to the correct path. Create the bare '''git''' repository that will serve as the team repository for Chimera 2 source code. Note that the repository is created for sharing within a group. The '''chgrp''' command defines which group will have cloning and update privileges. The access permissions such as the setgid bit of directories (meaning files created will inherit the group of the parent directory) in the repository is maintained by '''git''' and should not require manual intervention. {{{#!html
franklin:example conrad$ cd /var/tmp/conrad/example franklin:example conrad$ git init --bare --shared=group chimera2.git Initialized empty shared Git repository in /var/tmp/conrad/example/chimera2.git/ franklin:example conrad$ chgrp -R chimdev chimera2.git franklin:example conrad$ ls -l total 4 drwxrwsr-x 7 conrad chimdev 3864 May 1 09:34 chimera2.git/}}} Create a bootstrap repository so that we can set up the initial configuration for the project. The reason this repository is temporary is that the push/pull linkage between local and remote branches need to be set up when the branches are created, but are handled automatically during cloning after they have been created. Since we will only use '''master''' and '''develop''' branches in the team repository, we can set them up now and developers who clone later will not have to worry about configuring the push/pull targets. {{{#!html
franklin:example conrad$ git clone --shared chimera2.git bootstrap Initialized empty Git repository in /var/tmp/conrad/example/bootstrap/.git/ warning: You appear to have cloned an empty repository. franklin:example conrad$ cd bootstrap /var/tmp/conrad/example/bootstrap franklin:bootstrap conrad$ ls -la total 12 drwxr-xr-x 3 conrad ferrin 3864 May 1 10:32 ./ drwxrwxr-x 5 conrad ferrin 3864 May 1 10:32 ../ drwxrwxr-x 7 conrad ferrin 3864 May 1 10:32 .git/}}} Use '''git flow''' to set up the branches in the bootstrap repository. After initialization, we are on the '''develop''' branch where we add our initial files; '''xyzzy''' is our only file in this example. The '''add -A''' command adds all modified and untracked files to the staging area; the '''commit''' command commits files in the staging area to the local repository; the '''push''' command pushes the state of the current branch from the local repository, '''bootstrap''', to the remote team repository, '''origin''', which represents the repository from which we are cloned ('''chimera2.git''' in this case). {{{#!html
franklin:bootstrap conrad$ git flow init -d Using default branch names. No branches exist yet. Base branches must be created now. Branch name for production releases: [master] Branch name for "next release" development: [develop] How to name your supporting branch prefixes? Feature branches? [feature/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] franklin:bootstrap conrad$ git status # On branch develop nothing to commit (working directory clean) franklin:bootstrap conrad$ echo hello > xyzzy franklin:bootstrap conrad$ git add -A franklin:bootstrap conrad$ git status # On branch develop # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: xyzzy # franklin:bootstrap conrad$ git commit -m "initial setup" [develop ff9b042] initial setup 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 xyzzy franklin:bootstrap conrad$ git push origin develop Counting objects: 5, done. Delta compression using up to 64 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (5/5), 384 bytes, done. Total 5 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (5/5), done. To /var/tmp/conrad/example/chimera2.git * [new branch] develop -> develop}}} Make the '''master''' branch match the '''develop''' branch. The '''checkout''' command is used to switch from one branch to another; note that this command only uses the __local__ repository and does not require access to the team repository. {{{#!html
franklin:bootstrap conrad$ git checkout master Switched to branch 'master' You have new mail in /var/spool/mail/conrad franklin:bootstrap conrad$ git merge develop Updating 76fd917..ff9b042 Fast-forward xyzzy | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 xyzzy franklin:bootstrap conrad$ git push origin master Total 0 (delta 0), reused 0 (delta 0) To /var/tmp/conrad/example/chimera2.git * [new branch] master -> master}}} At this point, the team repository set up is complete. All the files are under revision control and the bootstrap repository may be safely deleted. The team repository, '''chimera2.git''', with '''master''' and '''develop''' branches, is ready for by developers. Note that developers still have to set up and use '''git flow''' after cloning in order to follow the [http://nvie.com/posts/a-successful-git-branching-model/ Vincent Driessen's branching model] conveniently. {{{#!html
franklin:bootstrap conrad$ cd .. franklin:example conrad$ ls -l total 12 drwxr-xr-x 3 conrad ferrin 3864 May 1 11:19 bootstrap/ drwxrwsr-x 7 conrad chimdev 3864 May 1 09:34 chimera2.git/ franklin:example conrad$ rm -rf bootstrap}}}