Fasten your seat belts: Flying the Oracle Development Cloud Service (4 – In Flight 1)

In the last part of the series Fasten your seat belts: Flying the Oracle Development Cloud Service (3 – Take Off – ROTATE) we finished the work on the first cloud workspace, a utility project holding framework extension classes we use in the upcoming development. We created a branch to add the build system we can use in the cloud as well as on the developer’s machine.
The developer checked in all his/her changes, but did not merge the branch back into the mainline development (master). This part describes how this action, called a merge request, is done. This action can be used as a quality gate to review the code the developer has build.
After logging into the Oracle Developer Cloud as developer we select the ‘Merge Requests’ tab of the project

Merge Requests

Merge Requests


where we create a new request by clicking on the ‘New Request’ button. In the next dialog we fill in the needed data
Create Merge Request dialog

Create Merge Request dialog


The target branch is the branch we like the feature branch to be merged into, in our case it’s the branch called ‘master’. If you have other branches you like to merge you can do this too and later merge the whole merged feature branches back into the master branch. The ‘review Branch’ is the branch we want the review on, in our case the ‘feature-setup-build’ branch. In the ‘reviews’ field we must add at at least one member of the team, but can add multiple members if we like. Each of the reviewers then gets a notification via e-mail that a review is waiting.

The developer can only wait now for the action of the reviewers. Sure he can do something else like start another task for the project 🙂

The mails give some basic information about the request and the links to quickly access the cloud. After logging into the Cloud as reviewer the same ‘Merge Requests’ looks like

As we see, there now are the ‘Approve’ and ‘Reject’ buttons available for the Reviewer.
The reviewer should look at the changes made in the branch e.g. by looking at the commits for it.
Commits of the feature branch

Commits of the feature branch


As we don’t know what these files are doing, we reject the merge request

This will notify the developer who can and should act on the comment.

In this case the files are obsolete and can be deleted from the feature branch before merging (by the developer).

After changing the merge request by adding a hint that we delete the obsolete files, the reviewer again get some e-mails notifying him about this change.
Looking at the request after login, the reviewer approves the request and merges the branch into the master branch.

If we now look at the master branch we see the build files as part of the master branch.

One final thing to do is to switch the build system configuration from the feature branch to the master branch. When we started working on the feature we set up the build system to use the feature-setup-build branch. We now switch the build setup to use hte master branch.

This concludes this part of the series. Next we build a simple ‘normal’ ADF application in the cloud, applying what we have learned so far.

Advertisements

Fasten your seat belts: Flying the Oracle Development Cloud Service (3 – Take Off – ROTATE)

The last part of the series 3 – Take Off – V1 we finished when we could build hte application using ANT on the local machine. In this part we are going to try this on the Oracle Developer Cloud. Finally we should see how Continuous Integration and Continuous Delivery works in the cloud.

Alt NOTE
I created a fresh set of ANT build scripts named ‘buildlocal.xml’ and ‘buildlocal.properties’ from the project to demonstrate the process. The original ones name ‘build.xml’ and ‘build.properties’ are the final result which I didn’t want to revert. So when you create the ANT scripts yourself you can user the default names ‘build.xml’ and ‘build.properties’. When I talk about build files I now mean the ones named ‘buildlocal.*’.

Demo Build Files

Demo Build Files


For the same reason we create a new build job in the cloud names ADFTestBuild to show the steps to take. The final build job is named ADFCommunuityFrkExt.
Demo Build Job

Demo Build Job

We pushed the files local build files already to the remote repository. Let’s run the build on the could. First we log into the Oracle Developer Cloud as team member and switch to the build tab and create a new build job (ADFTestBuild)


Note that we use JDK 7 to build the project. The Oracle Developer Cloud offers JDK 6-8 to work with. As we use JDev 12.1.3 we use JDK 7
JDK's available

JDK’s available


In the Source Code Management section we select the repository and branch to use for this job. The advanced section can be left blank as it’s filled by the system when you save the job. There are more advanced option you can set but they are not part of this post. All we nach to remember

Alt NOTE
Builds are dependent on ONE branch

Alt NOTE
The Build Trigger defines that each minute the CI system checks the SCM if something has changed. If yes, it schedules to execute the build job.

