私はここでGitフックを使って空想的なことをやろうとしていますが、どうすればよいのか(あるいはそれが可能かどうか)はわかりません。
私がする必要があるのは、すべてのコミットでそのハッシュを取得し、このハッシュでコミット内のファイルを更新することです。
何か案は?
私はここでGitフックを使って空想的なことをやろうとしていますが、どうすればよいのか(あるいはそれが可能かどうか)はわかりません。
私がする必要があるのは、すべてのコミットでそのハッシュを取得し、このハッシュでコミット内のファイルを更新することです。
何か案は?
回答:
私はあなたが心に描いているのと同じようなことをすることをお勧めします:ビルド/インストール/デプロイメントプロセスの一部として生成された追跡されていないファイルにSHA1を配置します。これは明らかに(git rev-parse HEAD > filename
またはおそらくgit describe [--tags] > filename
)簡単で、gitが追跡しているものとは異なるファイルになってしまうなど、おかしなことは何もしません。
コードは、バージョン番号が必要なときにこのファイルを参照できます。または、ビルドプロセスで情報を最終製品に組み込むことができます。後者は、実際にはgit自体がバージョン番号を取得する方法です。ビルドプロセスは、リポジトリからバージョン番号を取得し、実行可能ファイルにビルドします。
現在のコミットハッシュを書き込むことは不可能です。将来のコミットハッシュを事前に計算できた場合、ファイルを変更するとすぐに変更されます。
ただし、3つのオプションがあります。
pre-commit
、前のコミットハッシュを保存します:) 99.99%の場合、コミットを変更/挿入しないので、これは機能します。最悪の場合でも、ソースリビジョンを特定できます。私はフックスクリプトに取り組んでいますが、「完了したら」ここに投稿しますが、それでも— Duke Nukem Foreverがリリースされる前に:))
更新:コード.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
ペアを実際のコミットハッシュに変換するツールだけです:)
このアプローチでマージコミットを区別できるかどうかはわかりません。すぐにチェックします
誰かが私にidentの「man gitattributes」セクションを指摘しました。
アイデンティティ
パスに属性identが設定されている場合、gitはblobオブジェクトの$ Id $を$ Id:に置き換え、チェックアウト時に40文字の16進数のblobオブジェクト名が続き、その後にドル記号$が続きます。ワークツリーファイルで$ Id:で始まり$で終わるバイトシーケンスは、チェックイン時に$ Id $に置き換えられます。
考えてみれば、これはCVSやSubversionなども同様です。リポジトリを見ると、リポジトリ内のファイルには常に、たとえば$ Id $が含まれていることがわかります。それの拡張は含まれません。テキストが展開されるのは、チェックアウト時のみです。
ident
コミットの速さではなく、ファイル自体のハッシュです。git-scm.com/book/en/…から:「ただし、その結果の使用は制限されています。CVSまたはSubversionでキーワード置換を使用している場合は、日付スタンプを含めることができます。SHAはそれほど役に立ちませんが、それはかなりランダムであり、1つのSHAが別のSHAより古いか新しいかを判断できないためです。」filter
動作しますが、コミット情報をファイルに(またはファイルから)取得できます。
これはgitattributesのfilter
属性を使用することで実現できます。コミットIDを挿入したコマンドと、それを削除したコマンドを提供する必要があります。これにより、挿入されたファイルがコミットIDだけで変更されないようになります。smudge
clean
したがって、コミットIDがファイルのblobに格納されることはありません。作業コピーで展開されるだけです。(実際には、コミットIDをBLOBに挿入すると、無限に再帰的なタスクになります。☺)このツリーを複製する人は、自分の属性を設定する必要があります。
これが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]}
基本的に、によって返されるメッセージに対してsha1チェックサムを実行しgit cat-file commit HEAD
ます。このメッセージを調べると、2つのことがすぐに問題として飛び出します。1つはツリーsha1で、もう1つはコミット時間です。
これで、コミット時間は、メッセージを変更し、コミットを行うのにかかる時間または特定の時間にコミットするためのスケジューリングにかかる時間を推測することで簡単に処理されます。本当の問題はツリーsha1で、これはから取得できますgit ls-tree $(git write-tree) | git mktree
。基本的に、すべてのファイルとそのsha1チェックサムのリストであるls-treeからのメッセージに対して、sha1チェックサムを実行しています。
したがって、コミットsha1チェックサムは、ツリーsha1チェックサムに依存します。これは、ファイルsha1チェックサムに直接依存します。これは、円を完成させ、コミットsha1に依存します。したがって、あなたは私自身が利用できる技術に循環的な問題を抱えています。
と 安全性の低いチェックサムは、ブルートフォースを通じてファイル自体にファイルのチェックサムを書くことができることが示されています。ただし、sha1でそのタスクを実行した作業については知りません。これは不可能ではありませんが、現在の理解では不可能に近いものです(しかし、数年後にはそれは簡単なことだと知っている人はいます)。ただし、ファイルに(ブロブ)チェックサムの(ツリー)チェックサムの(コミット)チェックサムを書き込む必要があるため、これはブルートフォースにさらに困難です。