2013-05-30 32 views
16

Một trong những điều tôi lưu giữ trong số open novel in GitHublist of words Tôi muốn đặt tự động dòng đầu tiên, là số từ trong từ điển. Tùy chọn đầu tiên của tôi là viết một móc trước khi commit, đọc tập tin, đếm các từ, viết lại dòng đầu tiên và viết lại nó. Dưới đây là đoạn codeBạn có thể thay đổi nội dung tập tin trong git commit không?

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); 
    } 
    } 
}; 

Tuy nhiên, kể từ khi tập tin đã được dàn dựng, tôi nhận được lỗi này

error: Your local changes to the following files would be overwritten by checkout: text/words.dic Please, commit your changes or stash them before you can switch branches. Aborting

nó có thể là tốt hơn để làm điều đó như một cam kết nối và có nó thay đổi cho cam kết tiếp theo? Hoặc làm một cái gì đó hoàn toàn khác nhau hoàn toàn? Câu hỏi chung là: nếu bạn muốn xử lý và thay đổi nội dung của một tập tin trong khi cam kết, cách thích hợp để làm điều đó là gì?

Trả lời

15

Cam kết thực sự bị kẹt bởi git commit là bất kỳ nội dung gì trong chỉ mục khi móc trước khi kết thúc. Điều này có nghĩa là bạn có thể thay đổi tệp trong móc trước khi cam kết, miễn là bạn git add cũng vậy.

Dưới đây là ví dụ của tôi trước cam kết nối, sửa đổi từ .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 

và sau đó:

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

Nhưng lưu ý một lỗ hổng nhỏ (sẽ không áp dụng cho trường hợp của bạn):

$ 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 

Về cơ bản, vì bản cập nhật móc trước cam kết và git add s, tệp tiếp tục tăng dần mặc dù tôi không thực sự thực hiện cam kết, ở đây.

+0

Vì vậy, về cơ bản nó là một đứa trẻ khác hack, phải không? Thực hiện theo cách của tôi, tập tin được thay đổi, nhưng không được cam kết cho đến khi tập tin tiếp theo – jjmerelo

+1

Có.Tôi không chắc tôi sẽ thực sự hạnh phúc với một trong hai cách tiếp cận; Tôi muốn có một cái gì đó như một Makefile để cập nhật những thứ cần thiết, và một cái gì đó nhiều hơn một chút hướng dẫn sử dụng. Nhưng nó sẽ hoạt động. – torek

+0

Có thể thực hiện sau cam kết sẽ chính xác hơn? – jjmerelo

9

Hóa ra bạn có thể chạy "móc" - họ đang thực sự xử lý bởi mecanism khác - khi dàn dựng file (tại git add thời gian):

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

(di chuyển xuống một chút để các " smudge/sạch" sơ đồ)

đây là những gì tôi đã hiểu:

  1. chỉnh sửa các .gitattributes, và tạo các quy tắc cho các tập tin mà nên kích hoạt một bản cập nhật từ điển:

    novel.txt updateDict

  2. Sau đó, hãy nói với Git những gì các "updateDict" bộ lọc hiện trên smudge (git checkout) và sạch sẽ (git add):

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

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

Các vấn đề liên quan