web-dev-qa-db-ja.com

ドットファイルをシンボリックリンクする代わりに$ HOMEをgitに置くことの落とし穴はありますか?

私は何年もの間、_$HOME_ディレクトリ全体をSubversionにチェックインしてきました。これには、すべてのドットファイルとアプリケーションプロファイル、多くのスクリプト、ツール、ハック、私の好みの基本的なホームディレクトリ構造、いくつかの奇妙なプロジェクト、およびウェアハウス相当のランダムデータが含まれています。これは良いことでした。それが続いた間。

しかし、手に負えなくなった。基本的なチェックアウトは数十のシステムで同じですが、すべてのものが私のマシンに適しているわけではありません。すべてが異なるディストリビューションでうまく機能するわけではありません。

私は家の掃除の最中です-データをそれが属する場所に分離し、いくつかのスクリプトを個別のプロジェクトとして分割し、自動化すべきもののいくつかの壊れたリンクを修正します。

私の目的は、_$HOME_のトップレベルのチェックアウトのためにSubversiongitに置き換えることですが、これをすべてのシステムで必要なもの、つまりドットファイル、いくつかのディレクトリ、いくつかの基本的なカスタムスクリプト。

オンラインで読む場合、多くの人がシンボリックリンクアプローチを使用してこれを行っているようです。サブディレクトリにクローンを作成し、_$HOME_からリポジトリにシンボリックリンクを作成します。私の_$HOME_があった10年以上にわたって完全なバージョン管理下に置かれている私は、このアプローチの考え方が気に入らず、なぜ人々がストレートチェックアウトメソッドをそれほど嫌っているように見えるのか理解できません。 _$HOME_のトップレベルのチェックアウトとして、gitに固有の注意すべき落とし穴はありますか?

追伸良いコーディングの演習の一部として、ルートチェックアウトをGitHubで公開することも計画しています。考え直さなくても共有できるはずのファイルに収集できるセキュリティ機密情報がどれほどあるかは恐ろしいことです。 WiFiパスワード、パスフレーズのないRSAキーなど。

39
Caleb

はいgitを考慮してSubversion

Gitはデフォルトで貪欲で再帰的です

Subversionは、知らないことは何も無視し、チェックアウトから上下に、知らない(または別のリポジトリに属している)フォルダーに到達すると、フォルダーの処理を停止します。一方、Gitはすべての子ディレクトリに再帰し続け、名前空間の問題のためにネストされたチェックアウトを非常に複雑にします。ホームディレクトリは、他のさまざまなgitリポジトリをチェックアウトして作業する場所でもあるため、ホームディレクトリをgitに置くと、ほとんどの場合、生活が混乱することになります。

結局のところ、これが人々がドットファイルを孤立したフォルダにチェックアウトし、そこにシンボリックリンクする主な理由です。 $HOMEの子ディレクトリで他のことを行うときに、gitが邪魔にならないようにします。これはあなたの家をSubversionにチェックインする場合の純粋な好みの問題ですが、gitを使用する場合は必要になります。

ただし、代替ソリューションがあります。 Gitは、「偽のルート」と呼ばれるものを許可します。この場合、すべてのリポジトリ機構は、チェックアウト作業ディレクトリから物理的に分離できる代替フォルダーに隠されます。その結果、gitツールキットが混乱することはありません。リポジトリを確認することもできず、作業コピーだけが表示されます。いくつかの環境変数を設定することで、ホームディレクトリを管理しているときに、Gitにそれらの瞬間の商品を見つける場所を教えてくれます。環境変数を設定しないと、誰も賢くならず、あなたの家は古典的なfile-y selfのように見えます。