When we are finished with the feature we have to change the build job or to create a new one which uses the master or default branch to build on. In our situation where we implement the CI we set the branch to the one we are working on named ‘feature-setup-build’.

After saving the new job we can start it by clicking on the ‘Run Now’ button


Hm, the build did not work as it did on the local machine. This is shown by the icon in the first column of the job history table. To find out what went wrong we look at the output of the build by clicking on the ‘console’ button in the last column of hte table
Build output

Build output


In the first marked section we see the build file ‘buildlocal.xml’ which was used and in the second marked section the error message. It looks liek the build job can’t find the task ‘OJDeployAntTask’. A look into the buildlocal.xml file at line 40 reveals

   <taskdef name="ojdeploy" classname="oracle.jdeveloper.deploy.ant.OJDeployAntTask" uri="oraclelib:OJDeployAntTask"
             classpath="${oracle.jdeveloper.ant.library}"/>

where line 40 is the classpath in the above listing. This means that the variable “${oracle.jdeveloper.ant.library}” is not found. A look into the Oracle Developer Cloud at Developing Oracle ADF Applications with Oracle Developer Cloud Service give the needed information. We have to alter the build files
1. add a line

<property environment="env"/>

to the build.xml file before loading the build.properties
2. change the build.properties file to use information from the now loaded environemnt
The second part is a bit confusing. From the link above we learn to set a variable as
oracle.home=${env.ORACLE_HOME}
which is misleading a bit. The problem is that the developer cloud offers two environments to the user. One for 11g and one for 12c. As we use the one for 12c we have to use a different setup which can be found in the docs too at a different location Using Hudson Environment Variables. The second link tells us to use
oracle.home=${env.ORACLE_HOME12C3}

Alt NOTE
Add property environment="env" to your build.xml to load the environment of the server
Alt NOTE
Add
oracle.home=${env.ORACLE_HOME_12C3}
oracle.commons=${env.MIDDLEWARE_HOME_12C3}/oracle_common
middleware.home=${env.MIDDLEWARE_HOME_12C3}
install.dir=${env.ORACLE_HOME_12C3}
to the build.properties file to make use of hte servers environment.

With this info we can make the needed changes. The resulting build.properties is

#Fri Jul 24 15:06:08 CEST 2015
#Change the next three properties to match your projects names
workspace.name=ADFCommunityFrkExt
workspace=${env.WORKSPACE}
project.viewcontroller.name=FrkExtModel
project.deploy.folder=deploy
oracle.jdeveloper.deploy.profile.name=adflibADFCommunityFrkExt
output.dir=classes

# Don't change anything below!
oracle.home=${env.ORACLE_HOME_12C3}
oracle.commons=${env.MIDDLEWARE_HOME_12C3}/oracle_common
middleware.home=${env.MIDDLEWARE_HOME_12C3}
install.dir=${env.ORACLE_HOME_12C3}

#Flags
javac.deprecation=off
javac.nowarn=off
java.debug=on

project.workspace.file=${workspace.name}.jws
oracle.jdeveloper.ant.library=${oracle.home}/jdev/lib/ant-jdeveloper.jar
oracle.jdeveloper.workspace.path=${workspace}/${workspace.name}.jws
oracle.jdeveloper.project.name=${project.viewcontroller.name}
oracle.jdeveloper.deploy.dir=${workspace}/${project.deploy.folder}
oracle.jdeveloper.ojdeploy.path=${env.ORACLE_HOME_12C3}/jdev/bin/ojdeploy${env.EXEC_SUFFIX}
oracle.jdeveloper.deploy.outputfile=${workspace}/${project.deploy.folder}/${oracle.jdeveloper.deploy.profile.name}

