使用ClearCase和Git实现理想的工作流程

时间:2015-02-02 15:07:04

标签: git clearcase

简介

这不仅仅是一个事实,使用ClearCase(不是UCM)作为主要SCM用于少数人维护的大型项目是一个非常有效的解决方案。当它是企业标准时,我们坚持使用它,我们需要找到一个有效的解决方法。

ClearCase的常用工作流程包括master分支,develop分支和几个新功能分支。

        o--------o (feature)
       /          \
  ----o--o---o-----o----o (develop)
 /        \         \
*----------o---------o (main)

实施例

实际上,我称之为功能也可能是一种简单的重构,例如项目内部的大规模重命名。在这个例子中,因为ClearCase是以文件为中心的,所以我们总是需要一个临时分支(在非UCM CC中没有原子签入)。创建一个新的分支是痛苦的,拥有正确的config-spec是一项艰巨的任务。从这里,我看到两个解决方案:

  1. 成为公司并开始大量检查所有文件。由于SCM环境与ClearCase服务器不在同一站点上,因此一切都变慢。我计算每个文件2个,1个文件8分钟。在第一次喝咖啡休息后,我们完成工作并检查所有文件(另外8分钟浪费)。一些测试,新的大规模检查,错误修正,大规模签入,合并到develop分支,最终我们删除feature分支,这已不再有用。

    在这个解决方案中,一切都很慢,大量的咖啡因被消耗掉,工作流程效率很低。我不认为这是一个很好的解决方案。

  2. 因为我们想要跟踪我们的更改,并且我们不想浪费时间检查/删除所有项目的文件,我们从快照视图初始化Git存储库。实际上,Git存储库可以位于其他任何地方,而不是ClearCase。这些更改是在Git的帮助下在本地进行的,一旦完成,项目将被clearfsimport推回到ClearCase上。在此之后,我们仍然需要合并feature分支。这是在CC完成的。然后可以删除功能分支。

    此解决方案需要大量操作。此外,如果我们拼错目标视图或忘记删除所有临时文件,clearfsimport可能会非常危险。最后但并非最不重要的是,最终的合并必须在CC上完成。

  3. 快照视图

    在我的示例中,我没有提到快照视图,因为它们与Git不兼容。基于其时间戳识别的被劫持文件。如果我手动修改文件并恢复其原始修改日期,ClearCase将无法看到任何更改。这可能是非常危险的,如下面的例子证明的那样。

    如果你不相信我,你可以试试这个:

    stat -c 'touch --no-create -d "%y" "%n"' foo > restore_timestamp
    echo "ClearCase will not see this" >> foo
    source restore_timestamp
    rm restore_timestamp
    

    使用此机制,没有Git存储库可以驻留在ClearCase快照视图中。

    分离的Git存储库

    我怀疑我们是否可以找到创建临时分支的要求的任何解决方法。合并必须在ClearCase上完成,即使Git掌握了一切。

    我试图广泛使用复制/粘贴来将完全独立的Git存储库与ClearCase同步。在最终合并之前,我将develop分支的当前状态复制/粘贴到新的Git分支中,并尽快进行合并。最后,我使用clearfsimport将修改推送回develop分支。

    如果有人想在合并过程中访问项目,则此操作可能非常危险。因此,必须在操作期间锁定或保留开发分支。不幸的是,这个额外的操作在ClearCase上非常耗时。

    ClearCase" git checkout -b功能"等效

    在Git中,当我想创建一个新分支时,我只需输入:

     git checkout -b feature
    

    这就是全部,我可以马上处理我的新功能。在ClearCase上,事情有点不同。

    首先,我需要在我想要创建分支的位置放置标签。从带有Cygwin的Windows,我可以这样做:

    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}
    

    但是,我们需要小心,因为符号链接不会扩展。

    然后,必须创建一个分支:

    mkbrtype –c "Temporary Branch" my_temporary_branch 
    

    要处理此分支,需要创建视图:

    cleartool mkview -tag my_temporary_view \\shared\path\to\viewStorage\my_temporary_view.vws
    

    必须编辑config-spec:

    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
    

    现在,分支已创建。我们可以处理我们的功能。好吗,对吧?

    在Git中,我通常每天创建3-5个分支。我不认为我可以用ClearCase做同样的事情。我错了吗?

    讨论

    这两个提议的解决方案远非好,因为它们都需要在ClearCase上进行大量耗时的操作(创建分支,设置视图,签入,签出,进行合并,删除分支)。

    我正在寻找一种不涉及复杂操作的解决方案。我仍然认为Git可能是一个好伙伴,但ClearCase和Git如何一起工作?

    我认为我们可以使用一些脚本。我最近发现git-cc这可能是一个好的开始。不幸的是,这个项目尚未成熟。

    我还没有调查过这种方法,但我认为有一种解决方案可以让我们使用带有Git的ClearCase Snapshot View。在进行任何更改之前,必须保存每个文件的时间戳:

     find . -type f -exec stat -c 'touch--no-create -d "%y" "%n"' {} \; > restore
    

    从那里,我们可以使用Git,一旦是时候推动ClearCase上的更改或者只是从开发分支中提取更改,原始时间戳就可以恢复到所有文件,但是自上次以来修改后的文件同步:

     source ./restore
     git diff --name-only SHA1 SHA2 | xargs touch
    

    问题

    在StackOverflow上,人们喜欢精确的问题,而不是基于意见的主要问题。因此,经过这么长时间的介绍,我最终可以问我的问题:

    我尝试了许多不同的方法来改进我的工作流程,但使用ClearCase但是使用以文件为中心 SCM 的大型项目并不简单。我相信Git可以提供很多帮助,但我需要找到一个工作流,它允许本地git存储库与ClearCase同步,如果可能的话,不需要临时分支。

    能做到吗?

