Đặt giá trị cấu hình git cho tất cả các thư mục con


79

Tôi biết rằng có thể đặt các cấu hình per-repo ghi đè cấu hình cấp người dùng (tức là /path/to/my/repo/.gitconfigghi đè ~/.gitconfig). Có thể đặt cấu hình git ghi đè cài đặt cấp người dùng cho tất cả các thư mục con của một thư mục nhất định không? Tức là tôi có

|--topLevelFolder1
|--\
|   ---.gitconfig_override
|--\
|   ---childFolder1
|       \---[...]
|--\
|   ---childFolder2
|       \---[...]

Và tôi muốn các cài đặt được xác định trong .gitconfig_overrideđể áp dụng trongchildFolder1childFolder2.

Động lực của tôi cho điều này như sau: Tôi có một máy tính xách tay làm việc và tôi cũng sử dụng trong thời gian rảnh rỗi cho các dự án cá nhân. Tất cả mã công việc của tôi được lồng trong một thư mục. Khi tôi chuyển sang repos git công việc, tôi cần làm như vậy với tính cách công việc của mình - đăng nhập công việc thay vì tên và email công việc. Khi tôi chuyển đến kho lưu trữ cá nhân (github) của riêng mình, tôi muốn làm như vậy với tên thật và email cá nhân của mình.

Các giải pháp khả thi khác mà tôi đã nghĩ đến (và các vấn đề):

  • Tạo người dùng riêng biệt cho "công việc" và "giải trí", đặt cài đặt cấp người dùng của họ một cách thích hợp và đăng nhập với tư cách người dùng thích hợp khi tôi chuyển đổi ngữ cảnh (rắc rối, cộng với việc tôi có thể dễ dàng quên chuyển đổi)
  • Tạo tập lệnh tìm kiếm git repo bên trong "workFolder" và thêm / cập nhật các tệp .gitconfig của chúng để chứa các chi tiết thích hợp (nếu tôi tạo repo và quên chạy tập lệnh trước khi đẩy, tôi sẽ đẩy nhầm người)
  • "hack" git để mỗi khi tạo repo, nó sẽ kiểm tra đường dẫn tệp và nếu thích hợp, cập nhật tệp .gitconfig (phức tạp, lộn xộn và gần như chắc chắn là Cách làm sai - ngoài ra, tôi sẽ không có manh mối đầu tiên làm thế nào để đi về nó!)

Tôi đã kiểm tra câu hỏi này , câu hỏi này dường như chỉ chứa các giải pháp cho các repo đơn lẻ, không phải nhiều. Hy vọng sẽ có người xem câu hỏi này ai bỏ sót câu hỏi đó!


Bạn sẽ làm việc trên cùng một kho lưu trữ như cả "bạn làm việc" và "bạn cá nhân"? Nếu không, câu hỏi bạn đã liên kết chứa câu trả lời mà tôi muốn đưa ra. --globalCài đặt người dùng của bạn phải chứa bất kỳ danh tính nào bạn sử dụng nhiều hơn. Mỗi kho lưu trữ sử dụng danh tính khác nên có user.nameuser.emailđặt cho phù hợp.
Chris

Tôi sẽ không bao giờ làm việc trong cùng một repo với hai người dùng khác nhau - mỗi repo sẽ là "cơ quan" hoặc "nhà riêng" - nhưng vấn đề xuất phát từ thực tế là (ít nhất là đối với công việc), tôi có 35 repo, và đang bổ sung thường xuyên hơn. Tôi có thể thêm user.nameuser.emailcài đặt trong mỗi repo hiện có và thiết lập tập lệnh cron để thêm chúng vào bất kỳ repo nào mới được thêm vào, nhưng sẽ dễ dàng hơn nhiều nếu tôi có thể đặt chúng ở một nơi duy nhất "lọc xuống" bất kỳ repos trong các thư mục con.
scubbo

Câu trả lời:


32

CHỈNH SỬA: Git 2.13 đã giới thiệu bao gồm có điều kiện , được thiết kế để giải quyết vấn đề chính xác này.

Câu trả lời ban đầu của tôi được lưu giữ bên dưới, vì lợi ích của lịch sử (và người dùng bị mắc kẹt trên các phiên bản git cũ hơn).

====================================

