我如何重新设置git超级项目的基础,以更改子模块的哈希?

问题描述 投票:0回答:1

假设我们有两个git repos,一个是另一个的子模块(A将是超级项目,B将是子模块)。项目A本身不是源代码,而是一个收集和跟踪有关其子模块的信息的项目。 A存储库很少(如果有的话)在本地计算机上存在,而是一堆脚本来对其进行更新。

[一天,有人意识到回购B应该更好地使用LFS,并使用git lfs migrate import清理了回购。我有B的旧哈希和新哈希的列表。

我做了什么

由于仓库A发生线性变化(无分支),所以我能够执行git rebase --root -i,将所有提交更改为edit,然后运行一个简单的bash脚本,将子模块重置为新的哈希值。这是脚本的示例:

#!/bin/bash #set the submodule path and input files submodulePath=foo newHashesFile=NewHashes.txt originalHashesFile=OriginalHashes.txt while [ (test -d "$(git rev-parse --git-path rebase-merge)" || test -d "$(git rev-parse --git-path rebase-apply)" ) ]; do numLines=`git ls-files --stage | grep $submodulePath | wc -l` if [ $numLines = 1 ]; then oldHash=`git ls-files --stage | grep $submodulePath | sed -e 's/^160000 \([^ ]*\) 0.*$/\1/g'` echo oldHash: $oldHash else echo merge conflict oldHash=`git ls-files --stage | grep $submodulePath | grep '^160000 \([^ ]*\) 3.*' | sed -e 's/^160000 \([^ ]*\) 3.*$/\1/g'` echo oldHash: $oldHash fi lineNumber=`grep -n $oldHash $originalHashesFile | sed -e 's/^\([^:]*\):.*/\1/g'` newHash=`head -n $lineNumber $newHashesFile | tail -n 1` if [ ! $lineNumber ]; then echo Hash not changed else cd $submodulePath git reset --hard $newHash cd ../ fi git add $submodulePath/ git commit --amend git rebase --continue done

问题

所有这些都有效,但是我想知道是否有一种更简单的方法,因为我想我会被要求再次进行此操作。这个问题有两个部分。

    是否有一种简单的方法告诉git您希望默认值为edit而不是pick,而不依赖于编辑器?
  1. 是否有一种更简单的方法告诉git执行脚本的作用?如果我在超级项目中执行了git lfs migrate import,会有所帮助吗?
git git-submodules rebase
1个回答
0
投票
是否有一种简单的方法告诉git您希望编辑默认值而不是选择内容,而不依赖于编辑器?

否。但是,有一种方法可以将命令序列编辑器设置为与其他编辑器不同的编辑器:设置环境变量GIT_SEQUENCE_EDITOR。因此,例如,您可以执行:

GIT_SEQUENCE_EDITOR="sed -i '' s/^pick/edit/" git rebase -i ...

(假设您的sed具有以这种方式工作的-i,依此类推。]

是否有一种更简单的方法告诉git来执行脚本的工作?

鉴于您要更新每个gitlink哈希,我将使用git filter-branch(而不是git rebase)来进行此操作,并使用--index-filter进行gitlink哈希更新。我不确定这是否是

simpler,但更直接。索引过滤器本身将使用与您执行此操作类似的方法来使用git ls-files --stage,但可能本身也会使用生成的sed脚本或awk脚本。 Generated-sed可能会更快,而awk可能会更简单,尤其是如果您有一个现代的awk,您可以在其中读取哈希映射。

© www.soinside.com 2019 - 2024. All rights reserved.