Introduction
This is more than a fact, using ClearCase (not UCM) as main SCM for large projects maintained by few people is a pretty not efficient solution. When it's Corporate Standard, we are stuck with it and we need to find an efficient workaround.
The usual workflow with ClearCase consists of a master
branch, a develop
branch and several new feature branches.
o--------o (feature)
/ \
----o--o---o-----o----o (develop)
/ \ \
*----------o---------o (main)
Example
Actually, what I call a feature could be also a simple refactoring, such as a massive renaming inside the project. In this example, and because ClearCase is file-centric, we always need a temporary branch (no atomic checkin in non-UCM CC). Creating a new branch is painful and having the right config-spec is a struggling task. From here, I see two solutions:
Be corporate and start the massive checkout of all the files. Because the SCM environment does not reside on the same site as the ClearCase servers, everything gets slower. I count 2s per file and 8min for 1k files. After the first coffee break, we do the work and we check in all the files (another 8min wasted). Some tests, a new massive checkout, a bugfix, a massive checkin, the merge to the
develop
branch and eventually we delete thefeature
branch, which is no longer useful.In this solution, everything's slow, a lot of caffeine gets consumed and the workflow is pretty inefficient. I don't think this is a good solution.
Because we would like to keep a trace of our changes, and we do not want to waste time checkin/out all the project's files, we init a Git repository from a snapshot view. Actually, the Git repository could be located anywhere else ouside ClearCase. The changes are made locally with the help of Git and, once everthing's done, the project is pushed back on ClearCase with
clearfsimport
. After this, we still need to merge thefeature
branch. This is done in CC. The feature branch can then be deleted.This solution requires lots of manipulations. Also,
clearfsimport
can be very dangerous if we misspell the target view or if we forget to remove all the temporary files. Last but not least, the final merge has to be done on CC.
Snapshot Views
In my examples, I did not mentioned the Snapshot Views because they are not compatible with Git. A hijacked file identified based on its timestamp. If I manually modify a file and restore its original modification date, ClearCase won't see any changes. This could be very dangerous as the following example proves it.
If you don't believe me, you can try this:
stat -c 'touch --no-create -d "%y" "%n"' foo > restore_timestamp
echo "ClearCase will not see this" >> foo
source restore_timestamp
rm restore_timestamp
With this mechanism, no Git repository can reside inside a ClearCase Snapshot View.
Separated Git repository
I doubt we can find any workaround to the requirement for a temporary branch creation. The merge has to be done on ClearCase even though Git is holding everything behind.
I have tried to use the Copy/Paste extensively to synchronize a completely separated Git repository with ClearCase. Right before the final merge, I copy/paste the current state of the develop
branch in a new Git branch and do the merge as quickly as possible. At the end, I used clearfsimport
to push the modifications back to the develop
branch.
This operation could be very dangerous if someone wants to access the project during the merge process. For this reason, the development branch has to be locked or reserved during the operation. Unfortunately, this additional operation is very time consuming on ClearCase.
The ClearCase "git checkout -b feature" equivalent
In Git when I want to create a new branch I simply type:
git checkout -b feature
That's all, and I can work on my new feature right away. On ClearCase, things are a bit different.
First, I need to place a label where I want to create my branch. From Windows with Cygwin, I can do this:
LABEL=my_temporary_label
VOB=vob_name
cleartool mklbtype -global -nc lbtype:${LABEL}@\\${VOB}
cleartool mklabel -replace ${LABEL} `cleartool find . -cview -print -nxn | awk '{printf "%s ", $0}'`
cleartool find . -cview -type l -exec 'cleartool ls %CLEARCASE_XPN%' | \
perl -p -e 's/\\/\//g' | \
perl -p -e 's/\r//g' | \
perl -e 'while(<>) {s@([.]/)(.*/)(.*-->\s*)@$2@;print;}' | \
xargs -n1 cleartool mklabel ${LABEL}
However, we need to be careful because symbolic links are not expanded.
Then, a branch has to be created:
mkbrtype –c "Temporary Branch" my_temporary_branch
To work on this branch, a view need to be created:
cleartool mkview -tag my_temporary_view \\shared\path\to\viewStorage\my_temporary_view.vws
The config-spec has to be edited:
element * CHECKEDOUT
element .../lost+found -none
element * .../develop_branch/LATEST
mkbranch develop_branch
element * /main/A_LABEL_WHERE_THE_BRANCH_IS_BRANCHED_ON
element * /main/LATEST
end mkbranch develop_branch
Now, the branch is created. We can work on our feature. Easy, huh?
In Git, I usually create 3-5 branches a day. I don't think I can do the same with ClearCase. Am I wrong?
Discussion
The two proposed solutions are far from good because they all require a lot of time consuming operations on ClearCase (create a branch, set a view, checkin, checkout, do the merge, delete the branch).
I am looking for a solution that does not involve complex manipulations. And I still believe Git could be a good ally, but how can ClearCase and Git work together?
I think we can use some scripting. I recently found git-cc which could be a good start. Unfortunately, this project is not mature yet.
I haven't investigated this approach, but I think there is one solution where we can use a ClearCase Snapshot View with Git. The timestamp of each file has to be saved before making any changes:
find . -type f -exec stat -c 'touch--no-create -d "%y" "%n"' {} \; > restore
From there, we can work on Git and once it is time to push the changes on ClearCase or just pull the changes from from the development branch, the original timestamp can be restored on all files but the modified files by since the last synchronization:
source ./restore
git diff --name-only SHA1 SHA2 | xargs touch
The Question
On StackOverflow, people like precise questions, not primary opinion-based questions. Thus, after this pretty long introduction I eventually can ask my question:
I have tried many different approaches to improve my workflow with ClearCase but working on large projects with a file-centric SCM is not straightforward. I believe Git could help a lot, but I need to find a workflow that allows the synchronization of a local git
repository with ClearCase and, if possible, without requiring a temporary branch.
Can that be done?