这不仅仅是一个事实,使用ClearCase(不是UCM)作为主要SCM用于少数人维护的大型项目是一个非常有效的解决方案。当它是企业标准时,我们坚持使用它,我们需要找到一个有效的解决方法。
ClearCase的常用工作流程包括master
分支,develop
分支和几个新功能分支。
o--------o (feature)
/ \
----o--o---o-----o----o (develop)
/ \ \
*----------o---------o (main)
实际上,我称之为功能也可能是一种简单的重构,例如项目内部的大规模重命名。在这个例子中,因为ClearCase是以文件为中心的,所以我们总是需要一个临时分支(在非UCM CC中没有原子签入)。创建一个新的分支是痛苦的,拥有正确的config-spec是一项艰巨的任务。从这里,我看到两个解决方案:
成为公司并开始大量检查所有文件。由于SCM环境与ClearCase服务器不在同一站点上,因此一切都变慢。我计算每个文件2个,1个文件8分钟。在第一次喝咖啡休息后,我们完成工作并检查所有文件(另外8分钟浪费)。一些测试,新的大规模检查,错误修正,大规模签入,合并到develop
分支,最终我们删除feature
分支,这已不再有用。
在这个解决方案中,一切都很慢,大量的咖啡因被消耗掉,工作流程效率很低。我不认为这是一个很好的解决方案。
因为我们想要跟踪我们的更改,并且我们不想浪费时间检查/删除所有项目的文件,我们从快照视图初始化Git存储库。实际上,Git存储库可以位于其他任何地方,而不是ClearCase。这些更改是在Git的帮助下在本地进行的,一旦完成,项目将被clearfsimport
推回到ClearCase上。在此之后,我们仍然需要合并feature
分支。这是在CC完成的。然后可以删除功能分支。
此解决方案需要大量操作。此外,如果我们拼错目标视图或忘记删除所有临时文件,clearfsimport
可能会非常危险。最后但并非最不重要的是,最终的合并必须在CC上完成。
在我的示例中,我没有提到快照视图,因为它们与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快照视图中。
我怀疑我们是否可以找到创建临时分支的要求的任何解决方法。合并必须在ClearCase上完成,即使Git掌握了一切。
我试图广泛使用复制/粘贴来将完全独立的Git存储库与ClearCase同步。在最终合并之前,我将develop
分支的当前状态复制/粘贴到新的Git分支中,并尽快进行合并。最后,我使用clearfsimport
将修改推送回develop
分支。
如果有人想在合并过程中访问项目,则此操作可能非常危险。因此,必须在操作期间锁定或保留开发分支。不幸的是,这个额外的操作在ClearCase上非常耗时。
在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同步,如果可能的话,不需要临时分支。
能做到吗?
答案 0 :(得分:2)
在VonC的answer中,他建议不要使用中间分支并使用Git管理所有内容。
通过一个例子,我想展示他的方法。我们从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视图中。