0
点赞
收藏
分享

微信扫一扫

删除已经提交到git仓库中的文件(批量脚本)

野见 2022-03-22 阅读 134

最近有个奇葩的需求,基于某些保密原因,需要比较两个时间点编译的jar包中的class文件,将没有修改的已经提交到仓库中的对应源码文件彻底删除,从所有提交历史中都抹除。经过查找,可以使用两种方法:

1、git filter-branch --tree-filter 'rm -rf ${file_path_name}' --prune-empty -f HEAD --all

这种方式已经被废弃,修改速度慢,而且修改完成后git push origin 时总是报错。(我是没有提交成功)。 

2、git filter-repo --force --invert-paths --path ${file_path_name}

这种方式是filter-branch替代方式,需要先安装filter-repo(需要先安装 python 然后 pip install git-filter-repo 来安装,详见github-git-filter-repo)。

第二种方式最大的问题是执行后,不在与原仓库有关联,必须提交到新的一个仓库,目前尚未研究怎么提交到原仓库的方法。

注:${file_path_name}为你想要删除的文件路径和文件名称,路径是相对于仓库的目录,例如:WEB-INF/src/util/FileUtil.java

上面方法如果单个文件操作时,非常简单,当存在大量文件时,就比较繁琐,因此用python整理了一个脚本,实现对两个文件进行比较,并自动对比较结果中文件相同的源文件(没有修改),从仓库中抹除,最后提交到新的仓库中。因此编写了一个python批量脚本:dir_compare_rm_file.py内容如下:

#coding=utf-8
#!/usr/bin/env python
#import git_filter_repo
import sys
import os
import re
from filecmp import dircmp
import subprocess


dir_old=r'D:\your_project_old\WEB-INF\classes'
dir_new=r'D:\your_project_new\WEB-INF\classes'
repos_path=r'D:\your_project_repos'
##存放比较结果
same_files_list=[]
#递归比较文件夹函数
def print_diff_files(dcmp):
    for name in dcmp.diff_files:
        print("diff_file %s found in %s and %s" % (name, dcmp.left, dcmp.right))
    if dcmp.left_only:
        print('%s: %s ' % (dcmp.left, dcmp.left_only))
    if dcmp.right_only:
        print('%s: %s ' % (dcmp.right, dcmp.right_only))
    for same_files in dcmp.same_files:
    		if(same_files.endswith(".class")  and not "$" in same_files):
    			same_files_list.append(os.path.join(dcmp.right, same_files))        
    for sub_dcmp in dcmp.subdirs.values():
        print_diff_files(sub_dcmp)
        
#执行递归文件夹比较
dcmp = dircmp(dir_old, dir_new)
print_diff_files(dcmp)
#输出比较后,相同的文件
for index,same_files in   enumerate(same_files_list):	 
	rm_file=same_files[same_files.index('WEB-INF\\'):].replace("classes\\","src\\")
	#从右替换一次扩展名为java
	rm_file=re.sub(r'(.*).class',r'\1.java',rm_file)
	#执行命令行cd到仓库目录	
	p = subprocess.Popen(' cd ' +repos_path,
                     shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT,
                     encoding='utf-8'
                     )

	#stdout
	print(p.communicate()[0])			
	#执行命令行filter-repo 抹除文件	
	print('[%s/%s] remove file: git filter-repo --force --invert-paths --path %s  ' % (index,len(same_files_list),rm_file)) 
	p = subprocess.Popen(' git filter-repo --force --invert-paths --path '+rm_file,
                     shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT,
                     encoding='utf-8'
                     )
	print(p.communicate()[0])
	#stdout

可以保留了提交历史的仓库。

举报

相关推荐

0 条评论