回答:
このgit describe
コマンドは、人間が提示できるコードの「バージョン番号」を作成するための優れた方法です。ドキュメントの例から:
git.git current treeのようなもので、私は得ます:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721
つまり、私の「親」ブランチの現在のヘッドはv1.0.4に基づいていますが、その上にいくつかのコミットがあるため、describeは追加のコミット( "14")の数とそのコミットの省略されたオブジェクト名を追加しました最後にそれ自体(「2414721」)。
Python内から、次のようなことができます。
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
fatal: No names found, cannot describe anything.
git describe --always
タグが見つからない場合、最後のコミットにフォールバックします
git describe
通常、少なくとも1つのタグが必要です。タグがない場合は、--always
オプションを使用します。詳細については、git describeのドキュメントを参照してください。
git
コマンドからデータを取得するためにハッキングする必要はありません。GitPythonは、これや他の多くのことを行うための非常に優れた方法git
です。Windowsの「ベストエフォート」もサポートしています。
pip install gitpython
あなたができる後
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
ImportError: No module named gitpython
。エンドユーザーがgitpython
インストールしたことに依存することはできません。また、コードが機能する前にエンドユーザーにインストールを要求すると、移植できなくなります。自動インストールプロトコルを含めない限り、その時点ではクリーンなソリューションではありません。
pip
/ requirements.txt
)を使用してインストールできます。「クリーン」ではないものは何ですか?
import numpy as np
stackoverflow全体で想定できる理由は不明ですが、gitpythonのインストールは「クリーン」で「ポータブル」ではありません。ホイールを再発明せず、醜い実装を隠蔽し、サブプロセスからのgitの回答をハッキングしないので、これは断然最良のソリューションだと思います。
pip
またはを簡単にインストールできる機能pip
。これらの最新のシナリオでは、pip
ソリューションは「標準ライブラリ」ソリューションと同じくらい移植可能です。
この投稿にはコマンドが含まれ、Gregの回答にはサブプロセスコマンドが含まれています。
import subprocess
def get_git_revision_hash():
return subprocess.check_output(['git', 'rev-parse', 'HEAD'])
def get_git_revision_short_hash():
return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
.decode('ascii').strip()
バイナリ文字列をデコードするためにa を追加します(そして改行を削除します)。
numpy
その中に見栄えの良いマルチプラットフォームルーチンがありますsetup.py
:
import os
import subprocess
# Return the git revision as a string
def git_version():
def _minimal_ext_cmd(cmd):
# construct minimal environment
env = {}
for k in ['SYSTEMROOT', 'PATH']:
v = os.environ.get(k)
if v is not None:
env[k] = v
# LANGUAGE is used on win32
env['LANGUAGE'] = 'C'
env['LANG'] = 'C'
env['LC_ALL'] = 'C'
out = subprocess.Popen(cmd, stdout = subprocess.PIPE, env=env).communicate()[0]
return out
try:
out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
GIT_REVISION = out.strip().decode('ascii')
except OSError:
GIT_REVISION = "Unknown"
return GIT_REVISION
env
が、クロスプラットフォーム機能にはdictのセットアップが必要だと思っていました。祐二の答えはそうではありませんが、おそらくそれはUNIXとWindowsの両方で機能します。
.decode('ascii')
動作するようにロケールを設定します-それ以外の場合、エンコーディングは不明です。
サブプロセスが移植可能ではなく、パッケージをインストールしてこれほど簡単なことをしたくない場合は、これも実行できます。
import pathlib
def get_git_revision(base_path):
git_dir = pathlib.Path(base_path) / '.git'
with (git_dir / 'HEAD').open('r') as head:
ref = head.readline().split(' ')[-1].strip()
with (git_dir / ref).open('r') as git_hash:
return git_hash.readline().strip()
私はこれを私のリポジトリでテストしただけですが、それはかなり一貫して動作するようです。
これがグレッグの答えのより完全なバージョンです:
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
または、スクリプトがリポジトリの外部から呼び出されている場合:
import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
os.chdir
、cwd=
argを使用しcheck_output
て、実行前に作業ディレクトリを一時的に変更できます。
何らかの理由でgitを使用できないが、gitリポジトリ(.gitフォルダーが見つかった)がある場合は、.git / fetch / heads / [branch]からコミットハッシュをフェッチできます。
たとえば、コミットIDを取得するために、リポジトリルートで実行される次の汚いPythonスニペットを使用しました。
git_head = '.git\\HEAD'
# Open .git\HEAD file:
with open(git_head, 'r') as git_head_file:
# Contains e.g. ref: ref/heads/master if on "master"
git_head_data = str(git_head_file.read())
# Open the correct file in .git\ref\heads\[branch]
git_head_ref = '.git\\%s' % git_head_data.split(' ')[1].replace('/', '\\').strip()
# Get the commit hash ([:7] used to get "--short")
with open(git_head_ref, 'r') as git_head_ref_file:
commit_id = git_head_ref_file.read().strip()[:7]
git rev-parse HEAD
コマンドラインから始めます。出力構文は明白でなければなりません。