python - Git tree-filter 在提交时运行 python 脚本

标签 python git file-permissions git-filter-branch git-rewrite-history

我早些时候在 #git 上被问到这个问题,但由于它相当重要,我会把它贴在这里。我想在 repo 上运行 filter-branch 以使用 python 脚本修改(数千个)超过数百次提交的文件。我在 repo 目录中使用以下命令调用 clean.py 脚本:

git filter-branch -f --tree-filter '(cd ../cleaner/ && python clean.py --path=files/*/*/**)'

Clean.py 看起来像这样并将修改路径中的所有文件(即 files/*/*/**):

from os import environ as environment
import argparse, yaml
import logging
from cleaner import Cleaner

parser = argparse.ArgumentParser()
parser.add_argument("--path", help="path to run cleaner on", type=str)
args = parser.parse_args()

# logging.basicConfig(level=logging.DEBUG)

with open("config.yml") as sets:
    config = yaml.load(sets)

path = args.path
if not path:
    path = config["cleaner"]["general_pattern"]

cleaner = Cleaner(config["cleaner"])

print "Cleaning path: " + str(path)
cleaner.clean(path, True)

运行命令后终端输出如下:

$ python deploy.py --verbose
INFO:root:Checked out master branch
INFO:root:Running command:
'git filter-branch -f --tree-filter '(cd C:/Users/Graeme/Documents/programming/clean-cdn/clean-jsdelivr/ && python clean.py --path=files/*/*/**)' -d "../tmp"' in ../jsdelivr
Rewrite 298ec3a2ca5877a25ebd40aeb815d7b5a5f33a7e (1/1535)
Cleaning path: files/*/*/**

C:\Program Files (x86)\git/libexec/git-core\git-filter-branch: line 343: ../commit: No such file or directory
C:\Program Files (x86)\git/libexec/git-core\git-filter-branch: line 346: ../map/298ec3a2ca5877a25ebd40aeb815d7b5a5f33a7e
: No such file or directory
could not write rewritten commit
rm: cannot remove `/c/Users/Graeme/Documents/programming/clean-cdn/tmp/revs': Permission denied
rm: cannot remove directory `/c/Users/Graeme/Documents/programming/clean-cdn/tmp': Directory not empty

python 脚本成功执行并正确修改了文件,但 filter-branch 没有完成修复提交。 似乎存在权限问题,但我无法绕过它以提升的权限运行。我已经尝试使用 git v1.8 和 v1.9 在 win7、win8 和 ubuntu 上运行过滤器分支。
编辑 该脚本在 Centros 上与 git1.7.1

一样工作

目标是在 files/*/*/** 中的内容完成与数据库的同步后,减少 CDN 存储库的大小(接近 1GB)。
The source code of the project
Target repo for the rewrite

最佳答案

您遇到的权限问题很有趣 - 您是在存储库的本地副本(即您对文件系统具有完全访问权限的副本)上还是在远程服务器上执行此操作?

阅读您的 Python 代码,您似乎在尝试删除超过一定大小但不是 .INI 文件的每个文件,我做对了吗?

如果是这样,请问您是否考虑过The BFG Repo-Cleaner ?显然,您通过编写自己的代码(我知道我有)学到了很多关于 Git 的知识,但我认为 BFG 可能是为您的需求量身定制的 - 并且会比任何 git-filter-branch 都快。基于方法。

在您的情况下,您可能希望使用如下命令运行它:

$ java -jar bfg.jar --strip-blobs-bigger-than 100K  my-repo.git

这将删除所有大于 100K 的 blob,它们在您的最新提交中。

我在 jsdelivr 上快速运行了一下 repo ,并在 the cleaned repo 中将包大小从 284M 减少到 138M . BFG 清洁步骤不到 5 秒,随后的 git gc --prune=now --aggressive不到 2 分钟。

完全披露:我是 BFG Repo-Cleaner 的作者。

关于python - Git tree-filter 在提交时运行 python 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22740020/

相关文章:

svn - 我如何使用 git-svn 只获取/克隆几个分支?

php - Apache 权限,PHP 文件创建,MKDir 失败

go - Linux 上 Go 中的八进制文件权限位

python - 在 Beam 管道中以编程方式生成 BigQuery 架构

python - 如何使用 TensorFlow 在 Returnn 中加载经过训练的网络的权重

git - 跟踪忽略和 --assume-unchanged 如何进行 merge

git - ^{} 在 git 中是什么意思?

python - 获取由其中之一标记的多个数组的所有组件状态

python - 在 PyCharm 中查找调用 Python 函数的位置

linux - 在 Java 5 中设置文件权限