Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在git中捆绑子模块更改?_Git_Bundle_Git Submodules - Fatal编程技术网

如何在git中捆绑子模块更改?

如何在git中捆绑子模块更改?,git,bundle,git-submodules,Git,Bundle,Git Submodules,如果我有一个包含子模块的存储库,并且我想为sneakernet创建一个捆绑包,那么如何使捆绑包包含更新子模块所需的对象 例如,假设我有一个名为parent的存储库,它包含一个名为submod的子模块。我想创建一个bundle,其中包含自commitbasecommit以来的所有最新工作,因此,从父目录根目录中,我自然会执行以下操作: git bundle create mybundlefile.bundle basecommit..myworkingbranch 这将创建一个名为mybundl

如果我有一个包含子模块的存储库,并且我想为sneakernet创建一个捆绑包,那么如何使捆绑包包含更新子模块所需的对象

例如,假设我有一个名为
parent
的存储库,它包含一个名为
submod
的子模块。我想创建一个bundle,其中包含自commit
basecommit
以来的所有最新工作,因此,从
父目录
根目录中,我自然会执行以下操作:

git bundle create mybundlefile.bundle basecommit..myworkingbranch
这将创建一个名为
mybundlefile.bundle
的文件,其中包含范围
basecommit..myworkingbranch
以及ref
myworkingbranch
上的
parent
repo中的所有提交对象。问题是,如果这些提交中的任何一个更改了子模块,那么生成的包将不会非常有用,因为这些提交仅作为更改子模块哈希存储在包文件中。因此,bundle文件中存储的对象只是说“我正在提交
3ba024b
,我将子模块
submod
的哈希值从
2b941cf
更改为
1bb84ec
”但是捆绑包实际上并不包括更新捆绑包中的子模块并为
myworkingbranch
创建一个干净的工作树所需的对象
2b941cf..1bb84ec

如何创建bundle文件,以便子模块repo中的所有对象也包括在内。也就是说,如果父repo的基本提交
basecommit
指向hash
A
处的子模块
submod
,并且父repo的工作分支
myworkingbranch
指向hash
B
处的子模块
submod
,那么我的包不仅需要包含
basecommit..myworkingbranch
,但是也有
A..B

如何创建bundle文件,以便子模块repo中的所有对象也包括在内

你不能。捆绑文件特定于Git存储库。子模块只是指向另一个Git存储库的链接,因此必须为单独的Git存储库创建单独的捆绑包。(然后,您可以从各种捆绑包中创建一个存档。)

很明显,Git可以深入到每个子模块中,在每个子模块中运行
Git bundle
,为您生成这些不同的文件。但是,要传递给sub-
git bundle
命令的参数很复杂。您必须编写自己的脚本,并使用
git submodule foreach
使其在每个子模块中运行,并让脚本计算出要使用的参数

然后,您可能希望将每个捆绑包打包在一起(可能打包到tar、rar、zip或任何归档文件中),以便进行传输和拆分/获取。在拆分过程中,您将需要另一个
git子模块foreach
,这可能会更烦人,因为理想情况下,这应该使用新的子模块集(在拆分顶级模块并选择适当的提交之后)

有可能是有人写了脚本来做这件事,但如果是这样,我不知道。它不包括在Git本身中,捆绑包本身是一种笨拙和非主流的东西。

我写这篇文章就是为了做到这一点。有很多角落里的案子,我怀疑我是否都拿到了。请尝试一下,如果您的用例需要任何修复,请在项目上打开一个问题

为了子孙后代,我将列出上面项目中的所有代码;但是您应该直接从github克隆

bundle.py
#/usr/bin/env蟒蛇3
“”“为子模块创建捆绑包”“”
导入操作系统
导入argparse
导入子流程
导入tarfile
导入子模块_提交
导入字符串
随机输入
进口舒蒂尔
parser=argparse.ArgumentParser(description='Create bundle for submodules(递归地))\
以方便sneakernet连接。在联机计算机上\
为每个存储库制作一个包,然后打包到一个.tar文件中\
在脱机计算机上,使用tar文件上的unbundle.py解压并\
从每个存储库的相应捆绑中提取。“)
parser.add_参数('filename',metavar='filename',type=str,help='file以创建例如./my_bundles.tar')
parser.add_参数('commit_range',metavar='[baseline]..[target]',type=str,default='..HEAD',nargs='?',
help='commit要捆绑的顶级存储库的范围;默认为everything')
args=parser.parse_args()
类IllegalArgumentError(ValueError):
通过
尝试:
[基线,目标]=args.commit_range.split(“..”)
除值错误外:
raise ILLEGARGUMERROR(f“无效的提交范围:{args.commit_range}”:
+“应为[基线]…[目标]。基线和目标是可选的”
+“但是点是区分两者的必要条件。”)与“无”
完整的历史记录=错误
from_str=f'from{baseline}'
如果基线=“”:
打印(“无基线(所有捆绑包都是完整的历史捆绑包)”)
完整历史=真实
from_str=“从头开始”
如果目标=“”:
目标='HEAD'
打印('将'+from_str+f'更新为{target}'的捆绑包)
需要更新_={}
新的_子模={}
束=[]
对于子模块_提交中的子模块。子模块_提交('.',目标):
新_子模块[子模块['subdir']]=子模块['commit']
root_dir=os.getcwd()
tar_file_name=os.path.basename(args.filename).split('.')[0]
temp_dir=f'temp_dir_for{tar_file_name}_bundles'#注意,如果该dir已经有内容,那么这将不起作用
def create_bundle(子模块_dir、新_提交_sha、基线_描述符=“”):
bundle\u temp=f'{submodule\u dir}.bundle'
bundle_path=f'{temp_dir}/{bundle_path_in_temp}'
如果子模块_dir=='.':
路由_到_根='。/'
其他:
路由_到_根=(su