如何将Git子模块的指针恢复到存储在存储库中的提交?

我在我的主git仓库中有一个git子模块。 据我了解,主回购存储一个SHA值(某处…),指向子模块的“链接到”的具体提交。

我进入我的子模块并inputgit checkout some_other_branch 。 我不知道我来自哪个承诺。

我想恢复该指针,以便主repo和子模块再次同步。

我的第一个(可能是天真的)本能就是说git reset --hard – 这似乎适用于其他任何事情。 令我惊讶的是,这并不适用于这种情况。

所以我想通了,我可以inputgit diff ,记下子模块指针所使用的SHA ID,然后进入子模块和git checkout [SHA ID] …但是肯定有一个更简单的方法吗?

由于我还在学习git submodules,如果有我不知道的概念的话,请随时纠正我的术语。

您想要更新您的子模块,以便与父库相信它应该是同步的。 这是更新命令的用途:

从子模块手册页:

更新已注册的子模块,即克隆缺less的子模块和
检出包含的索引中指定的提交
库。 这将使子模块HEAD分离,除非
 --rebase或--merge被指定或者是关键的子模块$ name.update
被设置为重新绑定或合并。

运行这一切都应该是好的:

 git submodule update 

要更改子模块指向的提交,需要在子模块中检出该版本,然后返回到包含的回购,添加并提交该更改。

或者,如果您希望子模块位于顶级回购指向的版本上,请执行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>) 

在“superproject”文件夹中使用git ls-tree HEAD来查看你的子模块原来的提交。 然后转到子模块目录,并使用git log --oneline --decorate来查看原始提交所在的分支。 最后, git checkout original-commit-branch

使用我设置的一些testing目录,以下是这些命令的样子:

 $ 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在f68bed6处显示为HEAD。 子模块提交f68bed6有三个分支,可用于在子模块目录中签出。

我刚刚遇到的另一个情况是,如果在子模块中有一个未执行的更改,您要放弃。 git子模块更新不会删除这个变化,也不会git重置 – 在父目录上。 你需要去submodule目录,并做一个混帐重置 – 哈德。 所以,如果我想完全放弃我的父母和子模块中未分离的变化,我会做以下工作:

在家长:

 git reset --hard git submodule update 

在子模块中:

 git reset --hard