Hành vi chính xác mà bạn mong muốn không được hỗ trợ, dựa trên việc đọc trang web gitconfig.

Tuy nhiên, kể từ git 1.7.12 , Git đọc dữ liệu cấu hình từ bốn nguồn khác nhau , hai trong số đó là dành riêng cho người dùng:

$XDG_CONFIG_HOME/git/config~/.gitconfig. Mục ~/.gitconfignhập ghi đè mục nhập trong $XDG_CONFIG_HOME/git/config.

Điều đó có nghĩa là bạn có thể lưu trữ gitconfig cá nhân của mình tại $XDG_CONFIG_HOME/git/configvà đặt các ghi đè dành riêng cho máy ~/.gitconfig. Cái gì đó như

[user]
    email = username@example.com

trong ~/.gitconfignên bao gồm trường hợp email của bạn.

Lưu ý rằng nếu $ XDG_CONFIG_HOME không được đặt, git sẽ tìm kiếm ~/.config/git/config.

Điều này hoạt động tốt đối với tôi, vì tôi chỉ có hai kho lưu trữ cá nhân trên máy công việc (cấu hình emacs của tôi và tệp dotfiles của tôi). Nếu bạn thường xuyên thêm các kho lưu trữ cá nhân vào máy làm việc của mình, điều này có thể không đủ tốt cho bạn.

Trong trường hợp đó, giấy gói tùy chỉnh xung quanh git initgit clonesẽ được đặt cược tốt nhất của bạn.

Bất kỳ tệp nhị phân nào trên $ PATH của bạn có tên khớp với 'git- *' đều có thể được gọi là lệnh git, vì vậy bạn chỉ cần một cặp tập lệnh shell gọi lệnh ban đầu với tất cả các args đã được truyền, sau đó sao chép tệp cấu hình chính xác vào .git/config.


Một số cài đặt git có thể được kiểm soát bằng cách đặt các biến môi trường. Chúng ghi đè các giá trị từ tệp cấu hình. Một tiện ích rất tốt để thiết lập / bỏ thiết lập các biến env trên mỗi hệ thống phân cấp thư mục là direnv,. Xem câu trả lời của tôi bên dưới để biết tất cả các chi tiết.
Ajay M

90

Như đã đề cập trong bản chỉnh sửa của NateEag , git's Conditional Bao gồm hoàn hảo cho việc này. Vì câu trả lời đó là câu trả lời dành cho những người trên git <2,13, đây là câu trả lời dành cho những người có phiên bản mới hơn.

Trước tiên, hãy tạo một tệp cấu hình mới ở đâu đó với các cài đặt bạn muốn có hiệu lực trong các thư mục con - bằng cách sử dụng các thư mục của câu hỏi ban đầu, giả sử nó ở ~/topLevelFolder1/.gitconfig_include

Trong ~/.gitconfig, thêm:

[includeIf "gitdir:~/toplevelFolder1/"]
    path = ~/topLevelFolder1/.gitconfig_include

Bất kỳ thư mục con nào ~/topLevelFolder1bây giờ sẽ bao gồm cấu hình trong ~/toplevelFolder1/.gitconfig_include- không cần phải thay đổi thủ công .git/configtrong repo của mỗi thư mục con. (Điều này không ghi đè bất kỳ thứ gì trong cấu hình thư mục con - nó chỉ thêm vào nó, như "bao gồm" ngụ ý.)


10
Dấu gạch chéo ( /) trong gitdirđiều kiện là quan trọng.
stefanct

2
Đây nên được đánh dấu là câu trả lời chính xác cho câu hỏi này. Nhờ đề cập đến includeIf(và một chút thử nghiệm và lỗi), giờ đây tôi đã định cấu hình một cây thư mục cụ thể trên PC làm việc của mình, trong đó mọi hành động Git xác định tôi là tài khoản cá nhân và sử dụng khóa SSH cá nhân của tôi, cùng với thư mục tương tự cho nội dung công việc trên PC cá nhân của tôi. Trong khi đó phần còn lại của mỗi hệ thống sử dụng email, tên và khóa SSH thích hợp trên cả hai máy. Tôi chỉ ước tôi

ifphần thực sự cần thiết? Nếu tham chiếu pathkhông tồn tại, mục nhập dường như bị bỏ qua.
Oliver Pearmain