2 个答案:

答案 0 :(得分:2)

来自VonC

的可能解决方案

VonCanswer中,他建议不要使用中间分支并使用Gi​​t管理所有内容。

通过一个例子,我想展示他的方法。我们从ClearCase上的这个配置开始:

  o------o----o (develop)
 /        \ 
*----------o (main)

我们的想法是使用Git来促进最终合并到develop分支的新功能的开发。

我们首先将ClearCase项目复制到本地文件夹并初始化一个Git存储库(如果Git存储库尚不存在)。

WORKSPACE=~/foo
cp `cleartool ls -r | grep '@@' | sed 's/@@.*$//'` $WORKSPACE
cd $WORKSPACE
git init
git add .
git commit -m "Initial commit"
git checkout -b feature

我们花了一些时间在自己的本地Git分支上开发该功能:

                  x----x--x---x----x (feature on Git)
                 /
                x---------- (master on Git)
               /
  o------o----o------o----o (develop)
 /        \ 
*----------o (main)

在一天结束时,是时候从ClearCase中同步可能的更改了:

git checkout master
git --ls-files | xargs rm
cd $CCVIEW
cleartool ls -r | grep '@@' | sed 's/@@.*$//' > $WORKSPACE/ccview
cd $WORKSPACE
cat ccview | xargs -n1 cp {} $WORKSPACE    
cat ccview | xargs git add 
git commit -m "Imported from CC"

现在我们在feature分支上进行了多次提交,master Git分支与ClearCase同步。

                  x----x--x---x----x (feature on Git)
                 /
                x-----------o (master on Git)
               /           /
  o------o----o------o----o (develop)
 /        \ 
*----------o (main)

我们不要忘记在整个合并过程中锁定ClearCase View。这是为了防止其他开发人员看到clearfsimport删除自己的更改。要锁定ClearCase分支,这很容易:

cleartool lock brtype:$BR_NAME 

然后可以在Git上完成合并:

git checkout master
git merge feature

feature Git分支与master合并。

                  x----x--x---x----x (feature on Git)
                 /                  \
                x-----------o--------o (master on Git)
               /           /
  o------o----o------o----o (develop)
 /        \ 
*----------o (main)

可以将修改推回到ClearCase

OUT="$(mktemp -d)"
cp -v --parents `git ls-files | sed 's/[^ ]*\.gitignore//g'` $OUT
clearfsimport -comment 'clearfsimport' -rec -unco -nset $OUT $CVIEW    
rm -rf $OUT

可以删除锁定以重新授权分支上的更改

cleartool unlock brtype:$BR_NAME

                  x----x--x---x----x (feature on Git)
                 /                  \
                x-----------o--------o (master on Git)
               /           /          \
  o------o----o------o----o------------o (develop)
 /        \ 
*----------o (main)

除非我们需要继续,否则可能会删除Git存储库和本地工作区。

  o------o----o------o----o------------o (develop)
 /        \ 
*----------o (main)

在此解决方案中,我们没有在ClearCase上使用中间分支,并且所有合并过程都发生在Git上。 ClearCase历史记录保留。唯一不好的一点是需要锁定开发分支以进行最终合并。

@VonC,如果我错了,请随时修改我的答案。

答案 1 :(得分:1)

  

实际上,我称之为功能也可能是一种简单的重构,例如项目内部的大规模重命名。在这个例子中,因为ClearCase是以文件为中心的,所以我们总是需要一个临时分支(在非UCM CC中没有原子签入)。
  创建一个新的分支是痛苦的,拥有正确的config-spec是一项艰巨的任务

所以......不要创建一个临时分支? 如果要与Git合作使用,只需在Git仓库中创建该功能分支,在Git Repo中进行最终合并,然后然后 clearfsimport结果在主ClearCase视图中。