让 Git 自动承诺

我想使用 git 来记录对文件的所有更改。

有没有一种方法,我可以打开 git 的’提交’自动发生每次文件更新-所以有一个新的提交,每次更改文件?

理想情况下,我希望我的用户甚至不知道 git 是在幕后运行的。然后,用户可以潜在地“撤消”对文件的更改——这可以通过从 git 中提取以前的版本来实现。

104134 次浏览

我很确定您需要将它连接到您的用户正在使用的任何编辑器中。您可以编写一些东西来轮询更改,但是根据使用模式的不同,轮询频率可能需要非常高,以确保它接收单个更改,而不是多个更改。

在 Linux 上,您可以使用 等等在每次文件内容更改时自动执行命令。

编辑: 以下命令在保存 file.txt 后立即提交它:

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

如果您知道文件的名称,并且只想监视一个(或几个文件) ,那么您可以每隔几分钟调用“ git commit”来实现这一点。如果文件没有更改,git 只会发出抱怨,您必须忽略这个错误,但除此之外,不会出现任何损坏。

除此之外,您还需要将这些文件标记为“自动提交”,以便也能够手动提交。通过这种方式,用户可以看到自动更改和更大的“逻辑”更改,这些更改伴随着提交注释来解释自上次手动提交以来发生的更改。

例如,使用“ AUTOCOMMIT”作为提交消息。稍后,您可以使用 git log 编写一个工具来清除这些提交(以找出要终止的修订) ,或者您可以尝试使用蛮力冲突解决策略在“手动提交”中创建一个分支 AUTOCOMMIT。

另一种选择是使用 git 底层命令来构建您自己的专用存储库。

最后,您可以将文件复制到一个新名称(“ $filename.ac”) ,同时执行自动提交以区分手动版本和自动版本。

早期的 等等答案很棒,但它并不是一个完整的解决方案。如前所述,它是在文件中一次性更改的一次性提交。它不适用于编辑文件创建具有原始名称的新 inode 的常见情况。Intifywait-m显然是按 inode 跟踪文件,而不是按名称跟踪文件。而且,在文件更改后,不会在没有 Git add去死吧的情况下对 去死吧进行暂存。做一些调整,下面是我在 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

这可以推广为等待文件和/或目录列表,以及相应的 等等进程,并在文件更改时重新启动每个 等等

我也有同样的问题,在 mac launchd 上有一个很好的解决方案。 它将监视一个文件或目录,如果有变化,你可以运行一个应用程序或任何其他..。

Git-wip 对我来说是一个很好的解决方案。 “ WIP”代表“正在进行中的工作”。每次运行‘ git wip’时,更改都会提交到一个单独的分支。它可以在命令行上运行,但是 vim 和 emacs 有一些扩展,可以在每次写入文件时自动运行 git-wip。

我编写了一个程序 GitPrime,为您的本地 Git 存储库提供自动保存。现在很容易滚回来之前,你打破了它!Bitbucket 仓库.

这应该适用于任何支持 bash shell 的平台,包括 Windows + Cygwin。

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

带有当前日期和时间的自动推送。

通知听起来确实是这项工作的正确工具。

有一个称为 Incron的工具,它可能正是你所寻找的。您可以在 crontab 之类的东西中指定文件或文件夹(以及事件类型,如“ change”、“ create”、“ unlink”) ,以及在发生此类事件时运行的命令。

与 inotifywait (类似于穷人的 cron sleep 10;do stuff)不同,这种方法可以捕获每个事件,而不仅仅是第一个事件。

我自己还没有使用过它,但是从文档来看,设置它看起来并不太复杂。

以前的答案推荐 等等这个工作时,我有这个问题时,我在正确的方向,所以我写了一个小脚本。首先,它只能递归地观察整个文件夹(与 Lester Buck 的示例相反) ,但是我也想在其他地方观察一个文件,所以我扩展了它。

结果是一个 剧本,当前称为 gitwatch,因为这就是它所做的: 它监视一个文件或文件夹的更改(使用 inotifywait) ,并将它们提交到一个 git 存储库。

你可以在 github: https://github.com/nevik/gitwatch上找到脚本、更多信息和说明

我想在窗口中做这件事,发现最好的方法是使用 目录监视器检查变化,然后当它检测到变化时,让它运行:

程序: cmd.exe

Params:/C: 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 *.*") ,但我认为这个命令不能正常工作。

我还创建了一个 post-commit 钩子,其中包含:

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

(如果存在任何冲突,那么它就会中止拉动,中止推动,但没有任何清晰的方法来判断这种情况是否已经发生——最终,我们放弃了整个想法,就因为这个缺陷。)

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

唯一的问题是它需要由 root 用户而不是 apache 用户运行,所以我还必须在 /etc/sudoers.d/中创建一个文件,其中包含:

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

对我来说,我觉得这个方法非常有效。目录监视器可以配置为在启动时运行并最小化启动,它可以监视多个不同的文件夹

这听起来像是你在寻找类似于 等等的东西,它被设计成自动将所有对/etc/* 的更改签入 git (或者任何你想要的 VCS) ,但是我看不出有什么理由它不能用于除了/etc 中的文件以外的其他文件。

如果您只想处理一个文件,那么这可能并不完美,但是如果您想跟踪给定目录中的所有内容,那么我认为值得进行检查。

当用户更改文件时,这个脚本不会运行,但是它可以作为 cron 作业运行(通过将其放到/etc/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

如果有人试图从 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"

我喜欢的两种解决方案是 等等—— 可以适应自定义目录而不是 /etc:

mkdir /foo
etckeeper -d /foo init`
etckeeper -d /foo commit 'message'

还有 Gitwatch特别是 如何使用它与 supervisord的说明。

我编写了这个小小的 shell 脚本,用于监视文件状态并触发命令,比如在构建成功时提交 git。

欢迎下载并试用。

Https://github.com/nzvincent/nzvincent-github/blob/master/inotify-tools/inotify.sh

这不能满足问题的“理想”部分,但这是我看到的最接近我想要的答案的问题,所以我认为它可以放在这里。我的第一个堆栈溢出后,虽然,如果我错了,所以道歉。

下面的脚本确保对保存的更改进行自动提交,但是 是的提示用户提交输入。(我意识到我的情况与 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

适用于视窗

根据这个 关于自动提交的文章,您应该创建包含以下内容的 .bat文件:

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

如果你不知道如何一步一步的执行,请参考这篇文章。

有几种选择:

  • Git 文件(autocommittee. sh)

    • `git add .
      git commit -am "auto commit"
      git push`
      
  • 批处理文件(* . bat)

    • %windir%\system32\CMD.exe /k git-bash.exe c:/yourapp/autocommit.sh
  • 任务计划程序

    • 创造任务

对我来说,它的工作,希望它能帮助一些

inotifywait的一个更现代的方法是使用 进来。你可以做一些简单的事情,比如:

find . | entr git commit -avm "msg"

它将自动提交您对已知 git 的文件所做的任何更改。