我有一个纯文本文件(不包含源代码)。我经常修改它(添加行、编辑现有行或任何其他可能的修改)。对于任何修改,我想自动地记录:
- 修改了什么(差异信息);
- 修改的日期和时间。
(理想情况下,我还希望能够在特定时间获取我的文件的版本,但这是一个优点,而不是必需的)。
这对于 Git 来说当然是可能的,但它太强大而且太复杂了。我不想每次都处理add
、commit
消息等。push
我只想用vi
(或等效的)编辑文件,保存它,并自动记录上面的修改(其差异和时间)。
Linux 下有没有工具可以实现这个功能?
更新:感谢您提出的所有建议和几种解决方案。我并不反对git
,但我明确希望避免它(出于多种原因,最后但并非最不重要的事实是我对它了解不够)。最接近上述要求(没有git
、没有提交消息、很少或没有开销)的工具是 RCS。它是基于文件的,这正是我正在寻找的。这甚至避免了使用脚本、提供文件的先前版本并避免了vi
.
题目要求准确;人们提出了许多意见,但问题本身并不是那么基于意见。然后,显然,可以通过工具或脚本来实现相同的目标,但这也适用于许多其他情况。
答案1
给git
一个机会
我不明白为什么使用强大的工具是一个问题。只需编写一个git
定期运行的简单 bash 脚本(通过cron
或systemd
计时器);自动生成提交消息等
正如其他人在评论中强调的那样,当然可以创建本地存储库(请参阅这里和那里更多细节)。
如果您更喜欢托管自己的远程存储库,则需要设置一个“裸存储库”。两者
git init
都git 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-tools
、bash
、tar
、rclone
等borg
。
更多信息:这里。
如果你想稍后阅读 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 还有更多东西需要了解。您可以查看ci
、co
、rcs
和rcsdiff
其他的联机帮助页。
以下是更多信息:
- 如果您跳过创建
RCS/
目录,那么存档将出现在与您的文件相同的目录中。 - 您可以“签入”文件以
ci
在存档中记录该文件的版本(*,v
RCS/ 目录中的文件)。签入会产生奇怪的副作用,即删除您的文件,使您的数据仅存在于*,v
存档中。为了避免这种副作用,请使用-l
or-u
与ci
命令。 - 您可以“签出”一个文件,以便
co
从存档中重新构建它。 - 您“锁定”文件以使其可写并防止其他人写入该文件,这会造成“合并”情况。在您的情况下,只有一个用户修改文件,“锁定”意味着可写,“解锁”意味着只读。如果您修改并“解锁”文件(通过强制写入),
ci
当您尝试检查更改时会抱怨(因此,避免这样做)。 - 由于您是唯一编辑文件的人,因此您可以选择多种方案:您可以将文件保持为只读(解锁)或可写(锁定)。我对不希望经常更改的文件使用解锁模式,因为这可以防止我意外修改它们,因为它们是只读的,即使对我来说也是如此。我对正在修改的文件使用锁定模式,但当我想保留内容的修订历史记录时。
-l
与ci
或一起使用co
将锁定它,使其保持可写状态。如果没有,-l
它将是只读的,co
或者如果是,它将被完全删除ci
。用于ci -u
将文件内容签入存档后将其保留为只读模式。- 使用
-m.
将防止ci
询问修订消息。 - 使用
-t-
将防止ci
询问初始消息(首次创建存档文件时)。 - 使用
-M
withci
或co
将使文件的时间戳与签入时的文件时间戳保持同步。 co -r1.2 -p -q myfile
将打印修订版1.2
到myfile
标准输出。如果没有该选项-p
,并假设已“myfile
解锁”(只读),则将co -r1.2 myfile
使用myfile
.禁用信息性消息。1.2
myfile
-q
- 您可以创建“分支”,并进行诸如
1.3.1.1
.我不推荐这样做,因为它很快就会变得混乱。我更喜欢保持线性的修改流程。
因此,如果您希望保持文件始终可写,您可以使用ci -l -M -m -t- myfile
.您可以使用rcsdiff myfile
查看当前内容myfile
与最近签入版本之间的差异。您可以使用查看修订版和的rcsdiff -r1.2 -r1.4 myfile
之间的差异。1.2
1.4
myfile
归档文件只是一个文本文件,其格式记录在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_other
in /etc/fuse.conf
,因为参数操纵是有问题的。这是正确的概念,但我不能推荐它,除非有人承担维护责任并修复它(我不是自愿的)。