and the build.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!--Ant buildfile generated by Oracle JDeveloper-->
<!--Generated Aug 22, 2015 3:15:37 PM-->
<project xmlns="antlib:org.apache.tools.ant" name="FrkExtModel" default="all" basedir=".">
  <property environment="env"/>
  <property file="build.properties"/>
  <path id="library.ADF.Model.Runtime">
    <pathelement location="${oracle.commons}/modules/oracle.idm_12.1.3/identitystore.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.model_12.1.3/adfm.jar"/>
    <pathelement location="${oracle.commons}/modules/groovy-all-2.1.6.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.model_12.1.3/adftransactionsdt.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.view_12.1.3/adf-dt-at-rt.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.model_12.1.3/adfdt_common.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.model_12.1.3/adflibrary.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.xdk_12.1.3/xmlparserv2.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.model_12.1.3/db-ca.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.model_12.1.3/jdev-cm.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.ldap_12.1.3/ojmisc.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.share_12.1.3/commons-el.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.share_12.1.3/jsp-el-api.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.share_12.1.3/oracle-el.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.security_12.1.3/adf-share-security.jar"/>
    <pathelement location="${oracle.commons}/modules/oracle.adf.security_12.1.3/adf-controller-security.jar"/>
    <pathelement location="${oracle.commons}/modules/javax.mail_2.0.0.0_1-4-4.jar"/>
  </path>
  <path id="classpath">
    <path refid="library.ADF.Model.Runtime"/>
  </path>
  <target name="init">
    <tstamp/>
    <mkdir dir="${output.dir}"/>
  </target>
  <target name="info">
    <echo level="info">build: env.ORACLE_HOME=${env.ORACLE_HOME_12C3}</echo>
    <echo level="info">build: env.WORKSPACE=${env.WORKSPACE}</echo>
    <echo level="info">build: workspace=${workspace}</echo>
    <echo level="info">build: install.dir=${env.ORACLE_HOME_12C3}</echo>
    <echo level="info">build: oracle.commons=${oracle.commons}</echo>
    <echo level="info">build: oracle.jdeveloper.ant.library=${oracle.jdeveloper.ant.library}</echo>
    <echo level="info">build: oracle.jdeveloper.ojdeploy.path=${oracle.jdeveloper.ojdeploy.path}</echo>
    <echo level="info">build: oracle.jdeveloper.deploy.dir=${oracle.jdeveloper.deploy.dir}</echo>
    <echo level="info">build: oracle.jdeveloper.deploy.profile.name=${oracle.jdeveloper.deploy.profile.name}</echo>
    <echo level="info">build: oracle.jdeveloper.workspace.path=${oracle.jdeveloper.workspace.path}</echo>
    <echo level="info">build: oracle.jdeveloper.deploy.outputfile=${oracle.jdeveloper.deploy.outputfile}</echo>
  </target>
  <target name="all" description="Build the project" depends="info,deploy,compile,copy"/>
  <target name="clean" description="Clean the project">
    <delete includeemptydirs="true" quiet="true">
      <fileset dir="${output.dir}" includes="**/*"/>
    </delete>
  </target>
  <target name="deploy" description="Deploy JDeveloper profiles" depends="init">
    <taskdef name="ojdeploy" classname="oracle.jdeveloper.deploy.ant.OJDeployAntTask" uri="oraclelib:OJDeployAntTask"
             classpath="${oracle.jdeveloper.ant.library}"/>
    <ora:ojdeploy xmlns:ora="oraclelib:OJDeployAntTask" executable="${oracle.jdeveloper.ojdeploy.path}"
                  ora:buildscript="${oracle.jdeveloper.deploy.dir}/ojdeploy-build.xml"
                  ora:statuslog="${oracle.jdeveloper.deploy.dir}/ojdeploy-statuslog.xml">
      <ora:deploy>
        <ora:parameter name="workspace" value="${oracle.jdeveloper.workspace.path}"/>
        <ora:parameter name="project" value="${oracle.jdeveloper.project.name}"/>
        <ora:parameter name="profile" value="${oracle.jdeveloper.deploy.profile.name}"/>
        <ora:parameter name="nocompile" value="false"/>
        <ora:parameter name="outputfile" value="${oracle.jdeveloper.deploy.outputfile}"/>
      </ora:deploy>
    </ora:ojdeploy>
  </target>
  <target name="compile" description="Compile Java source files" depends="init">
    <javac destdir="${output.dir}" classpathref="classpath" debug="${javac.debug}" nowarn="${javac.nowarn}"
           deprecation="${javac.deprecation}" encoding="UTF8" source="1.7" target="1.7" includeantruntime="false">
      <src path="src"/>
    </javac>
  </target>
  <target name="copy" description="Copy files to output directory" depends="init">
    <patternset id="copy.patterns">
      <include name="**/*.GIF"/>
      <include name="**/*.JPEG"/>
      <include name="**/*.JPG"/>
      <include name="**/*.PNG"/>
      <include name="**/*.cpx"/>
      <include name="**/*.dcx"/>
      <include name="**/*.ejx"/>
      <include name="**/*.gif"/>
      <include name="**/*.ini"/>
      <include name="**/*.jpeg"/>
      <include name="**/*.jpg"/>
      <include name="**/*.png"/>
      <include name="**/*.properties"/>
      <include name="**/*.sva"/>
      <include name="**/*.tag"/>
      <include name="**/*.tld"/>
      <include name="**/*.wsdl"/>
      <include name="**/*.xcfg"/>
      <include name="**/*.xlf"/>
      <include name="**/*.xml"/>
      <include name="**/*.xsd"/>
      <include name="**/*.xsl"/>
      <exclude name="build.xml"/>
    </patternset>
    <copy todir="${output.dir}">
      <fileset dir="src">
        <patternset refid="copy.patterns"/>
      </fileset>
      <fileset dir=".">
        <patternset refid="copy.patterns"/>
      </fileset>
    </copy>
  </target>
