web-dev-qa-db-ja.com

〜をソース管理下に置くためのヒント

多くの設定ファイル(.gitconfig、.gitignore、.emacsなど)がそこにあり、マシン間で持ち運びたいので、ホームディレクトリ(〜)をソース管理(この場合はgit)の下に置きたいです。それらをGitに置くと、それらを取得するのに最適です。

私のメインマシンはMacBookで、OS Xのセットアップ方法で、無視したいフォルダーがたくさんあります(ドキュメント、ダウンロード、.ssh)。すでにGit(.emacs.d)を使用しているフォルダーもあります。

私の考えは、これらすべてのディレクトリを.gitignoreファイルに追加することでしたが、それは一種の面倒で、予期しない結果をもたらす可能性があります。次に考えたいのは、保存したいファイルを定期的にホームのフォルダにコピーしてから、そのフォルダをコミットすることでした。それに関する問題は、コミットする前にそれらを移動することを覚えておかなければならないことです。

これを行うきれいな方法はありますか?

78
Dan McClain

Gitの下に$HOMEがあります。私の.gitignoreファイルの最初の行は

/*

残りは、!修飾子を使用して無視しないパターンです。この最初の行は、デフォルトでは、ホームディレクトリ内のすべてのファイルを無視することを意味します。バージョン管理したいファイルは、次のように.gitignoreに入ります。

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

私が持っているよりトリッキーなパターンは:

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

つまり、バージョン.ssh/configのみを使用したい-.ssh内のキーやその他のファイルをgitに入れたくない。上記は私がそれを達成する方法です。

編集:すべてのパスの先頭にスラッシュを追加しました。これにより、無視パターンはどこでもではなく、リポジトリ($ HOME)の先頭から一致します。たとえば、!lib/がパターンであり(libディレクトリ内のすべてを無視しないでください)、ファイル.gitignoreを追加した場合、以前はパターン(!.gitignore)がそれに一致していました。先頭のスラッシュ(!/.gitignore)を使用すると、ホームディレクトリの.gitignoreのみに一致し、サブディレクトリには一致しません。

これが無視リストと実際的な違いを生むようなケースは見たことがありませんが、技術的にはより正確なようです。

60
camh

私が(同じ目的で)行うことは、構成ファイルをサブディレクトリ~/libに置き、ホームディレクトリにシンボリックリンクを設定することです(例:.emacs -> lib/emacs/dot.emacs)。私はバージョン管理下で明示的に記述した構成ファイルのみを保持しています。ホームディレクトリには、バージョン管理されていない、自動的に作成されたドットファイルがたくさん含まれています。したがって、~/libはバージョン管理下にあり、私のホームディレクトリはそうではありません。

~/libの下のファイルからシンボリックリンクを作成するスクリプトがあります。新しいマシンでアカウントを作成するときは、~/libをチェックアウトしてそのスクリプトを実行することにより、アカウントを作成します。

私の経験はgitではなくCVSを使用しているため、100%転送することはできません。ホームディレクトリをCVSの直下に配置しなかった理由の1つは、~/.cvsignoreがホームディレクトリだけでなく、すべてのCVSチェックアウトに適用されることです。 gitにはこの問題はありません。ホームディレクトリをバージョン管理下に置くことと比較したそのアプローチの欠点は、git statusを使用して、明示的に無視することを決定したファイル(ignoreファイルにリストされるため、表示されない)およびあなたが意見のないファイル(?で表示されます)。

一部のファイルは、マシンごとに異なる必要があります。私はそれらを~/Local/SITENAME/libというディレクトリに置き、それらのシンボリックリンクも作成するか、(それをサポートするファイル形式の場合)~/libの下のファイルにincludeディレクティブを含めます。シンボリックリンク~/Here -> ~/Local/SITENAMEもあります。 gitは、CVSとは異なり、ほとんど同じですが同一ではないリポジトリをサポートするように設計されているため、マシン固有のファイルを管理するためのより良い方法があるかもしれません。実際、いくつかのドットファイルはシンボリックリンクではなく、~/libおよび~/Hereのコンテンツから自動的に生成されます。

ファイルが.gitignoreにリストされている場合でも、Gitの機能を使用してファイルを追跡し続けることができます。 .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

すべての新しいファイルが含まれるディレクトリ全体を追跡する場合は、以下の方法で.gitignoreから除外できます。 camhによる回答

!/somedirname

ファイルの追跡を停止したい場合は、次のコマンドを実行すると、Gitのインデックスからファイルが削除されますが、ハードドライブにはそのまま残ります。

git rm --cached .ssh/config
11
Nick Volynkin

BitBucket Mercurialリポジトリから$HOME/.conf/への構成ファイルをチェックアウトします。 GitHubリポジトリも同様に機能します。

~/.confチェックアウトには、$HOME内のシンボリックリンクを~/.conf内の各ファイルに入力するための構成ファイルとシェルスクリプトが含まれています。インクルードをサポートする構成フォーマット(.bashrc.inputrc.vimrcなど)の場合は、リンクではなく~/.confファイルをインクルードして、ローカルで上書きできるようにします。

一部の構成ファイルでは、Dropboxフォルダー内のファイルにシンボリックリンクし、Dropboxを介して共有します。

数か月間、$HOME自体をバージョン管理で維持しようとしましたが、大量の無視リストを管理するのにうんざりしており、実行中のアプリによって行われた構成変更をチェックインするのにうんざりしており、確認したい結果すらありませんでした。別のコンピュータで。 ~/.gconfまたは~/.config/monitors.xmlの競合を修正したり、デスクトップアプリのさまざまなバージョンに対応したりすることを想像できますか?

個人的にカスタマイズし、マシン全体でグローバルデフォルトとして共有したい構成ファイルの限定リストにシンボリックリンクするか、含めるのが簡単だと思います。

5
Graham

私はそのために古いrcsを使用します。

cico、およびrcsのマンページをご覧ください。これらのサイトも役立つはずです。

私は例えば私のドットファイルをバージョン管理するためにそれを使います:

ci -u .*vimrc

そして、それらを編集したい場合:

co -l .*vimrc

~RCSという名前のディレクトリを作成することをお勧めします。そうすれば、そのディレクトリをどこかに簡単にバックアップできます。

5
polemon

次のPython Dotfilesスクリプトを使用し始めました。これは、ファイルを自動リンクする便利なツールです。 https://pypi.python.org/pypi/dotfiles

3
trojjer

関連のないフォルダをソース管理下に置く2つ目の直感はいいと思います。

そこに2つのシェルスクリプトを追加するだけです。 1つは管理下にあるファイルを~にコピーし、もう1つは~からファイルを収集してソース管理フォルダーにコピーしてコミットします。

これは小さなマシンRubyで、新しいマシンのセットアップに使用します。

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