2009-01-07 26 views
129

Tôi muốn sử dụng git để ghi lại tất cả các thay đổi đối với một tệp.Thực hiện cam kết tự động git

Có cách nào tôi có thể biến git 'cam kết' tự động xảy ra mỗi khi tệp được cập nhật - vì vậy có một cam kết mới cho mỗi thay đổi đối với tệp không?

Lý tưởng nhất là tôi muốn người dùng của mình thậm chí không biết rằng git đang chạy đằng sau hậu trường. Sau đó, người dùng có thể có khả năng "hoàn tác" các thay đổi đối với tệp - và điều này có thể đạt được bằng cách kéo phiên bản trước đó ra khỏi git.

+6

Sẽ dễ dàng hơn khi sử dụng hệ thống tệp phiên bản: http://en.wikipedia.org/wiki/Versioning_file_system –

+1

SparkleShare khá ấn tượng về điều đó. – theode

Trả lời

102

Trên Linux, bạn có thể sử dụng inotifywait để tự động thực thi lệnh mỗi khi nội dung của tệp bị thay đổi.

Chỉnh sửa: lệnh sau cam kết file.txt ngay sau khi nó được lưu:

inotifywait -q -m -e CLOSE_WRITE --format="git commit -m 'autocommit on change' %w" file.txt | sh 
+0

Làm cách nào để bạn thực hiện việc này cho toàn bộ thư mục (không chỉ một tệp?) –

+1

Sử dụng cờ '-r' để' inotifywait', nhưng lưu ý rằng hạt nhân có giới hạn về số lượng đồng hồ inotifywait mà nó có thể đặt lên. 'người đàn ông inotifywait' sẽ cho bạn biết thêm. – JesperE

+9

có tùy chọn nào trong cửa sổ không? –

1

Tôi khá chắc chắn rằng bạn cần phải móc vào bất kỳ trình chỉnh sửa nào mà người dùng của bạn đang sử dụng. Bạn có thể viết một cái gì đó để thăm dò ý kiến ​​cho các thay đổi, nhưng tùy thuộc vào các mẫu sử dụng, tần suất bỏ phiếu có thể cần phải cực kỳ cao để đảm bảo rằng nó đã chọn từng thay đổi thay vì nhiều thay đổi.

+0

Ngoài ra, bỏ phiếu cho các thay đổi sẽ tạo điều kiện chủng tộc. – Bombe

+1

Không phải với các trình chỉnh sửa như emacs và yi, các tệp này ghi tệp "giao dịch" để cố gắng đảm bảo rằng dữ liệu sẽ không bị mất sau khi xảy ra sự cố. –

2

Nếu bạn biết tên của tập tin và bạn muốn theo dõi chỉ có một (hoặc một vài tập tin), bạn có thể chỉ cần gọi "git commit" vài phút một lần để đạt được điều này. Nếu tập tin không thay đổi, git sẽ chỉ phàn nàn và bạn sẽ phải bỏ qua lỗi này nhưng khác hơn thế, sẽ không có tham nhũng.

Ngoài ra, bạn sẽ muốn đánh dấu các tệp này là "cam kết tự động" để có thể cam kết thủ công. Bằng cách này, người dùng có thể thấy các thay đổi tự động và các thay đổi "hợp lý" lớn hơn đi kèm với các nhận xét cam kết để giải thích rằng đã thay đổi kể từ lần cam kết thủ công cuối cùng.

Ví dụ: sử dụng "AUTOCOMMIT" làm thông báo cam kết. Sau đó, bạn có thể viết một công cụ để loại bỏ các commit này bằng cách sử dụng git log (để tìm ra các bản sửa đổi để giết) hoặc bạn có thể thử tạo một nhánh AUTOCOMMIT bằng cách sử dụng xung đột bạo lực để giải quyết chiến lược để búa trong "cam kết thủ công".

Một tùy chọn khác là sử dụng lệnh cấp thấp git để tạo kho lưu trữ chuyên biệt của riêng bạn.

Cuối cùng, bạn có thể sao chép tệp sang tên mới ("$ filename.ac") trong khi thực hiện cam kết tự động để phân biệt giữa các phiên bản thủ công và tự động.

42

Câu trả lời trước đây inotifywait là tuyệt vời, nhưng nó không phải là một giải pháp hoàn chỉnh. Như được viết, đó là một hình ảnh cam kết thay đổi một lần trong một tệp. Nó không hoạt động đối với trường hợp thông thường khi chỉnh sửa một tệp tạo ra một inode mới với tên gốc. inotifywait -m rõ ràng là sau tệp theo inode, không theo tên. Ngoài ra, sau khi tệp đã thay đổi, nó không được dàn dựng cho git commit mà không cần git thêm hoặc git commit -a. Thực hiện một số điều chỉnh, dưới đây là những gì tôi đang sử dụng trên Debian để theo dõi tất cả các thay đổi đối với tệp lịch của tôi:

/etc/rc.địa phương:


su -c /home/<username>/bin/gitwait -l <username> 

/home/< tên >/bin/gitwait:


#!/bin/bash 
# 
# gitwait - watch file and git commit all changes as they happen 
# 

while true; do 

    inotifywait -qq -e CLOSE_WRITE ~/.calendar/calendar 

    cd ~/.calendar; git commit -a -m 'autocommit on change' 

done 

này có thể được khái quát hóa để chờ đợi vào một danh sách các tập tin và/hoặc thư mục, và tương ứng inotifywait quá trình và khởi động lại mỗi inotifywait dưới dạng tệp được thay đổi.

+6

Lester bạn có thể mở rộng cách tổng quát hóa này vào một thư mục? – Diego

1

tôi đã gặp vấn đề tương tự và trên mac launchd cung cấp cho bạn giải pháp tuyệt vời. nó sẽ xem tệp hoặc thư mục và nếu có thay đổi, bạn có thể chạy ứng dụng hoặc bất kỳ thứ gì khác ...

+0

Xem "Giám sát thư mục" tại đây: http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html – Kris

14

git-wip là giải pháp tuyệt vời phù hợp với tôi. "WIP" là viết tắt của "work in progress". Mỗi lần bạn chạy 'git wip', các thay đổi được cam kết với một nhánh riêng biệt. Nó có thể được chạy trên dòng lệnh, nhưng có các phần mở rộng cho vim và emacs để tự động chạy git-wip mỗi khi một tập tin được ghi.

5

Tôi đã viết một chương trình, GitPrime, để cung cấp tự động lưu trữ cho kho lưu trữ Git cục bộ của bạn. Bây giờ dễ dàng quay trở lại trước khi bạn busted nó! Bitbucket repository.

Điều này sẽ hoạt động trên bất kỳ nền tảng nào hỗ trợ vỏ bash bao gồm Windows + Cygwin.

+0

+1 Tôi đang sử dụng tính năng này trên cửa sổ (CygWin) để autosave thay đổi tôi thực hiện cho một kho git-tf cứ 10 phút một lần bằng cách sử dụng một nhiệm vụ theo lịch trình – Darbio

7
#!/bin/bash 
git commit -a -m "autoupdate `date +%F-%T`" 
git push 

autopushing với ngày giờ hiện tại.

7

Thực hiện âm thanh thực sự giống như công cụ phù hợp cho công việc.

Có một công cụ gọi là incron có thể chính xác những gì bạn đang tìm kiếm. Bạn có thể chỉ định tệp hoặc thư mục (và các loại sự kiện, như "thay đổi", "tạo", "bỏ liên kết") trong một cái gì đó như crontab và lệnh để chạy khi sự kiện như vậy xảy ra.

Ngược lại với inotifywait (tương tự như cron của người nghèo sleep 10;do stuff), điều này sẽ bắt mọi sự kiện, không chỉ là sự kiện đầu tiên.

Tôi chưa tự mình sử dụng, nhưng từ tài liệu không quá phức tạp để thiết lập.

21

Các câu trả lời trước đề xuất inotifywait cho công việc này đã giúp tôi đi đúng hướng khi tôi gặp vấn đề này, vì vậy tôi đã viết một tập lệnh nhỏ. Đầu tiên điều này chỉ có thể xem toàn bộ các thư mục đệ quy (đối diện với ví dụ của Lester Buck), nhưng sau đó tôi cũng muốn xem một tệp ở một nơi khác, vì vậy tôi mở rộng nó.

Kết quả là tập lệnh hiện được gọi là gitwatch, như vậy: nó xem tệp hoặc thư mục để thay đổi (sử dụng inotifywait) và cam kết chúng vào kho lưu trữ git.

Bạn có thể tìm thấy kịch bản, thêm thông tin và hướng dẫn trên trên github: https://github.com/nevik/gitwatch

+3

kịch bản nhỏ hữu ích ở đó. Tôi sẽ ghi lại nó. – iwein

+0

thú vị có thể hữu ích cho các trang web Magento. Tôi đang thử nghiệm nó nhưng dường như không thể làm cho nó tự động đẩy cũng như – NoSixties

10

