gitを自動コミットする


155

gitを使用してファイルへのすべての変更を記録したいと思います。

ファイルが更新されるたびにgit 'commit'をオンにして自動的に実行する方法はありますか?したがって、ファイルへの変更ごとに新しいコミットがありますか?

理想的には、gitがバックグラウンドで実行されていることをユーザーに知らせないでください。その後、ユーザーはファイルへの変更を「取り消す」可能性があります。これは、gitから以前のバージョンをプルすることで実現できます。


9
:バージョン管理ファイルシステムを使用する方が簡単だろうen.wikipedia.org/wiki/Versioning_file_system
ウィリアムPursell

1
SparkleShareはそれについてかなり印象的でした。
theode

SparkleShareは素晴らしいオプションのように見えますが、メインgit内の.gitフォルダーをすべて破壊します
insign

github.com/jw0k/gwatchを使用できます。WindowsとLinuxで動作します。
rubix_addict

@rubix_addict回答として投稿しなかったのはなぜですか?
トビアスキエンツラー

回答:


127

Linuxでは、inotifywaitを使用して、ファイルの内容が変更されるたびにコマンドを自動的に実行できます。

編集:次のコマンドは、file.txtが保存されるとすぐにコミットします。

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

2
フォルダー全体(これは1つのファイルだけではない)に対してこれを行うにはどうすればよいですか?
Anderson Green

2
-rフラグをinotifywaitに使用しますが、カーネルには、セットアップできるinotifywaitウォッチの数に制限があることに注意してください。man inotifywaitもっと教えてくれます。
JesperE 2012年

14
ウィンドウにオプションはありますか?
Chandan Pasunoori

50

以前のinotifywaitの回答はすばらしいですが、完全なソリューションではありません。書かれているように、これはファイルの1回の変更に対する1回限りのコミットです。ファイルを編集すると、元の名前で新しいiノードが作成されるという一般的なケースでは機能しません。 inotifywait -mは、ファイルを名前ではなくiノードで追跡します。また、ファイルが変更された後、それはgit addまたはgit commit -aなしでgit commitにステージングされません。いくつかの調整を行い、カレンダーファイルへのすべての変更を追跡するためにDebianで使用しているのは次のとおりです。

/etc/rc.local:


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

/ home / <username> / 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

これは、ファイルやディレクトリのリスト、および対応するinotifywaitプロセスで待機し、ファイルが変更されたときに各inotifywaitを再起動するように一般化できます。


8
レスターは、これをディレクトリに一般化する方法を拡張していただけませんか?
ディエゴ

29

この仕事にinotifywaitを推奨する以前の回答は、私自身がこの問題を抱えていたときに正しい方向に導いてくれたので、小さなスクリプトを書きました。まず、これはフォルダー全体を再帰的に監視することしかできませんでしたが(レスターバックの例とは逆に)、ファイルを別の場所でも監視したかったので、それを拡張しました。

結果は、現在と呼ばれているスクリプトです。gitwatchつまり、スクリプトは、ファイルまたはフォルダーの変更を監視し(inotifywaitを使用)、gitリポジトリにコミットします。

スクリプト、詳細情報、手順については、githubをご覧くださいhttps : //github.com/nevik/gitwatch


4
便利な小さなスクリプトがあります。書き留めておきます。
iwein

興味深いのは、magentoサイトに役立つかもしれません。私はそれをテストしていますが、自動的にプッシュすることもできないようです
NoSixties

16

git-wipは私にとってうまく機能する素晴らしいソリューションです。「WIP」は「作業中」の略です。「git wip」を実行するたびに、変更は別のブランチにコミットされます。コマンドラインで実行できますが、ファイルが書き込まれるたびにgit-wipを自動的に実行するvimおよびemacsの拡張機能があります。


12

私はこれをWindowsで実行したかったのですが、最善の方法はDirectory Monitorを使用して変更を確認し、変更を検出したときに実行することでした。

プログラム:cmd.exe

パラメータ:/CC:\pathToBatchFile.bat

そのバッチファイルには次のものが含まれています。

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"
))

また、ファイルを追加するための別のコマンド("%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*")を試してみましたが、適切に機能していないと思います。

コミット後のフックも作成しました:

#!/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

(競合があった場合、プルを中止し、プッシュを中止しますが、発生したことを明確に示す方法はありませんでした。結局、この1つの欠陥のため、アイデア全体を放棄しました。)

このcurlコマンドは、コードをプルする必要があることをサーバーに伝えました。phpでそれを処理するために必要なのは次のとおりです。

<?
$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";
}
?>

これに関する唯一の問題は、apacheユーザーではなくrootユーザーが実行する必要があるため、次の内容/etc/sudoers.d/を含むファイルを作成する必要があったことです。

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

私にとっては、それはかなりしっかりと機能したと思います。Directory Monitorは、起動時に実行され最小化された状態で起動するように構成でき、いくつかの異なるフォルダーを監視できます


また、Windowsでは、gitをLocalSystemで実行できません。そのため、独自の監視サービスを作成する場合は、実際にGitを実行できるユーザーで実行する必要があります。可能性がありますいくつかの設定/構成が不足していますが、とにかく新しいgit commitアカウントを設定する方が良いでしょう
Whelkaholism


8

