在windows上从Python3.x获取git标记
我尝试过,但无法在Windows10上用Python 3.8完成一项看似微不足道的任务。 在PowerShell(core)中,我用不到2分钟的时间编写:在windows上从Python3.x获取git标记,python,git,powershell,Python,Git,Powershell,我尝试过,但无法在Windows10上用Python 3.8完成一项看似微不足道的任务。 在PowerShell(core)中,我用不到2分钟的时间编写: repo = "../micropython/git" return (&git --git-dir=$repo describe --tags $(git --git-dir=$repo rev-list --tags='v[0-9].[0-9]*' --max-count=1)) 结果是该分支所在的“v1.12”(或任何最新版本
repo = "../micropython/git"
return (&git --git-dir=$repo describe --tags $(git --git-dir=$repo rev-list --tags='v[0-9].[0-9]*' --max-count=1))
结果是该分支所在的“v1.12”(或任何最新版本)
在花了太多时间在这个假定的oneliner上之后,使用python我根本无法得到任何结果
尝试:
# 1 feeding it the commandline as text
cmd_str = "git --git-dir=../micropython/.git describe --tags $(git --git-dir=../micropython/.git rev-list --tags='v[0-9].[0-9]*' --max-count=1)"
subprocess.run( cmdstr , capture_output=True,shell=True)
#2 splitting the cmdline using shlex.split
command_line = """
git describe --tags $(git rev-list --tags=\"v[0-9].[0-9]*\" --max-count=1)
"""
cmd = shlex.split(command_line)
x = subprocess.run( cmd, capture_output=True )
print(x)
# 3 using the 'gitpython' library
would not even import .... : see issue below
#4..20
many variations of the above
因此,作为一名开发人员,对我来说,最简单的方法似乎是从python到powershell(因为这是跨平台的),并获得依赖性
不过,我是在python而不是powershell中开始编写的,因为脚本是为python社区编写的(并且是一种学习体验),当然有一种方法可以以更类似于pylike的方式完成这项工作,甚至可能有点优雅
版本:
- Microsoft Windows[版本10.0.19041.1]
- git版本2.24.1.windows.2
- Python 3.8.1
capture_output=True
,以防有人(cough me cough)将3.6作为他们方便的测试系统的基础版本,并允许使用shell,这是$(…)
扩展所需的,这或多或少让我们第一次尝试。但是我们可以利用这样一个事实,即--git dir
相当于在环境中设置git_dir
,这意味着我们不必在命令字符串中执行两次:
import os, subprocess
env = os.environ.copy()
env["GIT_DIR"] = "../micropython/.git"
cmd = "git describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)"
ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=env, shell=True)
(当然,只要所有python都是3.7或更高版本,就可以使用capture\u output=True
作为两个stdout/stderr的缩写)
请注意,我们必须保存结果。这就是为什么我们在这里有ret=
来捕获结果。我们现在在ret
中得到了结果:
>>> print(ret)
CompletedProcess(args="git describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)", returncode=0, stdout=b'v2.24.0\n', stderr=b'')
请注意,retcode
是零,也就是说,作为一个整体,这两个stdout
和stderr
字段是字节而不是字符串。要解决此问题,我们可以在之后解码结果:
>>> print(ret.stdout.decode('utf-8'))
v2.24.0
>>>
(假设输出为UTF-8)或让子流程为我们执行。现代(3.7或更高版本)的方法是设置text=True
,但由于在这台特定的机器上我仍然坚持使用3.6,因此我使用了旧的方法:
ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=env, shell=True, universal_newlines=True)
这将产生更有用的结果:
>>> print(ret)
CompletedProcess(args="git describe --tags $(git rev-list --tags='v[0-9].[0-9]*' --max-count=1)", returncode=0, stdout='v2.24.0\n', stderr='')
请注意,使用shell=True
。也就是说,在Windows上,您可以得到“COMSPEC
环境变量”中的任何shell。使用默认的shell=False
并分别调用每个组件可能更明智:
import os, shlex, subprocess
env = os.environ.copy()
env["GIT_DIR"] = "../micropython/.git"
cmd = shlex.split("git rev-list --tags='v[0-9].[0-9]*' --max-count=1")
ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
if ret.returncode == 0:
# Note: I tested this w/o using universal_newlines=True and it
# worked fine, although the notion of adding a list of bytes to
# a list of strings seems a bit odd. This might not work well on
# Windows; consider adding `text=True` or `universal_newlines=True`
# above (and again below).
cmd = shlex.split("git describe --tags") + [ret.stdout.strip()]
ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
此时,ret
再次适合检查:如果ret.returncode
为零,ret.stdout
具有来自git sdescribe
的字节字符串。根据需要为文本翻译添加适当的字节
>>> print(ret)
CompletedProcess(args=['git', 'describe', '--tags', b'da72936f544fec5a335e66432610e4cef4430991'], returncode=0, stdout=b'v2.24.0\n', stderr=b'')
如果
ret.returncode
不为零,则说明git description
失败,或者先前的git rev列表失败。您在ret.args
中有失败的命令,它的状态在ret.returncode
中,在ret.stdout
中有任何stdout文本,在ret.stderr中有来自Git的任何错误消息Powershell是跨平台的?如果安装了,使用最简单的语法可能会更简单。为子shell运行一个子脚本,然后将结果拼接到主脚本中。是的,pwsh 6.x,也称为PowerShell Core,在许多不同的体系结构上运行。看,我同意你写的大部分内容;但是计算机说不:CompletedProcess(args=“git description--tags$(git rev list--tags='v[0-9].[0-9]*'--max count=1)”,returncode=129,stdout=b'',stderr=b“error:option
tags'不带任何值”`你们的参考平台是什么?我在一台机器上运行git版本2.24,在另一台机器上运行2.20.1。Git早在2010年就获得了对commit中的--tags=
的支持,在Git版本1.7.0.BTW中,看看您最初的问题陈述,如果我将其正确理解为“描述当前分支”,那么您的PowerShell代码就太复杂了。您得到的是一种在所选修订版上运行git descripe
的方法,方法是枚举与所选全局模式匹配的标记中日期最高的提交。我相信,我让Python代码做了与shell命令相同的事情。