制作git自动提交

时间:2009-01-07 12:34:18

标签: git

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

有没有办法可以让git'commit'on'在每次更新文件时自动发生 - 所以每次更改文件都会有新的提交?

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

19 个答案:

答案 0 :(得分:115)

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

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

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

答案 1 :(得分:46)

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

的/etc/rc.local:


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

/家庭/&lt;用户名&GT; / 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 。 / p>

答案 2 :(得分:25)

以前为这项工作推荐 inotifywait 的答案,当我自己遇到这个问题时,我正朝着正确的方向倾斜,所以我写了一个小脚本。首先,这只能递归地观察整个文件夹(与Lester Buck的例子相反),但后来我也想在其他地方看一个文件,所以我扩展了它。

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

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

答案 3 :(得分:16)

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

答案 4 :(得分:11)

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

程序:cmd.exe

参数:/ C 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 *.*"),但我认为我没有正常工作。

我还制作了一个包含以下内容的提交后挂钩:

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

(如果有任何冲突,那么它将中止拉动并中止推动,但没有任何明确的方式来判断发生了什么 - 最终我们因为这个缺陷而抛弃了整个想法。)< / p>

该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

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

答案 5 :(得分:8)

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

使用当前日期和时间自动修复。

答案 6 :(得分:7)

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

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

答案 7 :(得分:7)

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

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

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

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

答案 8 :(得分: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"

答案 9 :(得分:3)

我喜欢的两个解决方案是etckeeper - 除/etc之外的can be adapted to a custom directory

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

gitwatch - 特别是how to use it with supervisord的说明。

答案 10 :(得分:2)

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

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

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

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

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

答案 11 :(得分:1)

我很确定您需要将其挂钩到您的用户正在使用的任何编辑器中。您可以编写一些内容来轮询更改,但根据使用模式,轮询频率可能需要非常高,以确保它获取单个更改而不是多次更改。

答案 12 :(得分:1)

听起来你正在寻找类似于etckeeper的东西,它被设计为自动检查你对/ etc / *的所有更改为git(或你想要的任何VCS),但我认为没有理由不能用于/ etc。

以外的文件

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

答案 13 :(得分:1)

当用户更改文件时,此脚本不会运行,但它可以作为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

答案 14 :(得分:1)

对于Windows

根据此article about autocommit,您应创建包含以下内容的 <h2> Order Summary</h2> <table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">Item Title</th> <th scope="col">Price</th> <th scope="col">Quantity</th> <th scope="col">Size</th> <th scope="col">Total Item Price</th> </tr> </thead> <tbody> {% for order_item in object.items.all %} <tr> <th scope="row">{{ forloop.counter }}</th> <td>{{ order_item.item.title }}</td> <td>{{ order_item.item.price }}</td> <td> <a href="{% url 'core:remove-single-item-from-cart' order_item.item.slug %}"><i class="fas fa-minus mr-2"></a></i> {{ order_item.quantity }} <a href="{% url 'core:add-to-cart' order_item.item.slug %}"><i class="fas fa-plus ml-2"></a></i> </td> <td> {% if order_item.variation.all %} {% for variation in order_item.variation.all %} {{ variation.title|capfirst }} {% endfor %} {% endif %} </td> 文件:

.bat

,然后使用git add -u git commit -m "your commit message" git push origin master 执行。如果您不知道如何逐步进行操作,请参阅该文章。

答案 15 :(得分:0)

我有同样的问题,在mac launchd上为您提供了一个很好的解决方案。 它会查看文件或目录,如果有更改,您可以运行应用程序或其他任何内容......

答案 16 :(得分:0)

我制作了这个小巧的Shell脚本来监视文件状态并在构建成功时触发git commit之类的命令。

可以免费下载并试用。

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

答案 17 :(得分:0)

这不能满足问题的“理想”部分,但这是我所看到的最接近我想要的答案的问题,因此我认为它可以在这里进行。我的第一个stackoverflow帖子虽然如此,所以如果我误会了,深表歉意。

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

答案 18 :(得分:-3)

如果您不想弄乱代码和Linux命令,那么我建议您使用Dropbox进行编码。我发现Dropbox非常适合编码。我只是在我的PC上安装了dropbox并创建了一个虚拟主机。虚拟主机指向我的保管箱文件夹。每当我在任何文件上进行更改并按CTRL + S(即保存)时,它都会创建文件的新版本。我只是喜欢这项技术,这是使用保管箱进行编码的好处。

  • 节省时间:-不再需要队友推拉。如果您一次又一次地烦恼推和拉代码,则可以节省时间。
  • 如果与一组开发人员一起工作,很棒,如果您在每台开发人员PC上都安装了dropbox,然后在同一文件夹上工作,那么如果发生冲突,它将自动创建一个冲突文件。
  • 如果您意外删除了任何文件,则可以从云端垃圾桶中恢复它
  • 每次保存时进行版本控制。

最后我不是Dropbox的推动者。