Inotifyは本当にその仕事に適したツールのように思えます。

incronと呼ばれるツールがあり、これはまさにあなたが探しているものです。ファイルまたはフォルダー(および「変更」、「作成」、「リンク解除」などのイベントタイプ)をcrontabなどで指定し、そのようなイベントが発生したときに実行するコマンドを指定できます。

inotifywait(貧しい人のcronの類似物)とは対照的にsleep 10;do stuff、これは最初のイベントだけでなく、すべてのイベントをキャッチします。

私はそれを自分で使用したことはありませんが、ドキュメンテーションから、セットアップが複雑すぎないように見えます。


7

ローカルのGitリポジトリに自動保存を提供するプログラムGitPrimeを作成しました。バストする前に簡単にロールバックできるようになりました!Bitbucketリポジトリ

これは、Windows + Cygwinを含むbashシェルをサポートするすべてのプラットフォームで機能します。


+1 Windows(CygWin)でこれを使用して、スケジュールされたタスクを使用して10分ごとにgit-tfリポジトリに加えた変更を自動保存します
Darbio

6

誰かがPowershellからこれをやろうとした場合、私は以下を使用して成功しました:

& "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
そして、これはどのように自動的にトリガーされますか?
jerik、2014年

2
スケジュールされたタスク?
ozzy432836 2016年


2

ファイルの名前がわかっていて、1つ(またはいくつかのファイル)のみを監視する場合は、数分ごとに「git commit」を呼び出すだけでこれを実現できます。ファイルが変更されていない場合、gitは文句を言うだけなので、このエラーを無視する必要がありますが、それ以外は破損はありません。

さらに、手動でコミットできるように、これらのファイルを「自動コミット」としてマークする必要があります。このようにして、ユーザーは自動変更と、最後の手動コミット以降に変更されたことを説明するコミットコメントを伴うより大きな「論理」変更を確認できます。

たとえば、コミットメッセージとして「AUTOCOMMIT」を使用します。後で、git logを使用してこれらのコミットをパージするツール(killするリビジョンを見つけるため)を作成するか、ブルートフォース衝突解決戦略を使用してブランチAUTOCOMMITを作成して、「手動コミット」を実行することができます。

もう1つのオプションは、git低レベルコマンドを使用して独自の専用リポジトリを構築することです。

最後に、自動コミットを実行しながらファイルを新しい名前( "$ filename.ac")にコピーして、手動バージョンと自動バージョンを区別できます。


1

ユーザーが使用しているエディタにフックする必要があると確信しています。変更をポーリングする何かを書くこともできますが、使用パターンによっては、複数の変更ではなく個別の変更を取得することを確実にするために、ポーリング頻度を非常に高くする必要がある場合があります。


また、変更をポーリングすると、競合状態が発生します。
ボンベ、

1
emacsやyiなどのエディタでは、クラッシュ後にデータが失われないように「トランザクション」でファイルを書き込みます。
ロビングリーン

1

/ etc / *へのすべての変更を自動的にgit(または任意のVCS)にチェックインするように設計されているetckeeperに似たものを探しているようですが、ファイルで使用できなかった理由はわかりません/ etcにあるもの以外。

1つのファイルのみを処理したい場合、それは完璧ではないかもしれませんが、特定のディレクトリ内のすべてを追跡したい場合は、チェックする価値があると思います。


1

このスクリプトは、ユーザーがファイルを変更しても実行されませんが、(/ etc / cron。*ディレクトリにドロップすることにより)cronジョブとして実行できますが、これも適切な解決策です。

このスクリプトは/ srv / wwwディレクトリを反復処理し(すべてのサイトが保存されている場所に変更します)、すべてのファイルを追加、コミット、およびプッシュし、すべてを/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

0

私は同じ問題を抱えていましたが、Macのlaunchdは素晴らしい解決策を提供します。それはファイルまたはディレクトリを監視し、変更がある場合は、アプリやその他のものを実行できます...


ここでは、「ディレクトリの監視」を参照してください:developer.apple.com/library/mac/#documentation/MacOSX/...
クリス


0

これは質問の「理想的に」の部分を満たしていませんが、これは私が望んだ答えに最も近い質問だったので、ここに行くことができると考えました。私の最初のスタックオーバーフローの投稿ですが、私が間違っているとすみません。

次のスクリプトは、保存された変更の自動コミットを保証ますが、ユーザーにコミット入力を求めます。(私のシナリオはgit-noobのシナリオとは少し異なることに気づきました)。


# While running, monitors the specified directory, and when a file therein 
# is created or edited and saved, this prompts the user for a commit message.
# The --exclude is to avoid extra prompts for the changes made to 
# version control directories.

# requires inotify-tools

inotifywait --exclude '/\..+' -m  path/to/directory -e modify -e create |
        while read path action file; do
                gnome-terminal -e 'bash -c "cd path/to/directory; 
                                            git add *; 
                                            echo What did you just do??; 
                                            read varname; 
                                            git commit -m \"$varname\""'
        done

0

Windowsの場合

autocommitに関するこの記事によると.bat、コンテンツを含むファイルを作成する必要があります。

git add -u
git commit -m "your commit message"
git push origin master 

と実行しTask Schedulerます。ステップバイステップの方法がわからない場合は、その記事を参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.