git提取出两个版本之间的差异文件并打包

git提取出两个版本之间的差异文件并打包

 Linux运用  陈杰斌   3年前 (2013-09-11)   22678浏览   3评论 [编辑]

公司的项目原先是使用svn做版本管理,发布项目的时候是采用打包的方式压缩成zip格式的文件,然后用ftp上传。随着开发人员越来越多,需求变化也比较多,经常在开发新功能时要调整线上的问题,在一个分支上进行开发就非常不方便。虽然svn也支持多分支开发,但是操作非常不便,于是就把项目的版本管理切换成了git。

切换成git之后,为了平缓的过度,发布项目的时候还是打算使用打包的方式,然后ftp上传。那么问题就来了:git如何提取出两个提交之间的差异文件呢?

一开始找了git format-patch和git archive都没有找到需要的功能,后来就去查git diff命令,找到了方法。

git diff这个命令能比较两个提交之间的差异,使用–name-only参数可以只显示文件名。例如:

$ git diff 608e120 4abe32e --name-only
git diff列出两个提交之间差异的文件

git diff列出两个提交之间差异的文件

这个输出结果非常有意思,就是差异文件的相对地址,不正好是压缩命令的参数吗?于是立马使用压缩命令

$ zip update.zip c/environ.c ... 所有的文件...

就能成功打包了。只是这样的话也太麻烦了吧,幸好linux有提供一个命令xargs能将前一个命令的输出转成另外一个命令的参数,按照这个思路就非常简单了。

$ git diff 608e120 4abe32e --name-only | xargs zip update.zip
结合xargs进行打包

结合xargs进行打包

总结

其实这种发布方式并不是非常好,如果线上的环境也能使用版本管理就非常方便了,只是这需要多方面的的配合。从某种意义上来讲,这种打包更新方式只是一种折中的处理方式。

还一个问题是这样的:提交的排序是按照时间来进行的,如果有分支合并进来的,可能分支里的提交时间在上次发布的提交时间之前,这样是否会漏打包到文件呢?答案是不会的,因为合并分支会产生一个新的提交,这个提交一定是在上次发布的提交之后。

提取两个版本之间差异文件,可以使用 JGit 库中的 `DiffCommand` 类。以下是一个简单的示例代码,可以提取两个版本之间差异文件: ```java Git git = new Git(repository); ObjectId oldVersion = ObjectId.fromString("commit_id_1"); ObjectId newVersion = ObjectId.fromString("commit_id_2"); DiffCommand diffCommand = git.diff(); diffCommand.setOldTree(prepareTreeParser(repository, oldVersion)); diffCommand.setNewTree(prepareTreeParser(repository, newVersion)); List<DiffEntry> diffs = diffCommand.call(); for (DiffEntry diff : diffs) { System.out.println("Diff: " + diff.getChangeType() + ": " + diff.getOldPath() + " -> " + diff.getNewPath()); // 获取差异文件的内容 ObjectReader reader = repository.newObjectReader(); CanonicalTreeParser oldTreeIter = new CanonicalTreeParser(); oldTreeIter.reset(reader, diff.getOldId()); CanonicalTreeParser newTreeIter = new CanonicalTreeParser(); newTreeIter.reset(reader, diff.getNewId()); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); DiffFormatter formatter = new DiffFormatter(outputStream); formatter.setRepository(repository); formatter.format(diff); System.out.println("Content: " + outputStream.toString()); } ``` 其中,`prepareTreeParser` 方法可以用来准备一个树对象的解析器。示例代码如下: ```java private static AbstractTreeIterator prepareTreeParser(Repository repository, ObjectId objectId) throws IOException { try (RevWalk walk = new RevWalk(repository)) { RevCommit commit = walk.parseCommit(objectId); RevTree tree = walk.parseTree(commit.getTree().getId()); CanonicalTreeParser treeParser = new CanonicalTreeParser(); try (ObjectReader reader = repository.newObjectReader()) { treeParser.reset(reader, tree.getId()); } walk.dispose(); return treeParser; } } ``` 注意,在使用 JGit 库之前,需要先打开一个 Git 仓库的对象。可以使用以下代码来打开 Git 仓库对象: ```java FileRepositoryBuilder builder = new FileRepositoryBuilder(); Repository repository = builder.setGitDir(new File("/path/to/.git")) .readEnvironment() .findGitDir() .build(); ``` 其中 `/path/to/.git` 是 Git 仓库的目录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值