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

本文介绍了一个需求,即根据两个时间点的jar包中class文件对比,删除未改动的源码文件,并从Git历史中抹除。讨论了两种git过滤方法,一种被废弃,另一种(filter-repo)可能导致与原仓库断开关联。为解决大量文件操作问题,提供了Python脚本dir_compare_rm_file.py,该脚本能自动化对比和删除相同文件,但最终需提交到新仓库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近有个奇葩的需求,基于某些保密原因,需要比较两个时间点编译的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

最后提交到远程仓库:

#最后提交到新的远程仓库:

# git remote add origin https://gitlab_URL/your_project.git

#推送仓库

# git push -u origin master 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值