Git 子模块和 ssh 访问
我在使用包含多个子模块的 git 存储库时遇到一些问题。
超级 git 存储库是使用以下命令构建的:
mkdir projectname
cd projectname
git init
git submodule add ssh://myusername@server/pathtorepos
当不同的用户(“其他用户”)克隆超级存储库时,一切似乎都正常。但是当需要访问子模块时,
git submodule init
git submodule update
git 会尝试使用“myusername”而不是“otheruser”来克隆子模块。
如何解决这个问题呢?
I have some trouble with a git repository that contains several submodules.
The super git repository was constructed with the commands
mkdir projectname
cd projectname
git init
git submodule add ssh://myusername@server/pathtorepos
When a different user ("otheruser") then clones the super repository everything seems to work out. But when it is time to get access to the submodule
git submodule init
git submodule update
git tries to clone the submodule using "myusername" instead of "otheruser".
How to solve this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果可能,最好确保
.gitmodules
文件包含任何人都可以克隆的存储库的 URL,通常是git://
或http://
网址。然后,具有 SSH 访问权限的用户可以在克隆后更改为子模块,并将remote.origin.url
中的 URL 更改为使用其用户名指向 SSH URL,例如:其他用户应该能够即使在当前情况下也要这样做。 更新: Chris Johnsen 在下面指出,如果省略用户名,那么在
.gitmodules
中使用 SSH URL 也是合理的,并且存储库的所有用户都将具有 SSH 访问权限 -如果本地和远程的用户名不同,他们需要添加与上述类似的用户名。请注意,
.gitmodules
中的 URL 仅在初始化子模块时使用。初始化子模块会将主项目中的配置值submodule..url
设置为.gitmodules
中提交的内容 - 这是将使用的值在第一次子模块更新时。在初始化和更新子模块之间,您还可以使用如下命令更改将用于第一次更新的 URL:事实上,如果第一次更新失败,您可能需要执行此操作。第一次更新子模块后,您需要更改的 URL 是为子模块中的
origin
定义的 URL - 此时仅设置submodule.my-submodule 有用如果您可能要删除并重新更新子模块,请在主项目中添加 .url
配置值。If possible, it's best to make sure that the
.gitmodules
file contains a URL for the repository that can be cloned by anyone, typically either agit://
orhttp://
URL. Then users that have SSH access themselves can change into the submodule after cloning and change the URL inremote.origin.url
to point to an SSH URL with their username, e.g.:The other user should be able to do that even in the current situation. Update: Chris Johnsen points out below that it's also reasonable to use an SSH URL in
.gitmodules
if you omit the username and all the users of the repository will have SSH access - they'll need to add their username similarly to the above if it differs locally and remotely.Note that the URLs in
.gitmodules
are only used when initializing the submodule. Initializing the submodule sets the config valuesubmodule.<SUBMODULE-NAME>.url
in the main project to whatever's committed in.gitmodules
- this is the value that will be used on the first submodule update. Between initializing and updating the submodule, you can also change this URL that will be used for that first update with a command like:Indeed, you may need to do this if the first update fails. Once the submodule has been updated for the first time, the URL you need to change is that defined for
origin
within the submodule - at that point it's only useful to set thesubmodule.my-submodule.url
config value in the main project if you're likely to be deleting and re-updating the submodule.不要使用绝对 URL!在开源项目中,我们在添加子模块时使用相对 URL,该 URL 位于
.gitmodules
文件中。这将导致 git 根据父项目的 URL 克隆子模块 URL。使用相对路径可以完全避免指定协议(https、ssh)和用户名。例如,如果您想要的子模块可从 Git 服务器作为对等存储库获取,请在存储库的根目录中添加该对等子模块,如下所示:
然后创建/扩展
.gitmodules
文件像这样的条目:这样,就没有人需要编辑模块文件了。
ps 发布后我意识到我的答案是一个骗局,这是您应该使用的来源: 通过 ssh 或 https 自动访问 git 子模块
Don't use absolute URLs! In an open-source project we use a RELATIVE URL when adding the submodule, and that goes in the
.gitmodules
file. This will cause git to clone the submodule URL based on the URL of the parent project. Using a relative path neatly avoids specifying protocol (https, ssh) and username entirely.For example, if the submodule you want is available from your Git server as a peer repository, work in your repo's root directory to add that peer submodule like this:
Then the
.gitmodules
file is created/extended with an entry like this:This way, nobody has to edit the modules file.
p.s. after posting I realized that my answer is a dupe, here is the source you should use: Automatically access git submodules via ssh or https
另一个用户必须更改 .git/config 文件才能将用户名更改为他自己的用户名。这样,git 使用正确的用户连接到服务器。
The other user has to alter the
.git/config
file to change the user name to his own username. That way, git uses the right user to connect to the server.仅供参考,我最终使用的解决方案如下。
实际上其他人可以查看现有的存储库。
当我需要签出存储库时,可以使用以下命令来完成
对于其他人签出超级存储库,使用以下命令集。
唯一的区别是手动克隆其他存储库
请注意,发出命令后
,git 会告诉您请求的存储库和可用的存储库不相同。但这并不是致命的,您可以安全地继续。
Just for reference, the solution I ended up using is the following.
It is actually possible for others to check out the existing repository.
When I need to check out the repository it can be done with the commands
For others to check out the super repository, the following set of commands is used.
The only difference is the manual cloning of the other repository
Note that after issuing the
command, git will tell you that the requested repository and the available is not identical. But this is not fatal and you can safely continue.
不要在 URL 中包含用户名。当您克隆/拉取/等时,git 将提示输入用户名和密码
Do not include the username in the URL. git will prompt for the username and password when you clone/pull/etc
我的2美分:
我在使用创建存储库的同一用户从父级内部更新子模块存储库时遇到问题。我发现这是由 SSH 密钥上的密码引起的。当父-子存储库作为子模块连接并保存到 Git 时,我尝试将项目克隆到新位置。克隆父级成功(使用 SSH 密钥克隆时,我输入了密钥的密码)。但是,
git submodule update
命令失败,并出现Permission returned (publickey...)
,且未询问密码。当我删除密码后,更新命令成功运行。My 2 cents:
I had a problem updating the Submodule repo from within the Parent with the same user who created the repo. I found it was caused by the passphrase on the SSH key. When the Parent - Child repositories are connected as submodules and persisted to Git, I tried to clone the project to a new location. Cloning the parent succeeded (when cloning with an SSH key, I entered passphrase for the key). However, the
git submodule update
command failed withPermission denied (publickey...)
, without asking for the passphrase. When I removed the passphrase, the update command ran successfully.调试
通常,克隆(使用 ssh)的问题是 git 尝试使用 ssh 进行远程身份验证,但失败了。 添加详细模式
您可以使用
which ssh
调试此过程,并使用GIT_SSH_COMMAND="ssh -v" git clone --recurse-submodules [URL]
或 Windows
>set GIT_SSH_COMMAND=ssh -v
然后运行克隆命令。虽然对于这个特定问题,不使用子模块的绝对 URL 或避免将用户添加到这些 URL 可能是正确的答案;我(可能还有许多其他人)来到这里是为了寻找 ssh 访问的棘手问题的解决方案,我觉得这样的调试在很多情况下都会有所帮助,就像它对我所做的那样。
示例
我使用 Windows CMD+WSL2。运行 git 命令的 ssh -v 详细输出告诉
我,ssh 可能无法访问终端来获取 rsa 密钥的密码。尽管它适用于主存储库,但不适用于子模块。所以过了一段时间,我在某处读到 Windows 添加了自己的 OpenSSH 版本。 Windows 安装的 git 使用自己的 ssh,无法找到终端设备。我能够使用
set GIT_SSH_COMMAND="C:/WINDOWS/System32/OpenSSH/ssh"
通过 ssh 针对 WSL2 + CMD 修复子模块克隆Debugging
Usually, the problem with cloning (using ssh) is that git tries to use
ssh
for authentication to the remote and it fails. You can debug this process usingwhich ssh
and furthermore adding verbose mode usingGIT_SSH_COMMAND="ssh -v" git clone --recurse-submodules [URL]
or for windows
set GIT_SSH_COMMAND=ssh -v
and then running the clone command.While it might be a correct answer to not to use absolute URLs for submodules or avoid adding users to these urls for this particular question; I (and probably many others) arrive here in search for solution to trickier problems with ssh access and I felt such debugging can help in many cases, as it did for me.
Example
I was using Windows CMD+WSL2. Running the
ssh -v
verbose output for git commands I gotWhich told me that the ssh cannot probably access the terminal to get the password for the rsa key. Although it worked for the main repository, it did not for the submodules. So after a while, I read somewhere that windows added its own OpenSSH version. The git for windows installation was using its own ssh that could not find the terminal device. I was able to fix submodule cloning via ssh for WSL2 + CMD using
set GIT_SSH_COMMAND="C:/WINDOWS/System32/OpenSSH/ssh"