このトリックフローを少しスムーズにするために、いくつかの優れたツールがあります。 vcs-homeメーリングリスト は、開始するための事実上の場所のようであり、概要ページには、ハウツーや人々の経験の便利なまとめがあります。途中、 vcshmr のような気の利いた小さなツールがあります。ホームディレクトリを直接gitに保持したい場合は、vcshがほぼ必須のツールです。ホームディレクトリを裏でいくつかのリポジトリに分割することになった場合は、vcshmrを組み合わせて、すばやく簡単に管理できます。

17
Caleb

ホームディレクトリ全体をバージョン管理にチェックインしたくありません。これは、アクセスするすべてのサブディレクトリにホームディレクトリのバージョン管理コンテキストがあることを意味します。その場合、git checkoutなどのコマンドは実際のアクションを実行し、誤ってgit自体であるか、gitを呼び出すスクリプトであるかに関係なく、間違ったディレクトリから何かを実行すると問題が発生します。

また、不要なものをリポジトリに追加する可能性が高くなります。これは、すべてをチェックインした場合は問題ではありませんでしたが、現在は問題になっています。誤ってプライベートキーファイルを追加した場合(おそらく習慣が間違っている場合)、それをgithubにプッシュした場合

そうは言っても、主な欠点は実際には技術的なものではなく、自分から自分を救いたいだけだと思います。

シンボリックリンクについては、リポジトリをサブディレクトリに複製し、更新が必要なシンボリックリンクを更新するスクリプトを作成できます。ただし、このスクリプトに必要なメンテナンスの量は、スクリプトを使用することの利点を上回る場合があります。シンボリックリンクのほうが手間がかからないかもしれません。

シンボリックリンクを使用すると、gitにチェックインされるディストリビューション固有(またはホスト固有)の追加も簡単に行うことができます。 symlink-updateスクリプトは、互換性のないプラットフォームまたは異なるホスト向けのファイルを無視し、適切なファイルのみを更新します。

何かのようなもの:

HOMEREPO=$HOME/homerepo
Host=$(hostname)
UNAME=$(uname)

