将〜置于源代码控制之下的提示


77

我想将自己的主目录(〜)置于源代码控制下(在这种情况下为git),因为我想在其中携带许多设置文件(.gitconfig,.gitignore,.emacs等),并且将它们放在Git中将很适合于检索它们。

我的主计算机是MacBook,并且OS X的设置方式有很多我想忽略的文件夹(文档,下载,.ssh)。也有一些文件夹已经在使用Git(.emacs.d)。

我的想法是只将所有这些目录添加到我的.gitignore文件中,但这似乎有点烦人,并且可能导致一些无法预料的后果。我的下一个想法是定期将要存储的文件复制到home的某个文件夹中,然后提交该文件夹。这样做的问题是我必须在提交之前记住移动它们。

有没有一种干净的方法可以做到这一点?


您也可以制作一个脚本来提交所需的文件夹,然后通过cronjobs调用它。
Shadok

请注意,Mac OS X上的默认HFS +文件系统不区分大小写(但保留大小写),并且文件路径在用户空间中以规范分解的UTF-8编码!有关更多信息,请参见:< ahref=" stackoverflow.com/questions/5581857/…和MacOSX上的Umlaut问题</a>

Answers:


60

$HOME在git下。我的.gitignore文件的第一行是

/*

其余的模式是使用!修饰符不容忽视的模式。第一行表示默认设置是忽略主目录中的所有文件。我要进行版本控制的文件.gitignore如下:

!/.gitignore
!/.profile
[...]

我有一个比较棘手的模式:

!/.ssh
/.ssh/*
!/.ssh/config

也就是说,我只想要版本.ssh/config-我不希望我的密钥和.ssh中的其他文件放入git。以上是我如何实现的。

编辑:添加斜线以所有路径的开头。这使得忽略模式从存储库($ HOME)的顶部而不是任何位置匹配。例如,如果!lib/是模式(不要忽略lib目录中的所有内容),并且您添加了一个文件.gitignore,则以前的模式(!.gitignore)与之匹配。使用斜杠(!/.gitignore)开头时,它将仅.gitignore在我的主目录中匹配,而在任何子目录中均不匹配。

我没有看到这样的情况与我的忽略列表有实际区别,但是在我看来,这在技术上更加准确。


1
在我看来,可以更简单的方式实现相同的目标。
Nick Volynkin

24

我的工作(目的相同)是将配置文件放在子目录中,~/lib并在我的主目录中拥有符号链接,例如.emacs -> lib/emacs/dot.emacs。我只将我明确编写的配置文件保留在版本控制下。我的主目录包含大量不受版本控制的自动创建的点文件。因此~/lib处于版本控制之下,而我的主目录则不在。

我有一个脚本,可以根据下的文件创建符号链接~/lib。在新计算机上创建帐户时,我通过签出~/lib并运行该脚本来填充该帐户。

我的经验是使用CVS,而不是git,因此不是100%可移植的。我没有将主目录直接放在CVS下的原因之一是,这~/.cvsignore将适用于我所有的CVS检出,而不仅是我的主目录;git没有这个问题。与将主目录置于版本控制之下相比,该方法的缺点是您不能git status用来区分已明确决定忽略的文件(该文件将在忽略文件中列出,因此不会显示)和您没有意见的文件(将显示为?)。

某些文件在不同的计算机上需要不同。我将它们放在一个目录中,~/Local/SITENAME/lib并为它们创建符号链接,或者(对于支持它的文件格式)在下的文件中包含一个include指令~/lib。我也有一个符号链接~/Here -> ~/Local/SITENAME。由于与CVS不同,git被设计为支持大多数相似但不相同的存储库,因此可能有更好的方法来管理特定于计算机的文件。实际上,我的一些点文件不是符号链接,而是根据~/lib和下的内容自动生成的~/Here


也许您有core.excludesfile = ~/.gitignore。如果没有这样的配置,该文件将不会应用于除存储在其中的任何存储库之外的任何存储库~/.git(即使那样也不会应用于子存储库)。我使用core.excludesfile = ~/.git-user-excludes来避免我要应用于所有Git存储库的排除项(无论位置如何)与我要应用于保存主目录(部分)的存储库之间的冲突。
克里斯·约翰森

@Chris:我对git知之甚少。我可能会在gitignore手册页中误解了这一句话:“从与路径相同的目录中或任何父目录中的.gitignore文件读取的模式(...)”实际上是否在结帐的根处停止(即,在哪里该.git目录是)?
吉尔斯(Gilles)2010年

1
是的,向上搜索.gitignore文件受工作树根的限制。您引用的句子继续:“(直到工作树的顶层)”。
克里斯·约翰森

@Chris:我的手册页版本没有这些单词-看来措辞已经澄清。我已经纠正了我的答案。谢谢!
吉尔斯(Gilles)2010年


11

即使文件已在中列出,我们也可以使用Git的功能来继续跟踪文件.gitignore。因此,这足以满足.gitignore

$ cat .gitignore
/*

对于要跟踪的每个文件,运行add -f(该-f参数会覆盖和,.gitignore而忽略它们.git/info/exclude):

git add -f .gitignore
git add -f .profile
git add -f .zshrc
git add -f .ssh/config

为文件建立索引后,即使忽略了文件,Git也会跟踪所有更改。相同的方法适用于目录,但仅适用于实际存在的文件:

git add -f somedirname

如果要跟踪包含所有新文件的整个目录,则可以用camh.gitignore答案中所述的某种方式将其排除:

!/somedirname

如果您想停止跟踪文件,可以使用以下命令从Git的索引中删除文件,但不要在硬盘上保留它:

git rm --cached .ssh/config

1
如果可以的话,我会告诉你我的观点。需要注意的是,该方法只能用于跟踪文件,而不能用于跟踪目录。如果您想让git跟踪目录中的所有文件,您仍然需要在.gitignore中取消忽略该目录。否则,该目录中的新文件将不会显示为新文件。
camh 2015年

5

我用旧rcs的。

看看联机帮助页cicorcs。这些站点也应有所帮助:

我用它来控制我的点文件的版本,例如:

ci -u .*vimrc

如果我要编辑它们:

co -l .*vimrc

我建议在做一个新的目录RCS在你的~地方,你就可以轻松地备份目录。


2
rcs现在已经过时了,而git可以完成rcs的所有工作,此外还有很多其他事情。我曾经在不希望在服务器上建立存储库的本地任何地方使用rcs,但是对于这种用法,我现在已经完全切换到git了。我什至编写了一个包裹cvs2git的脚本,以将其中包含rcs文件的现有目录层次结构转换为git。
尼尔·梅休

1
是的,我知道它已经过时了。问题是关于如何做到这一点的提示。我刚刚告诉了这个人,我已经做很多很多年了(“日期”,提示,提示)。这并不意味着它是唯一可行的方法。
polemon 2013年

5

$HOME/.conf/从BitBucket Mercurial存储库中检出配置文件。GitHub存储库也可以正常工作。

~/.conf结账包含配置文件和一个shell脚本来填充符号链接中$HOME,以每个文件~/.conf。对于支持包容(配置格式.bashrc.inputrc.vimrc等),我包括~/.conf文件,而不是链接到它,这样我可以做局部覆盖。

对于某些配置文件,我符号链接到我的Dropbox文件夹中的文件,并通过Dropbox共享。

我花了几个月的时间尝试保持$HOME版本控制,但是我厌倦了管理大量的忽略列表,厌倦了检查正在运行的应用程序对配置所做的更改,结果甚至都不是我想在另一台计算机上签出的东西。您能想象解决~/.gconf或冲突~/.config/monitors.xml,还是迎合不同版本的桌面应用程序的需求?

我发现更容易符号链接或包含我个人定制的配置文件的有限列表,这些配置文件想作为全局默认值在计算机之间共享。


3

我刚刚开始使用以下Python Dotfiles脚本,这是一个方便的工具,可以自动为您链接文件:https ://pypi.python.org/pypi/dotfiles


1

我认为您的第二个直觉是在源代码管理下拥有不相关的文件夹,这很好。

只需在此处添加2个Shell脚本即可。一种将您控制下的文件复制到~,另一种从中收集文件~并将其复制回到源代码控制的文件夹并提交。


0

这是一个小红宝石脚本,我用它来安装新机器

#!/usr/bin/env ruby
# setup.rb

#list of dirs which you don't want to symlink
ignored = %w(.gitignore .gitmodules misc setup.rb readme)

current_dir = File.expand_path(Dir.pwd)
home_dir = File.expand_path("~")

links = `git ls-tree --name-only HEAD`.lines.map(&:strip).select {|x| !ignored.include?(x)  }

links.each do |link|
  link = File.join(current_dir, link)
  symlink = File.join(home_dir, File.basename(link))
  `ln -ns #{link} #{symlink}`
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.