使用 Vim:

使用 Vim:

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

  • 修改了什么(差异信息);
  • 修改的日期和时间。

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

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

Linux 下有没有工具可以实现这个功能?


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


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

答案1

git一个机会

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

正如其他人在评论中强调的那样,当然可以创建本地存储库(请参阅这里那里更多细节)。

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

博格备份

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

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

最酷的事情是它非常灵活 - 它很容易设置,但如果您愿意的话,可以给您很多选择。

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

答案2

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

  • 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

将使每个更改/撤消都永久保存在 undodir本地目录下vimDir,默认情况下位于.vim您的主目录中,或者在命令行的输出中:version--version命令行中提到的其他目录中。

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

使用 Emacs:

有一个类似的命名包叫做撤消树,它做类似的事情。有关撤消历史记录的更多信息这里

使用 Git:

我建议使用git 自动提交,这是一个小的 bash 脚本,与 git 因为它是唯一的依赖项,它监视当前 git 目录(启动它的位置)中是否有任何新文件/或修改的文件,并提交它们。

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

git init导航到所需的 git 目录后启动它(首先在特定目录上创建,更多信息请参阅官方手册)像这样:

screen -dmS namehere git-autocommit -i 1 -V

如果您使用screen, 来tmux

tmux new -n namehere git-autocommit -i 1 -V

否则:

git-autocommit -i 1 -V

如果您不想将其设置为背景就足够了。

使用 inotify 工具:

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

这里是要使用的标志inotifywatch

inotifywait -r -m -q -e close_write --format %w%f yourdirectorypathhere

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

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

    process $file
done

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

使用 git-annex:

我建议git-annex它不仅包含Git许多其他外部工具,例如inotify-toolsbashtarrcloneborg

更多信息:这里

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

git clone git://git-annex.branchable.com

网站、论坛(都是 Markdown 格式,所以下载速度非常快...)和代码库(Haskell 格式!)等

答案3

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

  • 创建一个 RCS 子目录,用于存储版本历史记录。
  • 编辑你的文件
  • 检查您的更改:ci -l -m -t- myfile
  • 重复

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

$RCSfile$
$Revision$
$Date$

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

存储的文件RCS/将被调用myfile,v,并将包含每个版本之间的差异。当然,关于 RCS 还有更多东西需要了解。您可以查看cicorcsrcsdiff其他的联机帮助页。

以下是更多信息:

  • 如果您跳过创建RCS/目录,那么存档将出现在与您的文件相同的目录中。
  • 您可以“签入”文件以ci在存档中记录该文件的版本(*,vRCS/ 目录中的文件)。签入会产生奇怪的副作用,即删除您的文件,使您的数据仅存在于*,v存档中。为了避免这种副作用,请使用-lor-uci命令。
  • 您可以“签出”一个文件,以便co从存档中重新构建它。
  • 您“锁定”文件以使其可写并防止其他人写入该文件,这会造成“合并”情况。在您的情况下,只有一个用户修改文件,“锁定”意味着可写,“解锁”意味着只读。如果您修改并“解锁”文件(通过强制写入),ci当您尝试检查更改时会抱怨(因此,避免这样做)。
  • 由于您是唯一编辑文件的人,因此您可以选择多种方案:您可以将文件保持为只读(解锁)或可写(锁定)。我对不希望经常更改的文件使用解锁模式,因为这可以防止我意外修改它们,因为它们是只读的,即使对我来说也是如此。我对正在修改的文件使用锁定模式,但当我想保留内容的修订历史记录时。
  • -lci或一起使用co将锁定它,使其保持可写状态。如果没有,-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.4myfile

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

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

答案4

吉特夫斯提供两全其美的功能,至少如果它对您有用的话。它提供了 git 存储库的视图,您可以在其中编辑文件,并且每个版本都会自动提交。

mkdir mnt
gitfs https://example.com/repo.git $PWD/mnt -o repo_path=$PWD/working_copy

之后,您可以在 中编辑文件mnt/current,文件的每个版本都会自动提交到 git,并且也可以通过mnt/history/*/*.

请注意,第一个参数必须是远程存储库。 Gitfs 似乎不适用于本地存储库:如果它是裸露的,它会指示 git 访问origin不存在的远程存储库,如果它是非裸露的,Gitfs 会尝试推送到它,但会失败,并且 Gitfs 不会。除非通过调试消息,否则不会告诉您,这样您就会丢失所有更改。

需要注意的是:gitfs 似乎有很多错误且维护不善。无声的失败是一个常见问题(通过-o log=-,debug=true,foreground=true,…尝试诊断)。您需要启用user_allow_otherin /etc/fuse.conf,因为参数操纵是有问题的。这是正确的概念,但我不能推荐它,除非有人承担维护责任并修复它(我不是自愿的)。

相关内容