for dotfile in $HOMEREPO/shared/* $HOMEREPO/Host-$Host/* $HOMEREPO/uname-$UNAME/*
do
    target=$HOME/$(basename $dotfile)
    [ ! -r $target ] && ln -s $dotfile $target
done

個人的に:私はシンボリックリンクを使用し、ディレクトリをシンボリックリンクしません。内のファイルのみ。これにより、それらのディレクトリでサイトローカルの変更(つまり、ファイルの追加/削除)を行う柔軟性が得られます。すべてのシンボリックリンクを手動で再作成する必要があるため、新しいシステムでアカウントを設定するのは面倒です。

14
mrb

別の見方をすると、私は$ HOMEをgitの下に置いており、欠点はありませんでした。私は明らかにこのgitリポジトリをgithubに同期しません。プライベートレポジトリのあるサービスを利用しています。また、メディアファイル、ダウンロード、パッケージをgitの管理下に置かないようにしています。

  • git statusは、「実行する、クリーンにする」チェックリストの一種です。

  • 私は一時的なもののために~/tmpを持っていますが、これは無視されます。

  • 最近インストールしたソフトウェアが$ HOMEに追加したいと思っているものをgit statusに表示したり、これらのファイルを削除したり、原因をアンインストールしたりすることもよくあります。

  • 本当に役立つローカルファイルとディレクトリを.gitignoreに手動で追加します。これには、「インストール時に行うことを知る」というメリットがあります。

  • 新しいVM=を構築するか、新しいPCをインストールする場合は、リモートホームを$ HOMEに複製するだけで、必要なものがすぐに手に入ります。

  • Vimプラグインのバンドルのようなものはもう必要ありません。

複雑さが嫌いです。 rcfileを微調整するときは、それを実行し、コミットしてプッシュします。その後、反射として、$ HOMEを1日おきにgit pullし、常に最新の構成にします。とても簡単です。

現在このレジメン下にあるマシン:自宅のラップトップ、仕事用PC、仕事用VM、および3つまたは4つのリモートサーバー。

6
gb.

私は両方を試しました、そして最後に symlinkアプローチ を優先しました:

  • どこへでもチェックアウト
  • make install
  • ログアウトして再度ログインし、X設定をロードする

短所:

  • ファイルを追加する前に、リポジトリに-ファイルを移動する必要があります
  • Makefileでシンボリックリンクのリストを維持する必要がある

利点:

  • 大規模な.gitignoreは必要ありません(私は控えめなUbuntuボックスの~に133のドットファイルがあります)
  • できますメンテナンススクリプトを保持およびその他の~関連のもの(Makefileユーティリティスクリプト など)邪魔にならない
  • できます個人設定と公開設定を個別にバージョン管理

制限:

  • @mrbとは異なり、私は~にのみシンボリックリンクを作成します。これにより、シンボリックリンクがシンプルになり、たとえば~/.vimなどの非常にまれな.gitignoreメンテナンスを犠牲にして、新しいファイルに気付くことは簡単になります。

私の場合、最後の2つの利点がスケールに影響を与えました。ホームディレクトリを乱雑にしたくなく、プライベートコンテンツとパブリックコンテンツを明確に区別したいです。

私が知っている、シンボリックリンクの処理に問題がある(または少なくとも問題があった)アプリケーションはPidginだけでした-通常のファイルでシンボリックリンクを上書きし続けました。

6
l0b0

これが1つです:git rebase -i --rootを実行しようとして、リポジトリの最初のコミットで.gitconfigをチェックインした場合、gitは.gitconfigファイルを一時的に削除します。リベース操作を完了するには、そのファイルに保存されている名前と電子メールが必要です。

それらを再度構成してgit rebase --continueを実行することもできますが、それを行ってリベース操作を完了した後、以前の最初のコミットであったコミットの前に、gitリポジトリがコミットメッセージなしで空のコミットを取得していました。私はそれを取り除く方法がわかりません。

代わりにgit rebase -i <commit>を実行し、.gitconfigの後のコミットとともに<commit>がチェックインされるとどうなるかわかりません。

おそらく最も簡単な解決策は、.gitconfigをリポジトリに追加せずに、.gitignoreにリストすることです。

3
HelloGoodbye

これが私のやり方です:

  1. クリーンなLinuxをインストールします(必須ではありませんが、手順4で生活をより快適にします)
  2. etckeeperをインストールする
  3. 家でgit initを実行
  4. .gitignoreを作成し、興味がないように見えるものや、大きく変わる可能性のあるものをすべて追加します。必ず*.cache*.lockなどを追加してください。/*を追加することはお勧めしません。家に新しいものが追加されても、自動的に通知されないためです。これはブラックリストアプローチとホワイトリストアプローチの比較です。基本的に、揮発性のものと、気にしないいくつかのソフトウェアを除いて、すべてのソフトウェアの構成を保持します。後でシステムをマージ、移行、または比較するときに、すべてを比較できると非常に便利です。 .bashrcと他のいくつかのドットファイルを格納するだけの場合よりも、はるかに速く新しいシステムをセットアップできます。このようにして、GUIを介して設定する可能性のある構成を保持し、どのdotfilesが設定を保存するかを意識する必要がなくなります。 (揮発性ファイルをコミットしたことが判明した場合でも、gitに変更なしと仮定するように指示できます)
  5. etckeeper init -d /home/usernameを実行します
  6. git commit -d /home/usernameを実行します
  7. シェルでエイリアスを設定し、homekeeper checkoutのようにコマンドラインをより快適にします

Etckeeperを使用する理由は、ファイルのアクセス許可などのメタデータを格納するためです(SSHキーなどの特定の項目ではかなり重要です)。これで、メタデータを自動的に保存するpre-commitフックができました。チェックアウト後のことはよくわかりません。おそらくetckeeper checkout xxx -d /home/userを使用する必要があります。もう少し詳しく調べて、この答えを詳しく説明します。

2
user13666