</project>

The files above are the original ones and can be run from the build console to get this

Great, we now have successfully enabled CI in the cloud for the ‘Framework Extension’ project. Well, there is something more to think about. Can’t we use the same ANT build scripts on the local machine too?

Yes, we can but we have to make some adjustments for this.

Now that we read the environment from the server the ANT script is running on to set the some of the variables we need to set these environment variables on the local machine too. this can be done easily by altering the jdev start file (Linux) or using a batch to first set the environment variables and then start jdev (Windows). Below is my changes jdev start script

#!/bin/bash

#=============================================================================
#  Launcher for Oracle JDeveloper 12c (12.1.2.0.0)
#=============================================================================

unset -v GNOME_DESKTOP_SESSION_ID
export MIDDLEWARE_HOME_12C3=/opt/jdev/12.1.3.0.0/Oracle/Middleware
export ORACLE_HOME_12C3=/opt/jdev/12.1.3.0.0/Oracle/Middleware/Oracle_Home/jdeveloper
export WORKSPACE=/data/development/ENTW_12.1.3.0.0
export EXEC_SUFFIX=
/opt/jdev/12.1.3.0.0/Oracle/Middleware/Oracle_Home/jdeveloper/jdev/bin/jdev $1

As you see I set the environment variables which are later read through the build.xml file before starting jdeveloper.
The one line
export EXEC_SUFFIX=
need special attention. It’s only necessary if you run JDev using different operating systems (Linux and Windows). The build file has one variable pointing to the the ojdeploy executable
oracle.jdeveloper.ojdeploy.path=${env.ORACLE_HOME_12C3}/jdev/bin/ojdeploy${env.EXEC_SUFFIX}
Users using Windows need to add the suffix ‘.exe’ to this variable as ojdeploy can’t be started otherwise under Windows.
The problem is that we can’t add it for Linux systems as they don’t know this suffix. The solution I found is to add ${env.EXEC_SUFFIX} to the executable and set it to an empty string for Linux systems. For Windows systems you have to set this environment variable to ‘.exe’. For this I use a batch file where I use
~~~setx EXEC_SUFFIX .exe~~~
before starting JDev. In the same batch I set the other variables too

setx ORACLE_HOME_12C3 r:\Java\12.1.3.0.0\Oracle\Middleware\jdeveloper
setx MIDDLEWARE_HOME_12C3 r:\Java\12.1.3.0.0\Oracle\Middleware
setx EXEC_SUFFIX .exe

Alt NOTE
To make the build files work under Windows and Linux and iOS add an environment variable defining the suffix for executable files.

One final trick is to set the workspace directory. The build.properties file has one more environment variable workspace=${env.WORKSPACE} which we need to set.
As the workspace isn’t fix on a local machine, at least if you have more than one workspace, you can’t set this variable before you start JDev. This has to be done per workspace, when you change the workspace.
JDev has a solution for this in the ANT properties section

ANT Project Properties

ANT Project Properties


