Python 试图从git pull中删除身份验证,从而创建奇怪的合并冲突和更改,这些冲突和更改不应';不存在

Python 试图从git pull中删除身份验证,从而创建奇怪的合并冲突和更改,这些冲突和更改不应';不存在,python,git,subprocess,git-pull,Python,Git,Subprocess,Git Pull,我编写了一个脚本来帮助在git中自动处理大型请求。我正在尝试摆脱用户在执行诸如拉动更新分支之类的操作时需要登录的情况,因此我一直在尝试找出如何做到这一点。所以,我最终在Bitbucket服务器中创建了一个个人令牌,看看我是否可以让它为自己工作,它确实可以工作。个人令牌并不适用于所有人,但我希望找到正确的语法来测试它 我想出的命令是: subprocess.check_call(['git', 'pull']+[f'https://{username}:{MYTOKEN}@{repo_url}']

我编写了一个脚本来帮助在git中自动处理大型请求。我正在尝试摆脱用户在执行诸如拉动更新分支之类的操作时需要登录的情况,因此我一直在尝试找出如何做到这一点。所以,我最终在Bitbucket服务器中创建了一个个人令牌,看看我是否可以让它为自己工作,它确实可以工作。个人令牌并不适用于所有人,但我希望找到正确的语法来测试它

我想出的命令是:

subprocess.check_call(['git', 'pull']+[f'https://{username}:{MYTOKEN}@{repo_url}'], cwd=repo_path)
但是我从它那里得到了非常奇怪的行为,它从我制作的脚本中提取了一堆文件,然后是一堆我没有碰过的文件。在这两种情况下,我从未将任何内容推送到远程分支,或提交到本地分支。舞台区也没有任何东西

所以,我试着看看会发生什么,我得到了正确的行为,它说我的回购是最新的,没有什么可拉。这与我一直在做的手动git拉取相匹配,因为我实际上没有接触任何文件。但它需要用户输入凭据,这正是我试图摆脱的

subprocess.check_call('git pull',cwd=repo_path)

知道是什么导致了这样的事情吗?

首先,我要说的是,您通常不应该在这里使用
git pull
,因为您正在编写一个不应该是交互式的脚本,并且
git pull
在运行第二个命令时尝试是交互式的。(有一些方法可以解决这个问题,特别是在Git的现代版本中,但这将有助于将事情分解为两个单独的步骤。)

这样一来,无论您是使用
git pull
运行
git fetch
,还是自己运行
git fetch
,都有一个关键区别:

git <command>
当我们使用URL运行同一命令时,即使是
git fetch origin
将使用的URL,我们也会改为get:

1c52ecf4ba0f4f7af72775695fee653f50737c71        <url>
这里的
命令
部分通常是
git merge
git rebase
中的一个(这里有一个非常特殊的情况不适用于两者都不是的情况)。
选项
取决于命令,因为
git merge
获得一个
-m
选项,而
git rebase
没有(但可以获得其他选项)。
hash
是这里真正的问题

git pull
提供给
git merge
git rebase
的哈希ID来自该
.git/FETCH\u HEAD
文件。当使用远程文件时,该文件的一行将对应于当前分支的上游,这就是Git将使用的哈希ID。但是当给
git fetch
一个URL而不是一个分支名时,fetch命令只写了一个散列ID:另一个git存储库的
头的散列ID
。如果这不是正确的散列ID,则第二个命令将使用错误的散列ID

这几乎可以肯定是正在发生的事情

如何解决这个问题 您可以通过以下方式进行修复:

  • git pull
    提供正确的名称,以便它可以将其传递给
    git fetch
    ,和/或
  • 自己运行
    git fetch
    ,然后根据需要自己运行第二个git命令
考虑到
git pull
的设计是交互式的,因此会根据用户的首选项配置设置更改其行为方式,我建议您同时执行这两项操作:自己运行
git fetch
,然后确定要运行的第二个命令

提取可能仍然需要访问令牌。(顺便说一句,在命令行上传递此消息会使机器上的其他进程可以读取访问令牌,因此它不是很安全。在一个安全的文件中设置一个保存令牌的远程,然后使用远程名称,可能会更安全一些。远程名称将控制远程跟踪名称,这些名称将继续使用。)在我前面提到的“持续烦恼”中,有更多的解决方法,但是一旦你有了一些远程跟踪名称,烦恼级别就相当低了,这可能已经足够好了。)但是现在,不管你怎么做,它都可以得到你想在另一个Git存储库中解析的任何分支或标记的名称,以便找到合适的人选


第二个命令仍然可以是
git merge
,可以是
--ff only
,也可以是rebase,检查是否成功并在失败时回滚,甚至可以是
git checkout
,以使用分离的头,而不是尝试更改本地存储库中的任何现有分支名称。不过,重要的是,通过知道git pull实际上意味着fetch,然后运行第二个命令,并且知道这里的各种选项,您可以控制这两个操作的所有部分。你不会因为使用了错误的选项和/或错误的分支名称而随心所欲地使用git pull。

我的解决办法是在它的末尾添加origin。我认为你的解释基本上仍然是正确的,因为它没有正确地执行。如果你保留
git pull
和URL,你只需要添加一个分支名称。这会将URL和分支名称提供给
git fetch
(请记住
pull
仍然是
fetch
+第二个命令)。如果还包括
origin
,则将
origin
和分支名称都提供给
git fetch
:这不是您想要的。它通常是无害的,但在极少数情况下,它会导致合并步骤执行八达通合并。
1c52ecf4ba0f4f7af72775695fee653f50737c71        <url>
git <command> <options> <hash>