Mẹo để đặt ~ dưới sự kiểm soát nguồn


77

Tôi muốn đặt thư mục chính của mình (~) dưới sự kiểm soát nguồn (git, trong trường hợp này), vì tôi có nhiều tệp cài đặt (.gitconfig, .gitignore, .emacs, v.v.) trong đó tôi muốn mang theo máy, và có chúng trong Git sẽ làm cho nó tốt để lấy chúng.

Máy chính của tôi là MacBook và cách cài đặt OS X, có nhiều thư mục tôi muốn bỏ qua (Tài liệu, Tải xuống, .ssh). Cũng có những thư mục đã sử dụng Git (.emacs.d).

Suy nghĩ của tôi là chỉ cần thêm tất cả các thư mục này vào tệp .gitignore của mình, nhưng điều đó có vẻ mệt mỏi và có thể dẫn đến một số hậu quả không lường trước được. Suy nghĩ tiếp theo của tôi là định kỳ sao chép các tập tin tôi muốn lưu trữ vào một số thư mục trong nhà, sau đó cam kết thư mục đó. Vấn đề với điều đó sẽ là tôi phải nhớ di chuyển chúng trước khi cam kết.

Có một cách sạch sẽ để làm điều này?


Bạn cũng có thể tạo một tập lệnh thực hiện các cam kết của các thư mục bạn muốn và gọi nó thông qua các cronjobs.
Shadok

Lưu ý rằng hệ thống tệp HFS + mặc định trên Mac OS X không phân biệt chữ hoa chữ thường (nhưng bảo quản trường hợp) và các đường dẫn tệp được mã hóa theo UTF-8 được phân tách chính tắc trong không gian người dùng! Để biết thêm thông tin, hãy xem: <a href=" stackoverflow.com/questions/5581857/ và vấn đề Umlaut trên Mac OS X</a>

Câu trả lời:


60

Tôi có $HOMEdưới git. Dòng đầu tiên của tệp .gitignore của tôi là