You can shoose from different variables JDev sets according to the workspace and project you are working with.
JDeveloper Variables

JDeveloper Variables

Alt NOTE
Set the env.WORKSPACE environment variable in the ANT properties of the project.

This concludes this part of the series. In the next post we finish the feature ‘feature-setup-build’ by introducing the code review function of the Oracle Developer Cloud. This will be followed by a post about building a simple ADF application with a UI which you use to show the Continuous Delivery (CD) option of the Oracle Developer Cloud.

JDeveloper 11.1.1.6.0: The Git Experience (Part 2)

End of November Oracle released a new JDeveloper version 11.1.1.6.0 Build 6229 (What’s new 11.1.1.6.0) which introduces Git support as one of the new features.
Part 1 showed how to setup and use git integration in JDeveloper
In part 2 of the series I show how branching and merging are done using the git integration in JDeveloper.

Let’s start with a picture of the current git repository:

Repository at Start

Repository at Start

Here is the first missing part in JDeveloper’s git integration. There is no visual representation of the whole repository available as shown in the image above. To get such a representation we need to install a third party tool (msysGit in my case, or Tortoise Git which can run in parallel on a Win7 machine). JDeveloper only allows you to see the history of one file via the ‘Version History’ menu. The images of the repository we’ll see in this blog are done with msysGit.

As we see there is only one branch named ‘Master’ and we see a straight line of dots, each representing a commit to the ‘Master’ branch. We start by adding a new branch to the repository named ‘AddCalcuatorClass’. The name of the branch can be almost anything, as long as it doesn’t contain spaces. We choose the name of a branch so that it reminds us later why we created the branch, or what it’s used for. As the name of the branch indicates we add a class to the project which implements a simple calculator.

Create New Branch

Create New Branch

Name the new branch ‘AddCalcuatorClass’

Name Branch

Name Branch

The ‘Application Navigator’ did not change, but the new branch is visible in the ‘Version Navigator’ in JDevelpoer

Version Navigator

Version Navigator

the same from the view of msysGit:

msysGit Repository after adding new Branch

msysGit Repository after adding new Branch

We need to play close attention to the different views and what they tell us. In JDeveloper we still see ‘[master]’ behind the project name. This tells us that we are still working on the ‘master’ branch and not the new created branch ‘AddCalculatorClass’. The msysGit image shows the same as the ‘master’ branch is printed in bold (which it does for the current branch).
To switch to the new branch we need to checkout the branch.

Checkout Branch

Checkout Branch

then click the ‘Select Branch’ button in the dialog to get to the available branches and select the ‘AddCalculatorClass’ and click ‘OK’, finally close the dialog by clicking ‘OK’ again.

Select Branch

Select Branch

After that we are working on the ‘AddCalculatorClass’ branch, only we don’t see it right away. We need to refresh the project (e.g. clicking the refresh button) to see the ‘[AddCalculatorClass]’ right to the project name.

Now working on 'AddCalaculatorClass' Branch

Now working on ‘AddCalaculatorClass’ Branch

Again the msysGit image:

msysGit: new active Branch

msysGit: new active Branch

Now we add a new class ‘Calculator’ to the project. For this we add the new class from the ‘Candidate’ tab and then commit the new file by committing it

Add new Class to Project and Repository

Add new Class to Project and Repository

Add new File

Add new File

Commit

Commit

Commit dialog

Commit dialog

Repository after adding new File

Repository after adding new File

Now we add an other method in the calculator class which should multiply to parameters and return the result. After that we commit the change and the repository looks like:

Repository after Change of Calculator Class

Repository after Change of Calculator Class

Let’s assume that we have to fix a bug in the main development path, which is ‘master’. We have to switch back to the ‘master’ branch. This is done by checking out the ‘master’ branch again. The procedure is the same we already saw before. The result in JDeveloper looks like:

Back on Branch 'master'

Back on Branch ‘master’

msysGit: Back to 'master'

msysGit: Back to ‘master’

As we see the new class ‘Calculator’ is not part of the project as it was not added in the ‘master’ branch. Back to the ‘master’ branch we add another class ‘Stack.java’ and add some lined to the existing class. After committing the changes, in multiple commit cycles to get a better visibility of the different branches, the repository look like:

