保留对文本文件的所有修改的历史记录

Bow*_*ark 8 linux version-control files

我有一个纯文本文件(不包含源代码)。我经常修改它(添加行、编辑现有行或任何其他可能的修改)。对于任何修改,我想自动记录:

  • 已修改的内容(差异信息);
  • 修改的日期和时间。

(理想情况下,我还希望能够在特定时间获取我的文件的版本,但这是一个加分项,而不是必需的)。

这对于 Git 来说肯定是可能的,但是它太强大和复杂了。我不想每次都处理addcommit消息push,等等。我只想用vi(或等效的)编辑文件,保存它,并自动记录上述修改(其差异和时间)。

是否有工具可以在 Linux 中完成此操作?


更新:感谢您提出的所有建议和已介绍的几种解决方案。我没有反对git,但我明确希望避免它(出于多种原因,最后但并非最不重要的事实是我不够了解)。最接近上述要求(没有git,没有提交消息,很少或没有开销)的工具是 RCS。它是基于文件的,这正是我正在寻找的。这甚至可以避免使用脚本,提供文件的先前版本并避免对vi.


问题的要求是准确的;提出了许多意见,但问题本身并不是基于意见的。然后,显然,可以通过工具或脚本实现相同的目标,但这也适用于许多其他情况。

hol*_*ill 15

git个机会

我不明白为什么使用强大的工具是一个问题。只需编写一个git定期运行的简单 bash 脚本(通过cronsystemd定时器);自动生成提交消息等。

正如其他人的评论强调这是-当然-可以创建本地存储库(见这里那里有详细介绍)。

如果您更喜欢托管自己的远程存储库,则需要设置一个“裸存储库”。无论git initgit clone接受--bare的说法。

博格备份

我也可以推荐borg 备份。它为您提供:

  • 时间戳
  • borg diff (快照之间的比较)
  • 修剪(删除旧的快照 - 假设您想要当前月份每天的快照,否则每月只需要一个)
  • 加密(可选)
  • 压缩(可选)
  • 以及更多...

很酷的一点是它非常灵活——它很容易设置,但如果你愿意的话,它会给你很多选择。

我曾经写过一个快速入门指南,可能会有帮助。

  • @BowPark 并不是说​​ git 根本不需要远程存储库。`git init` 为您提供了一个功能齐全、完全本地的存储库。 (8认同)
  • 请注意,使用 git 时不需要存在远程存储库。 (3认同)

Nor*_*tfi 9

有几种方法可以做到这一点:

  • vim
  • emacs
  • git
  • inotify-tools
  • git-annex (多合一解决方案)

这里有详细介绍:

使用 Vim:

然后我建议使用撤消历史记录,这不仅(顾名思义)与undo在 Vim 编辑器中执行操作的行为有关,还与您保存的操作有关。更多在这里。

将以下内容添加到您的.vimrc:

let vimDir = '$HOME/.vim'
let &runtimepath.=','.vimDir

" Keep undo history across sessions by storing it in a file
if has('persistent_undo')
    let myUndoDir = expand(vimDir . '/undodir')
" Create dirs
    call system('mkdir ' . vimDir)
    call system('mkdir ' . myUndoDir)
    let &undodir = myUndoDir
    set undofile
endif
Run Code Online (Sandbox Code Playgroud)

将使它所以每次修改/撤销将永久目录下保存 undodir在本地vimDir,这是在默认情况下要么.vim在你的主目录,或在输出提及其他的:version或者--version在命令行上。

为了更好地控制您的撤消历史,我建议您还使用Undotree来补充体验。

使用 Emacs:

有一个名为Undotree的类似命名包,它做类似的事情。在此处了解有关撤消历史记录的更多信息。

使用 Git:

我建议使用git-autocommit,这是一个小型 bash 脚本,使用 git 因为它只是依赖项,它会监视当前 git 目录(启动它的位置)以查找任何新文件/或修改过的文件,并提交它们。

鉴于Git它保留对文件的所有更改的性质,虽然它不适合生产/严肃项目,但如果您不介意没有提交消息/通用提交消息(您可以以后总是编辑/添加)。

导航到想要的 git 目录(首先git init在特定目录上创建,官方手册上有更多信息)后启动它,如下所示:

screen -dmS namehere git-autocommit -i 1 -V
Run Code Online (Sandbox Code Playgroud)

如果您正在使用screen,对于tmux

tmux new -n namehere git-autocommit -i 1 -V
Run Code Online (Sandbox Code Playgroud)

除此以外:

git-autocommit -i 1 -V
Run Code Online (Sandbox Code Playgroud)

如果你不想背景它就足够了。

使用 inotify 工具:

我建议使用inotify-tools或更具体地说inotifywatch,它可以检测并(顾名思义)观察文件/目录的更改,然后您可以对其进行操作(例如将其保存在其他地方等)。

这里使用的标志inotifywatch

inotifywait -r -m -q -e close_write --format %w%f yourdirectorypathhere
Run Code Online (Sandbox Code Playgroud)

这里是一个Bash使用上述内容的示例脚本:

#!/bin/bash
inotifywait -r -m -q -e close_write --format %w%f directorytowatch | while IFS= read -r file; do

    process $file
