如何将Git子模块指针恢复到包含仓库中保存的提交?

8fq7wneg  于 2023-02-28  发布在  Git
关注(0)|答案(7)|浏览(128)

我的主git存储库中有一个git子模块,据我所知,主存储库存储一个SHA值(某处...),指向它所“链接”的子模块的特定提交。
我进入我的子模块并输入git checkout some_other_branch。我不知道我来自哪个提交。
我想恢复该指针,以便主存储库和子模块再次同步。
我的第一个(可能是天真的)直觉是说git reset --hard--这似乎对其他任何事情都有效。令我惊讶的是,它对这个场景不起作用。
所以我发现我可以输入git diff,注意子模块指针曾经拥有的SHA ID,然后进入子模块和git checkout [SHA ID]......但是肯定有更简单的方法吗?
由于我还在学习git子模块,如果有我不认识的概念,请随时更正我的术语。

qij5mzcb

qij5mzcb1#

你想要更新你的子模块,使它与父仓库认为它应该是的同步。这就是update命令的作用:
在子模块手册页中:

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 --init

您还可以添加--recursive标志来递归遍历所有子模块。

q3aa0525

q3aa05252#

要修改子模块所指向的提交,您需要 checkout 子模块中的版本,然后返回到包含的repo,添加并提交修改。
或者,如果你想让子模块位于top repo指向的版本上,执行git submodule update --recursive。如果你刚刚克隆过,添加--init
同样,git submodule不带submodule命令也会显示你所指向的提交。如果提交不同步,提交前会有一个-或一个+。
如果查看其中包含子模块的树,可以看到该子模块被标记为commit,而其他子模块则被标记为blob或树。
要查看某个特定的提交指向哪些子模块,您可以:

git ls-tree <some sha1, or branch, etc> Submodule/path

然后你可以看到提交或者其他任何东西,如果你愿意的话,把它传入log,etc(git命令级的git-dir选项允许你跳过cd到子模块):

git --git-dir=Submodule/path log -1 $(<the above statement>)
zf2sa74q

zf2sa74q3#

另一种情况是,如果子模块中有一个未暂存的修改需要丢弃,git submodule update不会删除该修改,git reset --hard也不会删除父目录中的修改,你需要到子模块目录中执行一个git reset --hard,所以如果我想完全丢弃父目录和子模块中未暂存的修改,我可以这样做:
在父代中:

git reset --hard

git submodule update

在子模块中:

git reset --hard
h43kikqp

h43kikqp4#

这里的答案不知何故没有解决我的具体问题与子模块,所以如果它发生在你身上太,尝试以下...

git submodule foreach git reset --hard
67up9zun

67up9zun5#

使用“superproject”文件夹中的git ls-tree HEAD查看子模块最初的提交位置,然后切换到submodule目录并使用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”显示sm2子模块在f68bed6提交,但sm2的HEAD在5b8d48f。子模块提交f68bed6有三个分支,可用于在子模块目录中检出。

2o7dmzc5

2o7dmzc56#

我想忽略子模块和我的模块中的任何更改
下面的命令帮助我:

git submodule update --init --recursive
gg58donl

gg58donl7#

一个更新的可视化走查-这里我的子模块指向-8 c3 fd 8b转到这个文件夹和......会很简单。

git checkout master
error: pathspec 'master' did not match any file(s) known to git

在需要运行的子模块中,例如stylegan 2-ada文件夹

git checkout main
git pull

这解决了我的问题(暂时)
最后一步是提交父存储库中的更改,跟踪的更改会自动出现-我不需要创建文件-只需单击vscode中的+并推送文件更改即可。
这里你可以很清楚的看到git提交刷新了。

-Subproject commit 8c3fd8bac3e5a54a20e860fc163d6e67cc03c623
+Subproject commit 0045ea50f1b9710ffde3ab2a9a18c0d4c97bfaed

故障排除
注意有一个.gitsubmodule文件指向各自的git远程repo。

相关问题