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

Sma*_*ery 110 git git-submodules

我的主git repo中有一个git子模块.据我了解,主repo存储一个SHA值(某处......),指向它"链接到"的子模块的特定提交.

我进入了我的子模块并输入了git checkout some_other_branch.我不知道我来自哪个承诺.

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

我的第一个(可能是天真的)本能就是说git reset --hard- 这似乎适用于其他一切.令我惊讶的是,它不适合这种情况.

所以我发现我可以输入git diff,注意子模块指针曾经拥有的SHA ID,然后进入子模块并且git checkout [SHA ID]...但是肯定必须有一个更简单的方法吗?

由于我还在学习git子模块,如果有关于我不知道的概念的话,请随时更正我的术语.

Bri*_*man 150

您希望更新子模块,以使其与父存储库认为应该是的内容同步.这是更新命令的用途:

从子模块联机帮助页:

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
Run Code Online (Sandbox Code Playgroud)

  • 不知何故,对我来说,我需要添加`--init`.没有它,子模块将保持在"(新提交)"的状态.即使我的子模块已经初始化了. (2认同)
  • 如果子模块提交哈希被修改并取消暂存,则不起作用 (2认同)

Ada*_*ruk 20

要更改子模块指向的提交,您需要在子模块中签出该版本,然后返回包含repo,添加并提交该更改.

或者,如果您希望子模块位于顶部repo指向的版本上,请执行此操作git submodule update --recursive.--init如果您刚刚克隆,请添加.

此外,git submodule没有子模块命令将显示您指向的提交.如果提交不同步,则会在提交前面有 - 或者+.

如果您查看其中包含子模块的树,您可以看到子模块被标记为a commit而不是其余的blob或树.

要查看子模块的特定提交点,您可以:

git ls-tree <some sha1, or branch, etc> Submodule/path
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过将其传递到日志等来查看提交或其他任何内容(git-dirgit命令级别的选项允许您跳过必须cd到子模块):

git --git-dir=Submodule/path log -1 $(<the above statement>)
Run Code Online (Sandbox Code Playgroud)


Ben*_*ger 6

我刚遇到的另一种情况是,您要丢弃的子模块中是否存在未分级的更改。git子模块更新不会删除该更改,也不会在父目录上git reset --hard。您需要转到子模块目录并执行git reset --hard。因此,如果我想完全放弃父级和子模块中未进行的变更,请执行以下操作:

在家长中:

git reset --hard

git submodule update
Run Code Online (Sandbox Code Playgroud)

在子模块中:

git reset --hard
Run Code Online (Sandbox Code Playgroud)


Raj*_*oel 6

我想忽略子模块和我的模块中的任何更改

下面的命令帮助了我:

git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)


Dan*_*ruz 5

使用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)
Run Code Online (Sandbox Code Playgroud)

“超级项目”在提交时显示了sm2子模块,f68bed6但是sm2 在处具有HEAD头5b8d48f。子模块提交上f68bed6具有三个分支,可用于在子模块目录中检出。


Mic*_*han 5

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

 git submodule foreach git reset --hard
Run Code Online (Sandbox Code Playgroud)

https://kalyanchakravarthy.net/blog/git-discard-submodule-changes/