Repository after change to 'master'

Repository after change to ‘master’

Let’s switch back to the ‘AddCaclulatorClass’ branch to finish the work on this class by adding two more methods to subtract and divide to parameters. After this work is done the repository look like:

Repository after more work don in 'AddCalculatorClass' Branch

Repository after more work don in ‘AddCalculatorClass’ Branch

A requirement is that we need the changes done in the ‘master’ branch now need in our current branch ‘AddCalculatorClass’. For this we need to merge the branch ‘master’ to the current branch ‘AddCalculatorClass’. This is easily archived by opening the ‘Version Navigator’, open the node of the project and then the open the ‘Branches’, ‘Local’node. Here we see the currently available branches ‘master’ and ‘AddCalculatorClass’. The same can be archived by right clicking the Project and select ‘Versioning->Merge…’.

Merge 'master' Branch

Merge ‘master’ Branch

Merge

Merge

After Merge

After Merge

Don’t forget to refresh the project to see the added class. The resulting repository now looks like

Repository after Merge

Repository after Merge

with all changes made to the branch ‘master’ including the new class Stack. We could have done the merge the other way around. Then we had to checkout branch ‘master’ and then merge branch ‘AddCalculatorClass’. This would give us a repository looking like:

Merge 'AddCalculatorClas' to 'master'

Merge ‘AddCalculatorClas’ to ‘master’

The difference at this moment is, that the changes are visible in the ‘master’ branch and which branch is active after the merge. We can create another branch from every other tag or branch currently present in the repository. Let’s make a new branch ‘DoCalcDifferent’ from the ‘master’ branch. Remember that we are currently in branch ‘AddCalculatorClass’. Still we are able to create the new branch. We can also create a branch based onany other branch like ‘AddCalculatorClass’ which we call ‘AddCalc2’. A look at the repository after all this:

Branch Festival

Branch Festival

We see it’s easy to create new branches, switch between them to do some work, merge the different branches without problems. Make yourself familiar with the technique and how to use it. This is especially true after some wild changes to different branches. We may end up with a confusing repository like

Complex Repository after some changes

Complex Repository after some changes

where it’s not obvious which change created which node in the repository. It may take a while, but in the end it’s much easier then it looks and it’s more productive then SVN or CVS.

Learning to use git the integration into JDeveloper is a good start. However, we need some of the other git commands (e.g. cherry pick) or representations (gitk to view the whole repository) integrated into JDeveloper to make it really a great tool integration.

I have planned a third part for this series, but can’t really tell when it is going to happen. This 3rd part covers remote git repositories which add a new dimension to the git picture. Right now I don’t have a remote git repository available. I’m looking into this issue in the next couple of days/weeks and hopefully get one installed and running.

JDeveloper 11.1.1.6.0: The Git Experience (Part 1)

End of November Oracle released a new JDeveloper version 11.1.1.6.0 Build 6229 (What’s new 11.1.1.6.0) which introduces Git support as one of the new features.

After a short break in my busy schedule I tried out the new Git support and decided to write a multi part blog series about it. First I thought about writing it all up in one post, but the plenty available options would make this more like a book ;). So in this first part I run through the basics of Git support in JDeveloper, showing how to version an application using Git (locally), make changes to the project and show some parts which need some improvement from Oracle. The next part drills into branching and merging of projects and remote Git repositories.

Lets start with the obvious, a look at the available documentation. You find the documentation in the ‘Developing in Teams’ section of the JDeveloper internal documentation which is available via the ‘Help’ menu. You can search for ‘git’ using the ‘Help’ menu to get there fast. Looking at the first chapter it looks like Git has not added to all available topics. The ‘About the Available Versioning Systems’ only shows SVN, Concurrent Version System (CVS), Perforce, Serena Dimensions, ClearCase and Team System. However I assume that this will be fixed in an upcoming version of JDeveloper. There are more thinks which need to be reviewed in my opinion. I point them out whenever I talk about the specific topic.
A new chapter ‘Using Git with JDeveloper’ has been added which covers the basics of working with Git. My first impression is that the doc is written from the point of view of the Team extensions for JDeveloper because I couldn’t find the ‘Team’ menu as I don’t have a Team server available on my laptop. However, most options are reachable through right clicks, which then reveals the ‘Team’ menu, or at least parts of it. I encourage you to at least scan this documentation. If you never heard of Git you should search the Web for a introduction to Git first.

