私はここでGitフックを使って派手なことをしようとしていますが、その方法(または可能かどうか)を本当に知りません。
私がする必要があるのは、すべてのコミットでそのハッシュを取得し、そのハッシュでコミット内のファイルを更新することです。
何か案は?
念頭に置いたものに似た方法をお勧めします。ビルド/インストール/展開プロセスの一部として生成されるntrackedファイルにSHA1を配置します。明らかに簡単です(git rev-parse HEAD > filename
多分 git describe [--tags] > filename
)、そしてそれはgitの追跡とは異なるファイルで終わるような狂ったことを避ける。
コードは、バージョン番号が必要なときにこのファイルを参照できます。または、ビルドプロセスで情報を最終製品に組み込むことができます。後者は、実際にはgit自体がバージョン番号を取得する方法です。ビルドプロセスは、リポジトリからバージョン番号を取得し、実行可能ファイルにビルドします。
誰かが私にidentの「man gitattributes」セクションを指摘しました。
ident
属性identがパスに設定されている場合、gitはblobオブジェクトの$ Id $を$ Id:に置き換え、その後に40文字の16進blobオブジェクト名が続き、チェックアウト時にドル記号$が続きます。ワークツリーファイルで$ Id:で始まり$で終わるバイトシーケンスは、チェックイン時に$ Id $に置き換えられます。
考えてみると、これはCVS、Subversionなども同様です。リポジトリを見ると、リポジトリ内のファイルには常に$ Id $などが含まれていることがわかります。それの拡張が含まれることはありません。テキストが展開されるのはチェックアウト時のみです。
現在のコミットハッシュを記述することは不可能です。将来のコミットハッシュを事前に計算できた場合、ファイルを変更するとすぐに変更されます。
ただし、次の3つのオプションがあります。
pre-commit
に以前のコミットハッシュを格納します:) 99.99%のケースではコミットを変更/挿入しないので、これは機能します。最悪の場合でも、ソースリビジョンを特定できます。私はフックスクリプトに取り組んでおり、「完了したら」ここに投稿しますが、それでも-デュークヌケムフォーエバーがリリースされる前に:))
[〜#〜] upd [〜#〜]:.git/hooks/pre-commit
のコード::
#!/usr/bin/env bash
set -e
#=== 'prev-commit' solution by o_O Tync
#commit_hash=$(git rev-parse --verify HEAD)
commit=$(git log -1 --pretty="%H%n%ci") # hash \n date
commit_hash=$(echo "$commit" | head -1)
commit_date=$(echo "$commit" | head -2 | tail -1) # 2010-12-28 05:16:23 +0300
branch_name=$(git symbolic-ref -q HEAD) # http://stackoverflow.com/questions/1593051/#1593487
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD} # 'HEAD' indicates detached HEAD situation
# Write it
echo -e "prev_commit='$commit_hash'\ndate='$commit_date'\nbranch='$branch'\n" > gitcommit.py
必要なのは、prev_commit,branch
ペアを実際のコミットハッシュに変換するツールだけです:)
このアプローチでコミットのマージを区別できるかどうかはわかりません。すぐにチェックします
これは、 gitattributes でfilter
属性を使用することで実現できます。コミットIDを挿入するsmudge
コマンドと、それを削除するclean
コマンドを提供する必要があります。これにより、挿入されたファイルがコミットIDのために変更されないようになります。 。
したがって、コミットIDはファイルのBLOBに保存されることはありません。作業コピーで展開されているだけです。 (コミットIDを実際にBLOBに挿入すると、無限に再帰的なタスクになります。☺)このツリーを複製するユーザーは、自分で属性を設定する必要があります。
コミットボックスの外側を考えてください!
これをファイルhooks/post-checkoutにポップします
#!/bin/sh
git describe --all --long > config/git-commit-version.txt
このバージョンは、どこでも使用できます。
コミット内のファイルが変更されると、コミットのハッシュも変更されるため、実際にそうしたいとは思わない。
これがgit internalsを使用して困難な問題である理由を調べてみましょう。現在のコミットのsha1を取得するには
_#!/bin/bash
commit=$(git cat-file commit HEAD) #
sha1=($((printf "commit %s\0" $(echo "$commit" | wc -c); echo "$commit") | sha1sum))
echo ${sha1[0]}
_
基本的に、_git cat-file commit HEAD
_によって返されたメッセージに対してsha1チェックサムを実行します。このメッセージを調べると、2つのことがすぐに問題として飛び出します。 1つはツリーsha1で、2つ目はコミット時間です。
現在、コミット時間は、メッセージを変更し、特定の時間にコミットするか、コミットするようにスケジューリングするのにかかる時間を推測することで簡単に処理されます。本当の問題は、git ls-tree $(git write-tree) | git mktree
から取得できるツリーsha1です。基本的に、すべてのファイルとそのsha1チェックサムのリストであるls-treeからのメッセージに対してsha1チェックサムを実行しています。
したがって、コミットsha1チェックサムは、ツリーsha1チェックサムに依存します。ツリーsha1チェックサムは、ファイルsha1チェックサムに直接依存し、サークルを完成させ、コミットsha1に依存します。したがって、あなたは自分で利用できるテクニックに循環的な問題を抱えています。
安全性の低いチェックサム を使用すると、総当たりでファイルのチェックサムをファイル自体に書き込むことができることが示されています。ただし、sha1でそのタスクを達成した作業はわかりません。これは不可能ではありませんが、私たちの現在の理解では不可能に近い(しかし、おそらく数年後にそれが些細なことになることを知っている人)。ただし、(ツリー)チェックサム(チェック)の(コミット)チェックサムをファイルに書き込む必要があるため、これはブルートフォースにするのがさらに困難です。