/*

Phần còn lại là các mẫu không bỏ qua bằng cách sử dụng công cụ !sửa đổi. Dòng đầu tiên này có nghĩa là mặc định là bỏ qua tất cả các tệp trong thư mục nhà của tôi. Những tệp mà tôi muốn kiểm soát phiên bản đi vào .gitignorenhư thế này:

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

Một mô hình phức tạp hơn tôi có là:

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

Đó là, tôi chỉ muốn phiên bản .ssh/config- Tôi không muốn các khóa và các tệp khác trong .ssh đi vào git. Trên đây là cách tôi đạt được điều đó.

Chỉnh sửa: Đã thêm dấu gạch chéo để bắt đầu tất cả các đường dẫn. Điều này làm cho các mẫu bỏ qua khớp với từ đầu của kho lưu trữ ($ HOME) thay vì bất cứ nơi nào. Ví dụ: nếu !lib/là một mẫu (không bỏ qua mọi thứ trong thư mục lib) và bạn thêm một tệp .gitignore, trước đó mẫu ( !.gitignore) phù hợp với mẫu đó. Với dấu gạch chéo hàng đầu ( !/.gitignore), nó sẽ chỉ khớp .gitignoretrong thư mục chính của tôi chứ không phải trong bất kỳ thư mục con nào.

Tôi chưa thấy trường hợp nào điều này tạo ra sự khác biệt thực tế với danh sách bỏ qua của tôi, nhưng dường như nó chính xác hơn về mặt kỹ thuật.


1
Dường như với tôi rằng điều tương tự có thể đạt được theo cách dễ dàng hơn nhiều .
Nick Volynkin

24

Những gì tôi làm (với cùng một mục tiêu) là đặt các tệp cấu hình của tôi trong thư mục con ~/libvà có các liên kết tượng trưng trong thư mục chính của tôi, ví dụ : .emacs -> lib/emacs/dot.emacs. Tôi chỉ giữ các tệp cấu hình mà tôi đã viết rõ ràng dưới sự kiểm soát phiên bản; thư mục nhà của tôi chứa rất nhiều tệp chấm được tạo tự động không thuộc kiểm soát phiên bản. Do đó, ~/libdưới sự kiểm soát phiên bản, và thư mục nhà của tôi thì không.

Tôi có một tập lệnh tạo các liên kết tượng trưng từ các tập tin bên dưới ~/lib. Khi tôi tạo một tài khoản trên một máy mới, tôi sẽ điền nó bằng cách kiểm tra ~/libvà chạy tập lệnh đó.

Kinh nghiệm của tôi là với CVS, không phải git, vì vậy nó không thể chuyển nhượng 100%. Một trong những lý do tôi đã không đặt thư mục nhà của mình ngay dưới CVS là vì nó ~/.cvsignoresẽ áp dụng cho tất cả các kiểm tra CVS của tôi chứ không chỉ thư mục nhà của tôi; git không có vấn đề này Nhược điểm của cách tiếp cận đó so với việc có thư mục chính dưới sự kiểm soát phiên bản là bạn không thể sử dụng git statusđể phân biệt giữa một tệp mà bạn đã quyết định bỏ qua một cách rõ ràng (sẽ được liệt kê trong tệp bỏ qua, vì vậy không được hiển thị) tập tin mà bạn không có ý kiến ​​về (sẽ được hiển thị với a ?).

Một số tệp cần phải khác nhau trên các máy khác nhau. Tôi đặt chúng trong một thư mục được gọi ~/Local/SITENAME/libvà cũng tạo các liên kết tượng trưng cho chúng hoặc (đối với các định dạng tệp hỗ trợ nó) có một lệnh bao gồm trong tệp bên dưới ~/lib. Tôi cũng có một liên kết tượng trưng ~/Here -> ~/Local/SITENAME. Vì git, không giống như CVS, được thiết kế để hỗ trợ các kho lưu trữ hầu hết tương tự nhưng không giống nhau, có thể có một cách tốt hơn để quản lý các tệp cụ thể của máy. Một số tệp chấm của tôi trên thực tế không phải là liên kết tượng trưng, ​​nhưng được tạo tự động từ nội dung bên dưới ~/lib~/Here.


Có thể bạn có core.excludesfile = ~/.gitignore. Nếu không có cấu hình như vậy, tệp sẽ không được áp dụng cho bất kỳ kho lưu trữ nào ngoại trừ một kho lưu trữ trong ~/.git(ngay cả khi đó nó sẽ không áp dụng cho các kho lưu trữ phụ). Tôi sử dụng core.excludesfile = ~/.git-user-excludesđể tránh xung đột giữa các loại trừ tôi muốn áp dụng cho tất cả các kho Git của tôi (bất kể vị trí) và loại trừ tôi muốn áp dụng cho kho lưu trữ (một phần) thư mục nhà của tôi.
Chris Johnsen

@Chris: Tôi biết rất ít về git. Tôi có thể đã hiểu nhầm câu này trong gitignoretrang man: Các mẫu hình được đọc từ tệp .gitignore trong cùng thư mục với đường dẫn hoặc trong bất kỳ thư mục mẹ nào (mật). Thực tế, nó có dừng ở gốc của thanh toán không các .gitthư mục là)?
Gilles

1
Có, việc tìm kiếm .gitignorecác tập tin đi lên được giới hạn bởi thư mục gốc của cây làm việc. Câu bạn trích dẫn vẫn tiếp tục: chà (lên tới phần toplevel của cây công việc).
Chris Johnsen

@Chris: phiên bản trang nam của tôi không có những từ này - có vẻ như từ ngữ đã được làm rõ. Tôi đã sửa câu trả lời của mình. Cảm ơn!
Gilles

điều này đã được thảo luận trong cuộc trò chuyện gần đây
strugee

11

Chúng tôi có thể sử dụng khả năng của Git để tiếp tục theo dõi các tệp ngay cả khi chúng được liệt kê trong .gitignore. Vì vậy, điều này là đủ cho .gitignore:

$ cat .gitignore
/*

Đối với mỗi tệp mà bạn muốn theo dõi, hãy chạy add -f( -ftham số ghi đè bỏ qua cả trong .gitignore.git/info/exclude):

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

Sau khi đã lập chỉ mục một tệp, Git sẽ theo dõi tất cả các thay đổi mặc dù thực tế là tệp bị bỏ qua. Điều tương tự cũng hoạt động đối với một thư mục, nhưng chỉ đối với các tệp thực sự có mặt:

git add -f somedirname

Nếu bạn muốn theo dõi toàn bộ thư mục với tất cả các tệp mới xuất hiện trong đó, nó có thể được loại trừ .gitignoretheo một cách, được mô tả trong câu trả lời của camh :

!/somedirname

Nếu bạn muốn dừng theo dõi một tệp, lệnh này sẽ xóa một tệp khỏi chỉ mục của Git nhưng để nó không bị ảnh hưởng trên ổ cứng:

git rm --cached .ssh/config

1
Tôi sẽ cho bạn điểm của tôi nếu tôi có thể. Nếu cần lưu ý rằng phương pháp này chỉ có thể được sử dụng để theo dõi các tệp, không phải thư mục. Nếu bạn muốn có git theo dõi tất cả các tệp trong một thư mục, bạn vẫn cần bỏ qua thư mục đó trong .gitignore. Nếu không, các tệp mới trong thư mục đó sẽ không xuất hiện dưới dạng các tệp mới.
camh

5

Tôi sử dụng cái cũ rcscho điều đó.

Có một cái nhìn tại trang man cho ci, corcs. Những trang web này cũng hữu ích:

Tôi sử dụng phiên bản đó để kiểm soát dotfiles của tôi chẳng hạn:

ci -u .*vimrc

Và nếu tôi muốn chỉnh sửa chúng:

co -l .*vimrc

Tôi khuyên bạn nên tạo một thư mục có tên RCStrong của bạn ~, sau đó bạn có thể dễ dàng sao lưu thư mục đó ở đâu đó.


2
Bây giờ rcs khá đẹp và git làm mọi thứ rcs làm và nhiều hơn thế nữa. Tôi đã từng sử dụng rcs cho bất kỳ địa phương nào mà tôi không muốn chi phí thiết lập kho lưu trữ trên máy chủ, nhưng tôi đã hoàn toàn chuyển sang git ngay bây giờ cho loại sử dụng đó. Tôi thậm chí đã viết một tập lệnh bao bọc cvs2git để chuyển đổi hệ thống phân cấp thư mục hiện có với các tệp rcs trong đó thành git.
Neil Mayhew

1
Vâng, tôi biết đó là ngày. Câu hỏi là cho một mẹo về cách làm điều đó. Tôi vừa nói với anh chàng này rằng tôi đã làm việc đó trong nhiều năm qua ("ngày", gợi ý, gợi ý). Nó không có nghĩa theo cách đó là cách hợp lý duy nhất để làm điều đó.
Polemon

5

Tôi kiểm tra các tệp cấu hình của mình $HOME/.conf/từ kho lưu trữ BitBucket Mercurial. Một repo GitHub cũng sẽ hoạt động tốt.

Thanh ~/.conftoán chứa các tệp cấu hình và tập lệnh shell để điền các liên kết tượng trưng vào $HOMEtừng tệp trong ~/.conf. Đối với các định dạng cấu hình có hỗ trợ bao gồm ( .bashrc, .inputrc, .vimrc, vv) tôi bao gồm các ~/.conftập tin chứ không phải là liên kết đến nó, vì vậy mà tôi có thể làm ghi đè địa phương.

Đối với một số tệp cấu hình, tôi liên kết đến một tệp trong thư mục Dropbox của mình và chia sẻ qua dropbox.

Trong một vài tháng, tôi đã cố gắng $HOMEkiểm soát phiên bản, nhưng tôi cảm thấy mệt mỏi với việc quản lý danh sách bỏ qua lớn, tôi mệt mỏi khi kiểm tra các thay đổi cấu hình được thực hiện bằng cách chạy ứng dụng và kết quả thậm chí không phải là thứ tôi muốn kiểm tra trên máy tính khác. Bạn có thể tưởng tượng việc sửa các xung đột trên ~/.gconfhoặc ~/.config/monitors.xml, hoặc phục vụ các phiên bản khác nhau của các ứng dụng máy tính để bàn không?

Tôi thấy việc liên kết tới hoặc bao gồm một danh sách giới hạn các tệp cấu hình mà tôi đã tùy chỉnh cá nhân và muốn chia sẻ trên các máy dưới dạng mặc định toàn cầu.



1

Tôi nghĩ linh cảm thứ hai của bạn để có thư mục không liên quan dưới sự kiểm soát nguồn là tốt.

Chỉ cần thêm 2 kịch bản shell ở đó. Một để sao chép các tệp dưới sự kiểm soát của bạn ~và cái kia để thu thập các tệp từ ~và sao chép nó trở lại thư mục được kiểm soát nguồn và cam kết.


0

Đây là một tập lệnh ruby ​​nhỏ mà tôi sử dụng để thiết lập một máy mới

#!/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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.