如何将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