如何静默地“git 拉取”次级子模块,以便不需要更多提交?
How to `git pull` secondary submodules silently so that it does not require any more commits?
我对子模块和 git 比较陌生,但我一直在使用它们将我所有的 tmux 和 vim 插件等包含在 [=41] 上我自己的点文件存储库中=]枢纽。
这种情况并不经常发生,但有时当我拉取我的点文件存储库时,我的许多子模块文件都发生了变化。例如,在我最近的 git fetch
中,我得到了这样的东西(删除了几个插件更新以使其更短):
remote: Enumerating objects: 32, done.
remote: Counting objects: 100% (32/32), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 21 (delta 11), reused 20 (delta 10), pack-reused 0
Unpacking objects: 100% (21/21), 2.65 KiB | 14.00 KiB/s, done.
From https://github.com/someone/dotfiles
fb997fe..2bffa27 master -> origin/master
Fetching submodule tmux/plugins/tmux-yank
From https://github.com/tmux-plugins/tmux-yank
d776f4e..1b1a436 master -> origin/master
Fetching submodule vim/bundle/ultisnips
From https://github.com/SirVer/ultisnips
7941f98..d3b36cd master -> origin/master
Fetching submodule vim/bundle/vimtex
From https://github.com/lervag/vimtex
9b53bb31..49eab5d5 master -> origin/master
* [new tag] v1.4 -> v1.4
合并期间:
herophant:~/.dotfiles$ git merge
Updating fb997fe..2bffa27
Fast-forward
.gitmodules | 9 +++++++++
bashrc | 6 ++++++
tmux/plugins/tmux-yank | 2 +-
vim/UltiSnips/tex.snippets | 8 ++++++++
vim/bundle/rainbow | 1 +
vim/bundle/syntastic | 1 +
vim/bundle/ultisnips | 2 +-
vim/bundle/vim-airline | 2 +-
vim/bundle/vim-airline-themes | 2 +-
vim/bundle/vim-fugitive | 2 +-
vim/bundle/vim-racket | 1 +
vim/bundle/vimtex | 2 +-
vim/ftplugin/tex.vim | 1 +
vimrc | 20 ++++++++++++++++++--
14 files changed, 51 insertions(+), 8 deletions(-)
create mode 160000 vim/bundle/rainbow
create mode 160000 vim/bundle/syntastic
create mode 160000 vim/bundle/vim-racket
create mode 100644 vim/ftplugin/tex.vim
现在我的 git 状态(短格式)显示:
## master...origin/master
M .gitmodules
M tmux/plugins/tmux-yank
M vim/bundle/ultisnips
M vim/bundle/vim-airline
M vim/bundle/vim-airline-themes
M vim/bundle/vim-fugitive
M vim/bundle/vimtex
我真的不在乎子模块发生了什么,但如果它们得到更新,那可能是一件好事。我只是希望他们默默地做这件事,这样我就不必再做一次承诺来解决这个问题。有办法实现吗?
编辑:即使我将此更改提交到原始哈希,在一台机器上提交一个原始提交哈希会导致其他机器在 git pull
之后将这些提交哈希“修改”到它们以前的版本。
例如,vim-airline-themes 是昨天修改的。我不确定发生了什么,但是在 git commit
、vim-airline-themes 之后立即显示已修改。好的,我再做一次提交。这就是改变的地方
me@main-machine:~/.dotfiles$ git diff 4577802~ 4577802
diff --git a/vim/bundle/vim-airline-themes b/vim/bundle/vim-airline-themes
index e1b0d9f..7f53ebc 160000
--- a/vim/bundle/vim-airline-themes
+++ b/vim/bundle/vim-airline-themes
@@ -1 +1 @@
-Subproject commit e1b0d9f86cf89e84b15c459683fd72730e51a054
+Subproject commit 7f53ebc8f7af2fd7e6a0a31106b99491e01cd18f
我承诺,再做一些 git pull
s 只是为了确定,并且“没有新的变化”。我转到我的另一台机器,从我的 dotfiles 存储库中执行 git pull
,然后看到 /vim/bundle/vim-airline-themes
子模块已被修改。改变了什么?
me@other-machine:~/.dotfiles$ git diff vim/bundle/vim-airline-themes
diff --git a/vim/bundle/vim-airline-themes b/vim/bundle/vim-airline-themes
index 7f53ebc..e1b0d9f 160000
--- a/vim/bundle/vim-airline-themes
+++ b/vim/bundle/vim-airline-themes
@@ -1 +1 @@
-Subproject commit 7f53ebc8f7af2fd7e6a0a31106b99491e01cd18f
+Subproject commit e1b0d9f86cf89e84b15c459683fd72730e51a054
Git 似乎出于某种原因想要撤消它自己的更改?这一切看起来都是多余的,而且我相信这可以通过某种方式避免。解决方法是什么?
简短的回答是否定的。更具体地说:
I just want them to do this silently so that I don't have to make another commit to account for this.
您确实需要重新提交!子模块是另一个 Git 存储库,因此,它分两部分实现:
首先(在许多方面不那么重要),您将在超级项目的 work-tree 的顶层有一个名为 .gitmodules
的文件。这个文件进入每个提交,它存储一个新的 superproject-clone 需要的信息,以便 运行 它自己的每个子模块的 git clone
。
其次 - 也是您需要进行新提交的原因 - 每个 commit 存储一个 data-pair,包括:
- 子模块的路径,
- 要使用的原始提交哈希 ID 在 子模块中。
超级项目 Git 使用这些哈希 ID 来了解每个子模块中 git checkout
的内容。子模块存储库由 由 其超级项目控制,由超级项目 Git 执行:
(cd $path && git checkout $hash)
在指定提交的子模块中获取 detached-HEAD。 $path
和 $hash
来自超级项目提交。
各个子模块中的每一个都得到更新的事实并不是这里的触发器。您(大概)想要 在 子模块 中使用最新提交 的事实是触发器:您需要 record 这个事实在你的超级项目中。为此需要在超级项目 Git.
中进行新的提交
编辑: 如下面的评论所述,要从哪个子模块 repository/ies 中准确决定要提交的内容可能会变得非常棘手。我个人不喜欢 git pull
但它确实有一个在这里很有用的功能:你可以让它递归地进入每个子模块和 运行 另一个 git pull
在每个子模块中。不过那是一把 multi-edged 剑,因为你可能不想要一把 拉 本身。
您可以在超级项目中 运行 的 git submodule
命令也有多种操作模式:git submodule update --remote
有您的超级项目 运行 a [=每个子模块中的 20=] 后跟每个子模块中的 git checkout
。将此与不带 --remote
的 git submodule update
进行比较,后者将 运行 每个子模块中的 git fetch
后跟每个子模块中的 git checkout
。这提出了一个明显(但很好)的问题:鉴于我们只是说两者做同样的事情,确切地说,区别是什么?答案在于 git checkout
使用的哈希 ID。没有 --remote
的那个使用 superproject 要求的哈希 ID。带有 --remote
的那个使用哈希 ID,该哈希 ID 与相关子模块中的某些 remote-tracking 名称 一起使用,由 git fetch
运行 在该子模块中。
涉及到如此多的存储库——一个用于超级项目,一个用于超级项目的远程,每个子模块一个,每个子模块一个远程,所有这些都在这里使用——它变得混乱。再加上每个子模块都可以是一个或多个它自己的子模块的超级项目,并且这些操作中的每一个都可以递归,也可以不递归,这简直是一场噩梦。
这种事情是子模块有时被称为“sob-modules”的挥之不去的原因之一。子模块的许多最痛苦的方面是......好吧,我现在不会说 fixed,但比十年前不那么痛苦了。但是 Git 由于是分布式的,本来就很棘手,而子模块只会使这种情况呈指数级恶化。
所有这些都没有单一的治疗方法:这确实是一个难题,您只需要投入大量 skull-sweat 即可。如果您的各个子模块的作者协调他们的工作,那会有所帮助。
我对子模块和 git 比较陌生,但我一直在使用它们将我所有的 tmux 和 vim 插件等包含在 [=41] 上我自己的点文件存储库中=]枢纽。
这种情况并不经常发生,但有时当我拉取我的点文件存储库时,我的许多子模块文件都发生了变化。例如,在我最近的 git fetch
中,我得到了这样的东西(删除了几个插件更新以使其更短):
remote: Enumerating objects: 32, done.
remote: Counting objects: 100% (32/32), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 21 (delta 11), reused 20 (delta 10), pack-reused 0
Unpacking objects: 100% (21/21), 2.65 KiB | 14.00 KiB/s, done.
From https://github.com/someone/dotfiles
fb997fe..2bffa27 master -> origin/master
Fetching submodule tmux/plugins/tmux-yank
From https://github.com/tmux-plugins/tmux-yank
d776f4e..1b1a436 master -> origin/master
Fetching submodule vim/bundle/ultisnips
From https://github.com/SirVer/ultisnips
7941f98..d3b36cd master -> origin/master
Fetching submodule vim/bundle/vimtex
From https://github.com/lervag/vimtex
9b53bb31..49eab5d5 master -> origin/master
* [new tag] v1.4 -> v1.4
合并期间:
herophant:~/.dotfiles$ git merge
Updating fb997fe..2bffa27
Fast-forward
.gitmodules | 9 +++++++++
bashrc | 6 ++++++
tmux/plugins/tmux-yank | 2 +-
vim/UltiSnips/tex.snippets | 8 ++++++++
vim/bundle/rainbow | 1 +
vim/bundle/syntastic | 1 +
vim/bundle/ultisnips | 2 +-
vim/bundle/vim-airline | 2 +-
vim/bundle/vim-airline-themes | 2 +-
vim/bundle/vim-fugitive | 2 +-
vim/bundle/vim-racket | 1 +
vim/bundle/vimtex | 2 +-
vim/ftplugin/tex.vim | 1 +
vimrc | 20 ++++++++++++++++++--
14 files changed, 51 insertions(+), 8 deletions(-)
create mode 160000 vim/bundle/rainbow
create mode 160000 vim/bundle/syntastic
create mode 160000 vim/bundle/vim-racket
create mode 100644 vim/ftplugin/tex.vim
现在我的 git 状态(短格式)显示:
## master...origin/master
M .gitmodules
M tmux/plugins/tmux-yank
M vim/bundle/ultisnips
M vim/bundle/vim-airline
M vim/bundle/vim-airline-themes
M vim/bundle/vim-fugitive
M vim/bundle/vimtex
我真的不在乎子模块发生了什么,但如果它们得到更新,那可能是一件好事。我只是希望他们默默地做这件事,这样我就不必再做一次承诺来解决这个问题。有办法实现吗?
编辑:即使我将此更改提交到原始哈希,在一台机器上提交一个原始提交哈希会导致其他机器在 git pull
之后将这些提交哈希“修改”到它们以前的版本。
例如,vim-airline-themes 是昨天修改的。我不确定发生了什么,但是在 git commit
、vim-airline-themes 之后立即显示已修改。好的,我再做一次提交。这就是改变的地方
me@main-machine:~/.dotfiles$ git diff 4577802~ 4577802
diff --git a/vim/bundle/vim-airline-themes b/vim/bundle/vim-airline-themes
index e1b0d9f..7f53ebc 160000
--- a/vim/bundle/vim-airline-themes
+++ b/vim/bundle/vim-airline-themes
@@ -1 +1 @@
-Subproject commit e1b0d9f86cf89e84b15c459683fd72730e51a054
+Subproject commit 7f53ebc8f7af2fd7e6a0a31106b99491e01cd18f
我承诺,再做一些 git pull
s 只是为了确定,并且“没有新的变化”。我转到我的另一台机器,从我的 dotfiles 存储库中执行 git pull
,然后看到 /vim/bundle/vim-airline-themes
子模块已被修改。改变了什么?
me@other-machine:~/.dotfiles$ git diff vim/bundle/vim-airline-themes
diff --git a/vim/bundle/vim-airline-themes b/vim/bundle/vim-airline-themes
index 7f53ebc..e1b0d9f 160000
--- a/vim/bundle/vim-airline-themes
+++ b/vim/bundle/vim-airline-themes
@@ -1 +1 @@
-Subproject commit 7f53ebc8f7af2fd7e6a0a31106b99491e01cd18f
+Subproject commit e1b0d9f86cf89e84b15c459683fd72730e51a054
Git 似乎出于某种原因想要撤消它自己的更改?这一切看起来都是多余的,而且我相信这可以通过某种方式避免。解决方法是什么?
简短的回答是否定的。更具体地说:
I just want them to do this silently so that I don't have to make another commit to account for this.
您确实需要重新提交!子模块是另一个 Git 存储库,因此,它分两部分实现:
首先(在许多方面不那么重要),您将在超级项目的 work-tree 的顶层有一个名为
.gitmodules
的文件。这个文件进入每个提交,它存储一个新的 superproject-clone 需要的信息,以便 运行 它自己的每个子模块的git clone
。其次 - 也是您需要进行新提交的原因 - 每个 commit 存储一个 data-pair,包括:
- 子模块的路径,
- 要使用的原始提交哈希 ID 在 子模块中。
超级项目 Git 使用这些哈希 ID 来了解每个子模块中 git checkout
的内容。子模块存储库由 由 其超级项目控制,由超级项目 Git 执行:
(cd $path && git checkout $hash)
在指定提交的子模块中获取 detached-HEAD。 $path
和 $hash
来自超级项目提交。
各个子模块中的每一个都得到更新的事实并不是这里的触发器。您(大概)想要 在 子模块 中使用最新提交 的事实是触发器:您需要 record 这个事实在你的超级项目中。为此需要在超级项目 Git.
中进行新的提交编辑: 如下面的评论所述,要从哪个子模块 repository/ies 中准确决定要提交的内容可能会变得非常棘手。我个人不喜欢 git pull
但它确实有一个在这里很有用的功能:你可以让它递归地进入每个子模块和 运行 另一个 git pull
在每个子模块中。不过那是一把 multi-edged 剑,因为你可能不想要一把 拉 本身。
您可以在超级项目中 运行 的 git submodule
命令也有多种操作模式:git submodule update --remote
有您的超级项目 运行 a [=每个子模块中的 20=] 后跟每个子模块中的 git checkout
。将此与不带 --remote
的 git submodule update
进行比较,后者将 运行 每个子模块中的 git fetch
后跟每个子模块中的 git checkout
。这提出了一个明显(但很好)的问题:鉴于我们只是说两者做同样的事情,确切地说,区别是什么?答案在于 git checkout
使用的哈希 ID。没有 --remote
的那个使用 superproject 要求的哈希 ID。带有 --remote
的那个使用哈希 ID,该哈希 ID 与相关子模块中的某些 remote-tracking 名称 一起使用,由 git fetch
运行 在该子模块中。
涉及到如此多的存储库——一个用于超级项目,一个用于超级项目的远程,每个子模块一个,每个子模块一个远程,所有这些都在这里使用——它变得混乱。再加上每个子模块都可以是一个或多个它自己的子模块的超级项目,并且这些操作中的每一个都可以递归,也可以不递归,这简直是一场噩梦。
这种事情是子模块有时被称为“sob-modules”的挥之不去的原因之一。子模块的许多最痛苦的方面是......好吧,我现在不会说 fixed,但比十年前不那么痛苦了。但是 Git 由于是分布式的,本来就很棘手,而子模块只会使这种情况呈指数级恶化。
所有这些都没有单一的治疗方法:这确实是一个难题,您只需要投入大量 skull-sweat 即可。如果您的各个子模块的作者协调他们的工作,那会有所帮助。