使 git 自动提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/420143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:02:58  来源:igfitidea点击:

Making git auto-commit

git

提问by git-noob

I'd like to use git to record all the changes to a file.

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

Is there a way I can turn git 'commit' on to automatically happen every time a file is updated - so there is a new commit for every change to a file?

有没有一种方法可以在每次更新文件时自动打开 git 'commit' - 所以对文件的每次更改都有一个新的提交?

Ideally I'd like my users to not even know that git is running behind the scenes. A user could then potentially "undo" changes to a file - and this could be achieved by pulling a previous version out of git.

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

采纳答案by JesperE

On Linux you could use inotifywaitto automatically execute a command every time a file's content is changed.

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

Edit: the following command commits file.txt as soon as it is saved:

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

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

回答by Lester Buck

The earlier inotifywaitanswer is great, but it isn't quite a complete solution. As written, it is a one shot commit for a one time change in a file. It does not work for the common case where editing a file creates a new inode with the original name. inotifywait -mapparently follows files by inode, not by name. Also, after the file has changed, it is not staged for git commitwithout git addor git commit -a. Making some adjustments, here is what I am using on Debian to track all changes to my calendar file:

较早的inotifywait答案很好,但它不是一个完整的解决方案。正如所写的,它是对文件中的一次更改的一次提交。它不适用于编辑文件创建具有原始名称的新 inode 的常见情况。 inotifywait -m显然是按 inode 来跟踪文件,而不是按名称。此外,在文件更改后,它不会在没有git addgit commit -a 的情况下为git commit暂存。进行一些调整,这是我在 Debian 上使用的用于跟踪对我的日历文件的所有更改的内容:

/etc/rc.local:

/etc/rc.local:


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

/home/<username>/bin/gitwait:

/home/<用户名>/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

This could be generalized to wait on a list of files and/or directories, and the corresponding inotifywaitprocesses, and restart each inotifywaitas a file is changed.

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

回答by Nevik Rehnel

The previous answers recommending inotifywaitfor this job tipped me off in the right direction when I had this problem myself, so I wrote a little script. First this could only watch whole folders recursively (the opposite of Lester Buck's example), but then I also wanted to watch a file somewhere else, so I expanded it.

当我自己遇到这个问题时,之前推荐inotifywait用于这项工作的答案给我指明了正确的方向,所以我写了一个小脚本。首先,这只能递归地查看整个文件夹(与 Lester Buck 的示例相反),但后来我还想查看其他地方的文件,所以我扩展了它。

The result is a scriptcurrently called gitwatch, as that is what it does: it watches a file or folder for changes (using inotifywait), and commits them to a git repository.

结果是当前名为的脚本gitwatch,正如它所做的那样:它监视文件或文件夹的更改(使用 inotifywait),并将它们提交到 git 存储库。

You can find the script, more info and instructions over on github: https://github.com/nevik/gitwatch

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

回答by rafak

git-wipis a great solution that works well for me. "WIP" stands for "work in progress". Every time you run 'git wip', the changes are commited to a separate branch. It can be run on the command line, but there are extensions for vim and emacs to automatically run git-wip each time a file is written.

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

回答by Redzarf

I wanted to do this in windows, and found the best way was to use Directory Monitorto check for changes then when it detected a change have it run:

我想在 Windows 中执行此操作,并发现最好的方法是使用目录监视器来检查更改,然后在检测到更改时运行:

Program: cmd.exe

程序:cmd.exe

Params: /C C:\pathToBatchFile.bat

参数:/CC:\pathToBatchFile.bat

That batch file contained:

该批处理文件包含:

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

I also tried having another command in there to add files ("%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*"), but I don't think I got that working properly.

我还尝试在其中添加另一个命令来添加文件 ( "%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*"),但我认为我无法正常工作。

I also made a post-commit hook containing:

我还制作了一个提交后钩子,其中包含:

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

(If there were any conflicts then it would abort the pull and abort the push, but there wasn't any clear way to tell that had happened - in the end we abandoned the whole idea because of this one flaw.)

(如果有任何冲突,那么它会中止拉动并中止推动,但没有任何明确的方法可以说明已经发生了 - 最后我们因为这个缺陷而放弃了整个想法。)

That curl command told my server that it needed to do a pull on the code. All that was needed to handle it in php was:

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

The only problem with that was it needed to be run by the root user instead of the apache user, so I also had to make a file in /etc/sudoers.d/containing:

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

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

For me, I think that worked pretty solidly. Directory Monitor can be configured to run on startup and start minimized, and it can watch several different folders

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

回答by pixelbrei

Inotify really sounds like the right tool for the job.

Inotify 听起来确实是适合这项工作的工具。

There is a tool called incronwhich could be exactly what you are looking for. You can specify files or folders (and event types, like "change", "create", "unlink") in something like a crontab, and a command to run when such an event occurs.

有一个名为incron的工具,它可能正是您正在寻找的。您可以在 crontab 之类的东西中指定文件或文件夹(和事件类型,如“更改”、“创建”、“取消链接”),以及在发生此类事件时运行的命令。

In contrast to inotifywait (which would be the analog of the poor man's cron sleep 10;do stuff), this will catch every event, not just the first.

与 inotifywait (这将是穷人的 cron 的类比)相反sleep 10;do stuff,这将捕获每个事件,而不仅仅是第一个。

I haven't used it myself, but from the documentation it doesn't look too complex to setup.

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

回答by Brendan

I wrote a program, GitPrime, to provide autosave for your local Git repositories. Now easy to roll back to before you busted it! Bitbucket repository.

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

This should work on any platform that supports a bash shell including Windows+Cygwin.

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

回答by web-rider

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

autopushing with current date and time.

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

回答by mekuls

In case anyone tries to do this from Powershell I had success using the following:

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

回答by vmassuchetto

Two solutions that I like are etckeeper-- which can be adapted to a custom directoryother than /etc:

我喜欢的两个解决方案是etckeeper——可以适用于除以下之外的自定义目录/etc

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

And gitwatch-- specially the instructions of how to use it with supervisord.

gitwatch——特别是关于如何使用它supervisord的说明。