tôi muốn làm điều này trong các cửa sổ, và thấy cách tốt nhất là sử dụng Directory Monitor để kiểm tra những thay đổi sau đó khi nó phát hiện một sự thay đổi có nó chạy:

Chương trình: cmd.exe

Params: /CC:\pathToBatchFile.bat

Đó batch file chứa:

c: 
cd c:\gitRepoDirectory\ 
(if exist "%PROGRAMFILES(X86)%" (
"%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git commit -am AutoCommitMessage" 
) else (
"%PROGRAMFILES%\git\bin\sh.exe" --login -i -c "git commit -am AutoCommitMessage" 
)) 

Tôi cũng đã cố gắng có lệnh khác trong đó để thêm các tập tin ("%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*"), nhưng tôi không nghĩ rằng tôi đã làm việc đó đúng cách.

tôi cũng thực hiện một cam kết bài móc chứa:

#!/bin/sh 
git.exe pull -v --progress "origin" 
git.exe push --progress "origin" master:master 
curl.exe -s https://webserverdomain.com/updateFromGitHook.x?r=repoName 

(Nếu có bất kỳ xung đột sau đó nó sẽ hủy bỏ việc kéo và hủy bỏ việc đẩy mạnh, nhưng không có cách nào rõ ràng để nói rằng có đã xảy ra - cuối cùng, chúng tôi đã từ bỏ toàn bộ ý tưởng vì một lỗ hổng này.)

Lệnh curl đó nói với máy chủ của tôi rằng nó cần thực hiện việc kéo mã. Tất cả những gì là cần thiết để xử lý nó trong php là:

<? 
$r = $_GET['r']; 
if (!empty($c)) { 
    //use system instead of exec if you want the output to go back to the git client 
    exec("cd /path/to/repo/parent/$r; sudo git reset --hard HEAD; sudo git pull;"); 
    echo "\n\nServer: Updated\n\n"; 
} else { 
    echo "\n\nServer: UPDATE FAILED\n\n"; 
} 
?> 

Vấn đề duy nhất với điều đó là nó cần thiết để được điều hành bởi người dùng root thay vì người dùng apache, vì vậy tôi cũng đã phải thực hiện một tập tin trong /etc/sudoers.d/ chứa :

www-data ALL = NOPASSWD: /usr/bin/git 

Đối với tôi, tôi nghĩ rằng nó hoạt động khá chắc chắn. Directory Monitor có thể được cấu hình để chạy khi khởi động và bắt đầu thu nhỏ, và nó có thể xem nhiều thư mục khác nhau

+0

+1 Điều này cũng làm việc tuyệt vời với mercurial – 79E09796

1

Có vẻ như bạn đang tìm kiếm thứ gì đó tương tự như etckeeper, được thiết kế để tự động kiểm tra tất cả các thay đổi của bạn thành/etc/* vào git (hoặc bất kỳ VCS bạn muốn), nhưng tôi thấy không có lý do nó không thể được sử dụng với các tập tin khác với những người trong/etc.

Nếu bạn chỉ muốn đối phó với một tệp duy nhất, có thể điều đó sẽ không hoàn hảo, nhưng nếu bạn muốn theo dõi mọi thứ trong một thư mục nhất định, tôi nghĩ rằng nó đáng để kiểm tra.

1

Tập lệnh này không chạy khi người dùng thay đổi tệp nhưng có thể chạy dưới dạng công việc cron (bằng cách thả nó vào thư mục /etc/cron.*), cũng là giải pháp hợp lý.

Tập lệnh này sẽ lặp qua thư mục/srv/www của bạn (thay đổi nó ở bất kỳ nơi nào tất cả các trang web của bạn được lưu trữ), thêm, cam kết và đẩy tất cả các tệp và ghi lại mọi thứ vào /var/log/gitlog.txt

now=$(date +"%m.%d.%Y_%T") 
logfile='/var/log/gitlog.txt' 

for dir in /srv/www/*/ 
do 
echo -e '\n' >> $logfile 
echo "autocommit $dir $now" >> $logfile 
echo "--------------------------" >> $logfile 

cd $dir 
git add . >> $logfile 
git commit -am "autocommit $now" >> $logfile 
git push origin master >> $logfile 
done 
4

Trong trường hợp ai đó cố gắng làm điều này từ Powershell tôi đã thành công bằng cách sử dụng sau đây:

& "C:\Program Files (x86)\Git\bin\sh.exe" -c "cd D:\PATH\TO\REPO && git add --all && git commit -m 'Automatic Commit Message Goes Here' && git push origin master" 
+5

Và làm thế nào điều này được kích hoạt tự động? – jerik

+1

tác vụ đã lên lịch? – ozzy432836

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