done
Run Code Online (Sandbox Code Playgroud)

哪里process可以是你想要的任何东西,比如tar你想对文件修改进行备份,或者rclone你想把它上传到某个地方......

使用 git 附件:

我建议git-annex这不仅包括Git但许多其他外部工具,如inotify-toolsbashtarrcloneborg等。

更多信息在这里

如果你想稍后阅读维基/论坛,你也可以在本地 git clone ,以供离线阅读:

git clone git://git-annex.branchable.com
Run Code Online (Sandbox Code Playgroud)

用于网站、论坛(全部采用 Markdown,因此下载速度非常快...)和代码库(在 Haskell 中!)等


Ste*_*itt 7

另一种覆盖给定文件系统中所有文件的方法是使用日志结构的文件系统,例如NILFS

此类文件系统会附加更改,但不会替换数据。这实际上等效于连续快照(或者更确切地说,检查点),并允许您在过去的各个点重新访问文件系统。较旧的检查点在达到一定年龄后很容易被垃圾收集,但检查点可以变成永久快照,并且可以自动化,例如在上个月每小时保留一个快照,然后每天保留一个六个月,然后每周一次等等。

NILFS 在 Linux 上得到了很好的支持,并且在用于/home.


jrw*_*982 6

您可以尝试@steeldriver 提到的古老的 RCS(包“rcs”),这是一个非现代版本控制系统,它在每个文件的基础上工作,几乎没有开销或复杂性。有多种使用方法,但只有一种可能:

  • 创建一个 RCS 子目录,其中将存储版本历史记录。
  • 编辑您的文件
  • 签入您的更改: ci -l -m -t- myfile
  • 重复

如果您将此文本存储在文件中:

$RCSfile$
$Revision$
$Date$
Run Code Online (Sandbox Code Playgroud)

然后,一旦您签入(从技术上讲,当您签出时),RCS 将使用有关您的修订及其日期戳的信息填充这些字符串。

RCS/将调用存储在其中的文件myfile,v并将包含每个修订版之间的差异。当然,关于 RCS 还需要了解更多。你可以看一下联机帮助页cicorcsrcsdiff等。

以下是更多信息:

  • 如果您跳过创建RCS/目录,那么存档将出现在与您的文件相同的目录中。
  • 您“签入”一个文件以ci在存档中记录它的一个版本(*,vRCS/ 目录中的文件)。签入具有删除文件的奇怪副作用,使您的数据仅存在于*,v存档中。为避免这种副作用,请使用-l-uci命令一起使用。
  • 您可以“签出”一个文件以co从存档中重新构建它。
  • 您“锁定”一个文件以使其可写并防止其他人写入它,这会造成“合并”情况。在您的情况下,只有一个用户修改文件,“锁定”表示可写,“解锁”表示只读。如果您修改并“解锁”文件(通过强制写入),ci当您尝试检查更改时会抱怨(因此,避免这样做)。
  • 由于您是唯一编辑文件的人,因此您可以选择多种方案:您可以将文件保持为只读(解锁)或可写(锁定)。我对不希望经常更改的文件使用解锁模式,因为这样可以防止我意外修改它们,因为它们是只读的,即使对我来说也是如此。我对我正在积极修改的文件使用锁定模式,但是当我想保留内容的修订历史时。
  • 使用-lwithcico将锁定它,使其可写。如果没有-l它,它将是只读的,co或者它将被完全删除ci。用于ci -u在将文件内容签入存档后将文件保留为只读模式。
  • 使用-m.将阻止ci请求修订消息。
  • 使用-t-将阻止ci请求初始消息(首次创建存档文件时)。
  • 使用-Mwithcico将使文件的时间戳与签入时文件的时间戳保持同步。
  • co -r1.2 -p -q myfile将打印版本1.2myfile到标准输出。如果没有-p选项,并假设myfile被“解锁”(只读),然后co -r1.2 myfile将覆盖myfile一个只读副本修订1.2myfile-q禁用信息性消息。
  • 您可以创建“分支”,并使用1.3.1.1. 我不推荐这样做,因为它很快就会让人困惑。我更喜欢保持线性的修订流程。

因此,如果您希望文件始终可写,则可以使用ci -l -M -m -t- myfile. 您可以使用rcsdiff myfile来查看当前内容myfile和最近签入版本之间的差异。您可以使用rcsdiff -r1.2 -r1.4 myfile查看修订版1.21.4of之间的差异myfile

存档文件只是一个文本文件,其格式记录在man rcsfile. 但是,不要尝试直接编辑存档文件。IMO、基于文本的存档文件、绝对最小的额外负担(只有一个存档文件)和关键字替换是 RCS 的最大优势,并且使其成为仅限本地、单用户、单文件的绝佳工具-一次版本控制。如果我要重新设计 RCS,我会消除这种情况之外的复杂性(例如多用户、分支),我认为更现代的分布式版本控制系统可以更好地处理这些问题。

与任何命令一样,也有一些怪癖;您应该玩弄测试文件,直到您了解自己想要的工作流程。然后,为了获得最佳效果,将您最喜欢的选项嵌入到脚本中,这样您就不必记住-t-诸如 之类的东西。