2015-04-11 10 views
13

Tôi muốn bỏ qua một số tệp nhất định trong một chi nhánh mà không phải dựa vào tệp .gitignore được theo dõi sẽ bị ghi đè trong quá trình hợp nhất với các nhánh khác.Git không bao gồm tệp cho chi nhánh

Tôi đã theo dõi chặt chẽ a Stack Overflow answer cùng với the linked blog post, nhưng repo của tôi dường như không nhận ra được số excludesfile được chỉ định trong số .git/config của tôi. Tài liệu Git (git-config, gitignore) dường như không hiển thị cách chỉ định và giải quyết loại trừ tệp cho một nhánh cụ thể.

.git/config của tôi trông như thế này:

[core] 
     repositoryformatversion = 0 
     filemode = true 
     bare = false 
     logallrefupdates = true 
     ignorecase = true 
     precomposeunicode = true 
     excludesfile = +/info/exclude 

[branch "myspecialbranch"] 
     excludesfile = +/info/exclude_specialbranch 

tập tin .git/info/exclude của tôi trông như thế này (theo mặc định, tôi không chạm vào nó):

# git ls-files --others --exclude-from=.git/info/exclude 
# Lines that start with '#' are comments. 
# For a project mostly in C, the following would be a good set of 
# exclude patterns (uncomment them if you want to use them): 
# *.[oa] 
# *~ 
.DS_Store 

Tôi không có một tập tin .gitignore trong "specialbranch" của tôi.

Nếu tôi cố gắng bỏ qua một tập tin như info.php, file .git/info/exclude_specialbranch của tôi trông như thế này:

info.php 

... nhưng nó không bỏ qua các tập tin.

Nếu tôi chạy git status --ignored, nó chỉ liệt kê tệp .DS_Store từ tệp exclude mặc định.

Tuy nhiên, nếu tôi thêm info.php đến file .git/info/exclude tôi:

# git ls-files --others --exclude-from=.git/info/exclude 
# Lines that start with '#' are comments. 
# For a project mostly in C, the following would be a good set of 
# exclude patterns (uncomment them if you want to use them): 
# *.[oa] 
# *~ 
.DS_Store 
info.php 

nó bỏ qua các tập tin một cách hoàn hảo.

Lưu ý rằng nó vẫn hoạt động mà không có dòng excludesfile = +/info/exclude dưới [core] trong .git/config. Git dường như biết nơi mà toàn hệ thống exclude là không có tôi phải nói với nó.

Tôi có một cảm giác rằng .git/config không nhận ra địa chỉ của khách hàng của tôi không bao gồm file:

excludesfile = +/info/exclude_specialbranch 

... rất có thể vì việc sử dụng + để mô tả vị trí của thư mục .git.

Phương pháp chính xác để giải quyết các tệp loại trừ tùy chỉnh trong các phiên bản Git mới hơn?

Tôi đang chạy OSX 10.9.5 và phiên bản Git 2.2.1.

Trả lời

20

Git không hỗ trợ mỗi nhánh loại trừ các tệp

Bạn đang cố gắng đạt được điều gì đó mà Git không hỗ trợ. Các blog post là nguồn gốc của trò lừa đảo này the Stack Overflow answer chỉ parroted. Như đã lưu ý trong câu trả lời dưới câu trả lời đó, ngay cả bài đăng trên blog ban đầu chứa thảo luận cho thấy rằng giải pháp không hoạt động và liên kết đến một số newer blog post đề cập rằng ngay cả tác giả cũng không thể tái tạo hành vi.

Tại sao nó không hoạt động?Nếu bạn đọc man gitignoreman git-config, bạn sẽ chỉ thấy core.excludesfile được tham chiếu. Không có branch.<name>.excludesfile ở đó. core.excludesfile có nghĩa là cho phép bạn loại trừ ví dụ: Tệp Vim .swp hoặc các nội dung tạm thời khác mà phần mềm của bạn sử dụng.

core.excludesfile

Ngoài .gitignore (mỗi thư mục) và .git/info/exclude, Git nhìn vào tập tin này cho các mẫu của các tập tin mà không có nghĩa là để được theo dõi. "~/" được mở rộng thành giá trị $HOME và "~user/" vào thư mục chính của người dùng được chỉ định. Giá trị mặc định của nó là $XDG_CONFIG_HOME/git/ignore. Nếu $XDG_CONFIG_HOME không được đặt hoặc để trống, thì thay vào đó, $HOME/.config/git/ignore sẽ được sử dụng. Xem gitignore(5).

