我的主git repo中有一个git子模块。据我了解,主repo存储一个SHA值(某处......),指向它“链接到”的子模块的特定提交。
我进入了我的子模块并输入了git checkout some_other_branch
。我不知道我来自哪个承诺。
我想恢复该指针,以便主repo和子模块再次同步。
我的第一个(可能是天真的)本能是说git reset --hard
- 这似乎适用于其他一切。令我惊讶的是,它不适合这种情况。
所以我发现我可以输入git diff
,注意子模块指针曾经拥有的SHA ID,然后进入子模块git checkout [SHA ID]
...但是肯定必须是一种更简单的方法吗?
由于我还在学习git子模块,如果有我不知道的概念,请随时更正我的术语。
答案 0 :(得分:138)
您希望更新子模块,使其与父存储库认为的子模块同步。这是更新命令的用途:
从子模块联系人页面:
Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. This will make the submodules HEAD be detached unless --rebase or --merge is specified or the key submodule.$name.update is set to rebase or merge.
运行这个,一切都应该好:
git submodule update
答案 1 :(得分:18)
要更改子模块指向的提交,您需要在子模块中签出该版本,然后返回到包含的repo,添加并提交该更改。
或者,如果您希望子模块位于顶部仓库指向的版本上,请执行git submodule update --recursive
。如果您刚刚克隆,请添加--init
。
此外,没有子模块命令的git submodule
将显示您指向的提交。如果提交不同步,则会在提交前面有 - 或+。
如果你看一个带有子模块的树,你可以看到子模块被标记为commit
,而不是其他的blob或树。
要查看子模块的特定提交点,您可以:
git ls-tree <some sha1, or branch, etc> Submodule/path
然后,您可以通过将其传递到日志等来查看提交或其他任何内容(git命令级别的git-dir
选项允许您跳过必须cd到子模块):
git --git-dir=Submodule/path log -1 $(<the above statement>)
答案 2 :(得分:4)
在“superproject”文件夹中使用git ls-tree HEAD
查看子模块最初提交的内容。然后切换到子模块目录并使用git log --oneline --decorate
查看原始提交所在的分支。最后,git checkout original-commit-branch
。
使用我设置的一些测试目录,这是命令的外观:
$ git --version
git version 1.7.4.1
$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: sm2 (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-tree HEAD
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d .gitmodules
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 main
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed sm1
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337 sm2
$ cd sm2
$ git log --oneline --decorate
5b8d48f (HEAD, foo1) foo1.1
f68bed6 (origin/master, origin/HEAD, master) Initial commit.
$ git checkout master
Switched to branch 'master'
$ cd ..
$ git status
# On branch master
nothing to commit (working directory clean)
“superproject”显示提交f68bed6
处的sm2子模块,但sm2在5b8d48f
处显示HEAD子模块。子模块提交f68bed6
上有三个分支,可用于子模块目录中的签出。
答案 3 :(得分:4)
我遇到的另一个案例是,如果要丢弃的子模块中存在未分级的更改。 git子模块更新不会删除该更改,也不会在父目录上git reset --hard。您需要转到子模块目录并执行git reset --hard。因此,如果我想完全放弃父节点和子模块中的非分段更改,我会执行以下操作:
在家长中:
@Override
public int filterOrder() {
return 10;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
if ((ctx.get("proxy") != null) && ctx.get("proxy").equals("foo")) {
return true;
}
return false;
}
在子模块中:
git reset --hard
git submodule update
答案 4 :(得分:1)
这里的答案在某种程度上并没有解决我对子模块的具体问题,所以万一你也遇到过这种情况,请尝试以下方法......
git submodule foreach git reset --hard
https://kalyanchakravarthy.net/blog/git-discard-submodule-changes/
答案 5 :(得分:0)
我想忽略子模块以及模块中的任何更改
以下命令对我有帮助:
git submodule update --init --recursive
答案 6 :(得分:0)
更新后的视觉漫游 - 这里我的子模块指向 - 8c3fd8b 转到此文件夹并....
git checkout master
error: pathspec 'master' did not match any file(s) known to git
在子模块中,例如。运行所需的 stylegan2-ada 文件夹
git checkout main
git pull
这解决了我的问题(暂时)
最后一步是提交父仓库中的更改。跟踪的更改会自动出现 - 我不需要创建文件 - 只需通过单击 vscode 中的 + 并推送来暂存文件更改。
在这里你可以很清楚地看到 git commits 刷新。
-Subproject commit 8c3fd8bac3e5a54a20e860fc163d6e67cc03c623
+Subproject commit 0045ea50f1b9710ffde3ab2a9a18c0d4c97bfaed
问题排查
请注意,有一个 .gitsubmodule 文件指向相应的 git 远程存储库。