git python 脚本下的初始化 git filter-branch 使用了错误的目录
git init under python script called by git filter-branch uses wrong directory
我 运行 python 脚本的以下 MWE 读取抛出提交并在其他地方创建另一个 git 项目。
我以这种方式调用此脚本以遍历 git projectA 并在
的 bash 命令下创建另一个 git projectB
git filter-branch -f --tree-filter "python3 /media/sf_git/register-commits.py /home/mercury/splitted" --prune-empty --tag-name-filter cat -- --all
python3
的参数是每次提交时 运行 的脚本,它之后的路径是应该创建项目 B 的位置。
/media/sf_git/register-commits.py
import os
import sys
def git_init(module):
os.system('git init ' + module)
def create_project(parent, module):
os.chdir(parent)
print('parent:', parent)
git_init(module)
if not os.path.exists(os.path.join(parent, module, '.git')):
sys.exit('.git folder is not created.')
arg1 = sys.argv[1]
if arg1 is None:
sys.exit('The script argument is not provided')
commit_id = os.environ["GIT_COMMIT"]
module = 'projectB'
cwd = os.getcwd()
try:
dst_module_path = os.path.join(arg1, module)
if not os.path.exists(dst_module_path):
create_project(arg1, module)
except Exception as e:
print('Error: ' + str(e))
finally:
os.chdir(cwd)
问题是os.chdir
可以改变路径。我什至打印了它。这是正确的。但是 git init 命令 运行s 在项目 A 而不是项目 B 的同一工作目录中。它给了我以下错误
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...
Rewrite 8a30d5630ab7ead31ecc3b30122054d27eec0dbe (1/3058) (0 seconds passed, remaining 0 predicted)
Reinitialized existing Git repository in /home/mercury/projectA/.git/
.git folder is not created.
parent: /home/mercury/splitted
tree filter failed: python3 /media/sf_git/register-commits.py /home/mercury/splitted
它在 /home/mercury/splitted
下创建一个空文件夹 projectB
,其中没有 .git
文件夹。
看来还有一个侧面的问题,projectA被改变了。因为我运行第二次写脚本的时候,出现了错误
Proceeding with filter-branch...
You need to run this command from the toplevel of the working tree.
看来项目A受伤了。我知道的唯一修复方法是从备份中复制 projectA 的 .git
文件夹。
使用 subprocess.Popen
得到类似的结果:
def git_init(module):
parent = os.getcwd()
print('parent:', parent)
proc = subprocess.Popen(['git', 'init', module], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=parent)
p_status = proc.wait()
(output, err) = proc.communicate()
print(output)
输出
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...
Rewrite 8a30d5630ab7ead31ecc3b30122054d27eec0dbe (1/3058) (0 seconds passed, remaining 0 predicted)
parent: /home/mercury/splitted
parent: /home/mercury/splitted
b'Reinitialized existing Git repository in /home/mercury/projectA/.git/\n'
.git folder is not created.
tree filter failed: python3 /media/sf_git/register-commits.py /home/mercury/splitted
这很奇怪,git 在 /home/mercury/splitted
中创建了一个文件夹,但尝试在 /home/mercury/projectA
下启动 .git
。
当我运行正常python环境下的脚本时,一切正常。但是在 git filter-branch
下,即使工作目录已更改,路径也不适用于 git
。除此之外,当 git init
应用于另一个目录时,projectA 似乎已损坏。
我不确定这是 git
问题还是 python
问题。
出了什么问题以及如何解决这个问题?
What is wrong ...
在 git filter-branch
中,树过滤器中有两件事不能做,一般来说:
- 更改工作目录;
- 使用 Git 命令。
这不一定是一个排他列表,幸运的是,有一些方法可以解决这两个问题。
and how to fix this problem?
更改目录的限制实际上特定于顶层 shell 中的 shell 命令 运行 (filter-branch eval
在这里是你的过滤器)。由于您正在启动一个完全独立的进程 python
,因此您可以更改工作目录。但值得一提的是这个问题,因为尝试 优化 你的过滤器可能会导致 运行 进入它。
使用 Git 命令的限制是因为树过滤器专门用于让您使用 non-Git 命令来 重做每个提交的内容。使用 git filter-branch
只是为了 检查 每次提交的内容并不是这里的意图。
幸运的是,运行ning git init
有一个简单的解决方法:您只需要 删除 环境变量 GIT_DIR
当您调用 Git 时来自环境。如果您调用其他 Git 命令,则可能需要取消设置更多环境变量。
但总的来说,尚不清楚您为什么要为此使用 git filter-branch
。如果你想获得提交列表,正确的工具通常是 git rev-list
。如果您想从 这些提交中获取文件 ,事情会变得更加复杂,但是 filter-branch 仍然可能不是正确的工具。
我 运行 python 脚本的以下 MWE 读取抛出提交并在其他地方创建另一个 git 项目。
我以这种方式调用此脚本以遍历 git projectA 并在
的 bash 命令下创建另一个 git projectBgit filter-branch -f --tree-filter "python3 /media/sf_git/register-commits.py /home/mercury/splitted" --prune-empty --tag-name-filter cat -- --all
python3
的参数是每次提交时 运行 的脚本,它之后的路径是应该创建项目 B 的位置。
/media/sf_git/register-commits.py
import os
import sys
def git_init(module):
os.system('git init ' + module)
def create_project(parent, module):
os.chdir(parent)
print('parent:', parent)
git_init(module)
if not os.path.exists(os.path.join(parent, module, '.git')):
sys.exit('.git folder is not created.')
arg1 = sys.argv[1]
if arg1 is None:
sys.exit('The script argument is not provided')
commit_id = os.environ["GIT_COMMIT"]
module = 'projectB'
cwd = os.getcwd()
try:
dst_module_path = os.path.join(arg1, module)
if not os.path.exists(dst_module_path):
create_project(arg1, module)
except Exception as e:
print('Error: ' + str(e))
finally:
os.chdir(cwd)
问题是os.chdir
可以改变路径。我什至打印了它。这是正确的。但是 git init 命令 运行s 在项目 A 而不是项目 B 的同一工作目录中。它给了我以下错误
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...
Rewrite 8a30d5630ab7ead31ecc3b30122054d27eec0dbe (1/3058) (0 seconds passed, remaining 0 predicted)
Reinitialized existing Git repository in /home/mercury/projectA/.git/
.git folder is not created.
parent: /home/mercury/splitted
tree filter failed: python3 /media/sf_git/register-commits.py /home/mercury/splitted
它在 /home/mercury/splitted
下创建一个空文件夹 projectB
,其中没有 .git
文件夹。
看来还有一个侧面的问题,projectA被改变了。因为我运行第二次写脚本的时候,出现了错误
Proceeding with filter-branch...
You need to run this command from the toplevel of the working tree.
看来项目A受伤了。我知道的唯一修复方法是从备份中复制 projectA 的 .git
文件夹。
使用 subprocess.Popen
得到类似的结果:
def git_init(module):
parent = os.getcwd()
print('parent:', parent)
proc = subprocess.Popen(['git', 'init', module], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=parent)
p_status = proc.wait()
(output, err) = proc.communicate()
print(output)
输出
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...
Rewrite 8a30d5630ab7ead31ecc3b30122054d27eec0dbe (1/3058) (0 seconds passed, remaining 0 predicted)
parent: /home/mercury/splitted
parent: /home/mercury/splitted
b'Reinitialized existing Git repository in /home/mercury/projectA/.git/\n'
.git folder is not created.
tree filter failed: python3 /media/sf_git/register-commits.py /home/mercury/splitted
这很奇怪,git 在 /home/mercury/splitted
中创建了一个文件夹,但尝试在 /home/mercury/projectA
下启动 .git
。
当我运行正常python环境下的脚本时,一切正常。但是在 git filter-branch
下,即使工作目录已更改,路径也不适用于 git
。除此之外,当 git init
应用于另一个目录时,projectA 似乎已损坏。
我不确定这是 git
问题还是 python
问题。
出了什么问题以及如何解决这个问题?
What is wrong ...
在 git filter-branch
中,树过滤器中有两件事不能做,一般来说:
- 更改工作目录;
- 使用 Git 命令。
这不一定是一个排他列表,幸运的是,有一些方法可以解决这两个问题。
and how to fix this problem?
更改目录的限制实际上特定于顶层 shell 中的 shell 命令 运行 (filter-branch eval
在这里是你的过滤器)。由于您正在启动一个完全独立的进程 python
,因此您可以更改工作目录。但值得一提的是这个问题,因为尝试 优化 你的过滤器可能会导致 运行 进入它。
使用 Git 命令的限制是因为树过滤器专门用于让您使用 non-Git 命令来 重做每个提交的内容。使用 git filter-branch
只是为了 检查 每次提交的内容并不是这里的意图。
幸运的是,运行ning git init
有一个简单的解决方法:您只需要 删除 环境变量 GIT_DIR
当您调用 Git 时来自环境。如果您调用其他 Git 命令,则可能需要取消设置更多环境变量。
但总的来说,尚不清楚您为什么要为此使用 git filter-branch
。如果你想获得提交列表,正确的工具通常是 git rev-list
。如果您想从 这些提交中获取文件 ,事情会变得更加复杂,但是 filter-branch 仍然可能不是正确的工具。