làm việc xung quanh

Tôi tin rằng xấp xỉ tốt nhất của một tập tin không bao gồm mỗi chi nhánh được thực hiện bằng cách sử dụng thực hiện post-checkout hook và của .gitignore thông qua một liên kết tượng trưng.

Mỗi chi nhánh sẽ có, ví dụ: một thư mục .gitignores với các tệp được đặt tên theo các nhánh tương ứng. Sau đó, sẽ có một tệp .gitignores/__default sẽ được sử dụng theo mặc định. .gitignore sẽ bị loại trừ bởi tất cả các tệp loại trừ và sẽ được tạo bởi móc hậu kiểm xuất dưới dạng liên kết tượng trưng đến tệp tương ứng trong .gitignores.

Nếu bạn không muốn theo dõi các tập tin không bao gồm, bạn có thể làm tương tự với tập tin .git/info/exclude như một liên kết tượng trưng đến .git/info/excludes/__default, vv

+0

Nếu bạn muốn biết thêm thông tin về công việc xung quanh, hãy ping cho tôi qua @Palec trong phần bình luận ở đây. – Palec

+0

ha cảm ơn - tôi vừa đọc xong toàn bộ http://git-scm.com/docs/git-config (!) Và đã tự hỏi tại sao tôi không nhìn thấy một branch.excludesfile - tôi sẽ kiểm tra công việc của bạn- xung quanh. – goredwards

+0

Tôi đã kiểm tra lịch sử của git-config và gitignore manpages và họ không bao giờ đề cập đến 'branch. .excludesfile'. – Palec

1

Dưới đây là một kịch bản tôi đã viết để làm điều này:

#!/bin/bash                  

# This is designed to allow per-branch un-ignoring of certain files. 
# Use case: Compiled CSS files on master to push to server. 
# A special .gitignore file will be present on master at 
# {$gitignorePath}/{$disabledMasterGitignoreName} and that file should 
# enable the css files using the ! flag. @https://git-scm.com/docs/gitignore 

# When the branch specified by script parameters 
# is checked out, {$gitignorePath}/{$disabledMasterGitignoreName} is 
# copied to .gitignore. 
# On other branches this gitignore file is named $disabledMasterGitignoreName, versioned, 
# and {$gitignorePath}.gitignore will be deleted. Note, you must ignore 
# {$gitignorePath}.gitignore from your main .gitignore file 
# 
# To enable put this file in your path and call this script 
# in .git/hooks/post-checkout with pass a list of single-space-separated branches that 
# will enable the branch-specific .gitignore. 

# One caveat is that you can only merge into the branch containing the .gitignore 
# file. Otherwise you'll end up re-committing the files. This is fine if you are 
# using gitflow and `master` contains your special .gitigore using the ! syntax 
# that is un-ignoring files. 
# 
# Background: @http://stackoverflow.com/questions/29579546/git-excludesfile-for-a-branch 

set -e                   

gitignorePath='docroot/sites/all/themes' 
disabledMasterGitignoreName='.gitignore_master--disabled' 
#branchWithGitignoreEnabled='master' 

branch=$(git rev-parse --abbrev-ref HEAD) 

gitignoreRoot="$(git rev-parse --show-toplevel)/${gitignorePath}" 

if [ -f "${gitignorePath}/.gitignore" ] 
then 
    masterGitignoreExists=true 
fi 

if [ -f "${gitignorePath}/${disabledMasterGitignoreName}" ] 
then 
    disabledMasterGitignoreExists=true 
fi 

IFS=' ' read -a params <<< "[email protected]" 

if [[ " ${params[@]} " =~ " ${branch} " ]] 
then 
    if [ $disabledMasterGitignoreExists ] 
    then 
    cp -f "${gitignoreRoot}/${disabledMasterGitignoreName}" "${gitignoreRoot}/.gitignore" 
    echo "Enabled ${gitignorePath}/.gitignore" 
    fi 
elif [ $masterGitignoreExists ] 
then 
    rm -f "${gitignorePath}/.gitignore" 
    if [ masterGitignoreExists ] 
    then 
     echo "Disabled ${gitignorePath}/.gitignore" 
    fi 
fi 
Các vấn đề liên quan