Nếu chỉ git chỉ làm những điều hợp lý và đi bộ trên cây tìm kiếm .gitthư mục trong mỗi thư mục cha ...
Ian Kemp

@OliverPearmain Mục tiêu không phải là bao gồm tệp nếu nó tồn tại, mà là bao gồm tệp nếu bạn đang ở trong một repo theo đường dẫn đã cho.
phemmer

14

Bạn có thể sử dụng direnvlệnh để đặt các biến môi trường áp dụng cho tất cả các thư mục con. Bạn có thể ở bất kỳ đâu trong hệ thống phân cấp thư mục đó. Nếu cài đặt git bạn đang cố gắng thiết lập có thể được kiểm soát bởi một biến môi trường, thì bạn là người may mắn.

Đọc direnvtrang cơ bản http://direnv.net/ để thiết lập nó cho trình bao của bạn. Đối với zsh, nó đơn giản như dán dòng này ở cuối.zshrc và khởi động lại trình bao.

eval "$(direnv hook zsh)"

Kiểm tra xem cài đặt git bạn muốn có thể được kiểm soát bởi một biến môi trường hay không. Có vẻ như bạn muốn kiểm soátauthor.email một cây thư mục cụ thể, được điều khiển bởi biến môi trường GIT_AUTHOR_EMAIL,. Lưu ý, biến môi trường được ưu tiên hơn cấu hình. Danh sách đầy đủ các biến môi trường mà git hỗ trợ có tại đây: https://git-scm.com/book/en/v2/Git-Internals-Enosystem-Variables

Như, direnv chỉ định, tạo một tệp có tên, .envrcở gốc của hệ thống phân cấp; trong trường hợp của bạn,topLevelFolder1

Ví dụ:

echo export GIT_AUTHOR_EMAIL=myotheremail@esp.com > .envrc

"Cho phép" envrc: direnv allow .Thế là xong!

Mỗi khi bạn nhảy vào hệ thống phân cấp, direnvsẽ tìm thấy .envrctệp đã nói và tải nó.

$ cd ~/topLevelFolder1/childFolder1/project_name
direnv: loading ../../../.envrc
direnv: export +GIT_AUTHOR_EMAIL

$ echo ${GIT_AUTHOR_EMAIL}
myotheremail@esp.com

Nhảy ra khỏi cấu trúc thư mục và direnvsẽ dỡ các biến đó

cd ~
direnv: unloading

7

Các [include]phần trong cấu hình git ( .git/config, ~/.gitconfig...) là những gì bạn đang tìm kiếm.

[include]
    path = /path/to/foo.inc ; include by absolute path
    path = foo ; expand "foo" relative to the current file
    path = ~/foo ; expand "foo" in your $HOME directory

Xem câu hỏi đã trả lời chi tiết: Có thể đưa tệp vào .gitconfig của bạn không

Xem Tài liệu git-config: http://git-scm.com/docs/git-config#_includes

BIÊN TẬP

Thêm vào childFolder1/.git/configchildFolder2/.git/config:

[include]
    path = ../.gitconfig_override

2
OK - vì vậy điều này giải quyết vấn đề chỉ xác định user.nameuser.emailở một nơi (trong ../.gitconfig_override), nhưng tôi không nghĩ rằng nó thực sự trả lời câu hỏi ban đầu? Nếu childFolder1childFolder2là con của parentFolder, tôi đang tìm cách đặt các giá trị cấu hình trong parentFolderđó sẽ lọc xuống bất kỳ kho lưu trữ nào được bắt nguồn từ các thư mục con.
scubbo

1
Như NateEag đã chỉ ra , điều này chỉ được giới thiệu trong Git 2.13. (Git 2.13.0 có từ ngày 9 tháng 5 năm 2017.) Vì vậy, nếu bất kỳ ai đọc câu trả lời này thắc mắc tại sao nó không hoạt động với họ, có thể họ đang sử dụng phiên bản cũ hơn của Git.

LƯU Ý rằng gần đây tôi đã gặp phải một vấn đề trong đó các bao gồm có điều kiện này dường như không được tôn trọng. Vấn đề là git (ít nhất, bản cài đặt của tôi - 2.17.0 trên MacOSX) dường như yêu cầu dấu gạch chéo trên đường dẫn thư mục.
scubbo
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.