Contents
有时候, 我们写完一个项目需要对其进行打包. 打完成包非常简单, 我们可以使用git archive这个命令. 但是有时候我们需要对项目的一些特殊文件进行过滤. 这个时候, 可能会说这些文件可以放在.gitingore中. 我需要告诉的时, 在开发项目的时候, 有些文件也需要在git仓中, 以方便其他小组的人使用. 另一种情况, 我们需要打一个差异包出来, 如果没有任何特殊要求, 可以直接使用tar zxvf xxx-patch.tar.gz `git diff –name-only`进行打包. 但是你这个仓中含有很多个submodule时候, 使用这种方法, 会遇到一个很不幸的事, 不管这个子模块修改了一个, 还是多个文件, 他都会将这个子模块全部打包进去. 因此, 我们需要一个好的打包工具, 解决以上问题. 目前我是采用python + pygit2的方式. 同时你系统环境中要有git.
pygit2有一个已知的bug, 你给你的项目打tag, 如果打tag时候没有加上message. pygit2是无法读取到的.
读取git仓中的tag非常的简单. 代码如下
def get_tags(self): self.tags = []; print "=== Parsing package version"; data = self.repo.listall_references(); for item in data: ref = self.repo.lookup_reference(item); if (ref.type == pygit2.GIT_OBJ_COMMIT): oid = ref.oid; ref_obj = self.repo[oid]; if isinstance(ref_obj, pygit2.Tag): self.tags.append(ref_obj); else: continue; self.tags.sort(lambda x,y: cmp(y.tagger.time, x.tagger.time));
获取tag之后, 我们可以使用tag下属性timer, 根据时间先后次序进行排序. 这样你想取最后一个tag作为目标进行打包 只要self.tags[0](倒序)就能直接获取到. 同样你需要获取两个版本的差异. 只要git diff tag[0]..tag[1]
2. Diff的一些参数
git diff提供了非常多的功能. 前面一直提高的–name-only 只显示更新的文件
–name-status 显示更新的文件以及状态
–diff-filter=[A|C|D|M|R|T|U|X|B] diff过滤显示. A:增加, D:删除, M:修改, C: 复制, R: 重命名, T 更改, U 未合并, X 未知, B Broken
3.获得submodule的差异
这里通过git diff获得submodule的差异内容. 在git中, submodule的diff内容就是两个sha1的hash值. 我就是利用这一点. 提取两个函数值, 然后在使用git diff命令,提取出子模块的更新列表.代码如下:
def get_submodule_diff_files_list(self, submodule_dir, submodule, git_str): diff_info = git_str[0].strip().split(); #find -Subproject pre_subproject_position = diff_info.index('-Subproject') pre_subproject_version_position = pre_subproject_position + 2; #手动偏移2位 pre_version_hash = diff_info[pre_subproject_version_position]; #find +Subproject last_subproject_position = diff_info.index('+Subproject'); last_subproject_version_position = last_subproject_position + 2; last_version_hash = diff_info[last_subproject_version_position]; update_list = [] if (pre_version_hash and last_version_hash): tfiles = git("diff", last_version_hash, pre_version_hash, "--diff-filter=A,C,M,T", "--name-only", cwd=submodule_dir)[0]; tfiles = tfiles.strip().split(); update_list = [os.path.join(submodule,f) for f in tfiles]; else: update_list.append(submodule) return update_list;
0 Comments.