web-dev-qa-db-ja.com

git commit中にファイルの内容を変更できますか?

私が保持しているものの1つ GitHubの小説を開く単語のリスト 最初の行を自動的に設定したいのですが、これは辞書の単語数です。私の最初のオプションは、ファイルを読み取り、単語を数え、最初の行を書き直し、それを再び書き込む事前コミットフックを書き込むことです。これがコードです

PRE_COMMIT {
  my ($git) = @_;
  my $branch =  $git->command(qw/rev-parse --abbrev-ref HEAD/);
  say "Pre-commit hook in $branch";
  if ( $branch =~ /master/ ) {
     my $changed = $git->command(qw/show --name-status/);
     my @changed_files = ($changed =~ /\s\w\s+(\S+)/g);
     if ( $words ~~ @changed_files ) {
       my @words_content = read_file( $words );
       say "I have $#words_content words";
       $words_content[0] = "$#words_content\n";
       write_file( $words, @words_content );
     }
   }
};

ただし、ファイルはすでにステージングされているため、このエラーが発生します

エラー:次のファイルに対するローカルの変更は、チェックアウトによって上書きされます:text/words.dicブランチを切り替える前に、変更をコミットするか、隠してください。中止しています

コミット後のフックとしてそれを行い、次のコミットのために変更した方がいいのではないでしょうか?または、完全に異なる何かをしますか?一般的な質問は次のとおりです。コミット中にファイルのコンテンツを処理および変更する場合、適切な方法は何ですか。

26
jjmerelo

git commitによってスタックされた実際のコミットは、pre-commitフックが完了すると、インデックスにあるものになります。これは、あなたがそれらをgit addしている限り、pre-commitフック内のファイルをcan変更することを意味します。

これが.sampleから変更された私のプリコミットフックの例です。

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# [snipped much of what used to be in it, added this --
#  make sure you take out the exec of git diff-index!]

num=$(cat zorg)
num=$(expr 0$num + 1)
echo $num > zorg
git add zorg
echo "updated zorg to $num"
exit 0

その後:

$ git commit -m dink
updated zorg to 3
[master 76eeefc] dink
 1 file changed, 1 insertion(+), 1 deletion(-)

しかし、小さな欠陥に注意してください(あなたのケースには当てはまりません):

$ git commit
git commit
updated zorg to 4
# On branch master
# Untracked files:
[snip]
nothing added to commit but untracked files present (use "git add" to track)
$ git commit
updated zorg to 5
# Please enter the commit message for your changes. Lines starting
[snip - I quit editor without changing anything]
Aborting commit due to empty commit message.
$ git commit
updated zorg to 6
# Please enter the commit message for your changes. Lines starting

基本的に、pre-commitフックが更新され、git addsになるため、ここでは実際にコミットを実行していなくても、ファイルは増加し続けます。

21
torek

「フック」を実行できることがわかります-それらは実際には別のメカニズムによって処理されます-stagingファイル(git add時):

https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#_keyword_expansion

(「スマッジ/クリーン」ダイアグラムまで少し下にスクロールします)

これが私が理解したことです:

  1. .gitattributesを編集し、辞書の更新をトリガーするファイルのルールを作成します。

    novel.txt updateDict

  2. 次に、「UpdateDict」フィルターがスマッジ(git checkout)とクリーン(git add)に対して何をするかをGitに伝えます。

    $ git config --global filter.updateDict.clean countWords.script

    $ git config --global filter.updateDict.smudge cat

10
LeGEC