Leaving the documentation, lets start to play with Git. A short overview over the configuration option of Git:

GIT Options Page 1

GIT Options Page 1

This first page gives you the option to define some default text which the you can use when committing changes to the reposritory. Once you add a template they are shown in the dialog. like in the image below. I didn’t find out if you can add some tags to the templates which expand later to text like ‘author’. In my sample the text is not very intelligent, but it’s only to show the feature. The ‘/’ you see are line breaks which are added in the template.

GIT Options Page 2

GIT Options Page 2

GIT Options Page 3

GIT Options Page 3

GIT Options Page 4

GIT Options Page 4

As you see there isn’t much to configure in the global options. All other configurations are done on application level which we start looking into right now. We start with a test case, an generic Java application, which consists of just one Java class with a main function at the beginning.

Test Java class

Test Java class

As with SVN we start with ‘Versioning’ the application which we reach via a right click on the application work space, or the ‘Application’ menu, then use the ‘Version…’ menu.

'Version Application...'

‘Version Application…’

now we see Git as possible version control system

Hello Git

Hello Git

Now we follow the wizard

Git Import Wizard Page 1

Git Import Wizard Page 1

Git Import Wizard Page 2

Git Import Wizard Page 2

Git Import Wizard Page 3

Git Import Wizard Page 3

Git Import Wizard Page 4

Git Import Wizard Page 4

That’s it, easy enough. Now we see that the application is under source code control

Application after import

Application after import

and we find the first difference from the SVN view. We see that the project uses the ‘master’ version which is equal to the SVN ‘trunk’ version. Opening the tree in the ‘Version Control’ panel, we see the branches node and below it the local branch where we see the ‘master’ version.

OK, next we start to make some changes. First lets add a public method to the sole Java class. Right after this, save the change and open the ‘Pending Changes’ panel to see if the change is visible there.

First Change

First Change

Next we need to commit the change to the local repository. For this we have some image buttons:

Image Buttons to work with changes

Image Buttons to work with changes

the green plus sign is used to add files to the ‘staged index’. The ‘staged index’ holds all files which are later committed in one transaction. I call this a ‘commit set’. The button next one opens the commit dialog where you add a comment to the commit set. If you click the commit button right of the green plus sign you see the commit dialog, together with the changed file, but committing will tell you that there is nothing to commit from the ‘staged index’ or the ‘commit set’. That’s a difference to the SVN work flow. Using Git, changed files are first staged in an index, or a commit set. Only after this you can commit all files in the index or set together in one transaction.

Clicking the green plus sign opens a dialog which lets you add changes files. However, when you check the help for this dialog you get a kind of confusing help which tell you that you use this dialog if you add new files to the repository. This is not the case, so lets ignore this and add the changes file.

Add File Dialog and Help

Add File Dialog and Help

Once the file is added to the ‘commit set’ or ‘staged index’ you’ll notice, that the green plus sign gets gray, still the file is visible in the pending changes panel. Only after clicking the ‘commit’ button, right of the green plus button, adding a comment, or selecting one from the predefined templates, and closing the dialog with the OK button, the panels gets cleared. At this point the change is committed in the local repository.
To visualize this open the ‘Version History’ of the Java class:

Get Version Histroy

Get Version Histroy

and we’ll see all versions which we can filter using the filter select one choice at top of the panel.

Version Histroy

Version Histroy

Lets check the differences between the two versions:

Difference between versions

Difference between versions

This all looks like the we know it from SVN.

Finally, to conclude this first part lets check if we can work with an external Git application too. For this test I use msysgit and GitGui which comes together with the installation. The image below shows the change before the last commit

GitGui

GitGui

After some commits with msysgit we again look at the version history of the Java class

Version Histroy after msysgit commit

Version Histroy after msysgit commit

Thankfully, the two different applications (JDeveloper and msysgit) are working well together. Up to now I have not found anything which make working with the different apps break the whole version control system. That is a big step forward!

That’s it for the first part. Stay tuned for the next part where I show how to clone a repository from a remote Git server and how to work with branches.