web-dev-qa-db-ja.com

ブランチのGit excludesfile

他のブランチとのマージ中に上書きされる追跡された.gitignoreファイルに依存せずに、ブランチ内の特定のファイルを無視したい。

私は Stack Overflowの回答リンクされたブログ投稿 を厳密にフォローしましたが、私のリポジトリは指定されたexcludesfileを認識していません.git/config。 Gitのドキュメント( git-configgitignore )は、特定のブランチの除外ファイルを指定して対処する方法を示していないようです。

私の.git/configは次のようになります:

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

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

私の.git/info/excludeファイルは次のようになります(デフォルトでは、触れませんでした):

# 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

「特別支店」に.gitignoreファイルがありません。

info.phpのようなファイルを無視しようとすると、.git/info/exclude_specialbranchファイルは次のようになります。

info.php

…しかし、ファイルは無視されません。

git status --ignoredを実行すると、デフォルトのexcludeファイルの.DS_Storeファイルのみがリストされます。

ただし、info.php.git/info/excludeファイルに追加した場合:

# 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

ファイルは完全に無視されます。

excludesfile = +/info/exclude[core]の下に.git/configという行がなくても機能することに注意してください。 Gitはシステム全体のexcludeがどこにあるかを私に知らせずに知っているようです。

.git/configがカスタム除外ファイルのアドレスを認識していないようです。

excludesfile = +/info/exclude_specialbranch

+を使用して.gitディレクトリの場所を説明している可能性があります。

Gitの(より新しい)バージョンでカスタム除外ファイルに対処するための正しい方法は何ですか?

OSX 10.9.5とGitバージョン2.2.1を実行しています。

20
goredwards

Gitはブランチごとの除外ファイルをサポートしていません

Gitがサポートしていないものを達成しようとしている。 ブログ投稿 は、このデマの元のソースです Stack Overflow answer オウムのみ。その回答の下のコメントに記載されているように、元のブログ投稿でさえ、ソリューションが機能しないことを示す議論が含まれており、それは 新しいブログ投稿 にリンクしています。動作。

なぜ機能しないのですか? man gitignoreman git-config を読んだ場合、参照されているのはcore.excludesfileだけです。 branch.<name>.excludesfileはありません。 core.excludesfileは、たとえば、 Vimの.swpファイルまたはソフトウェアが使用するその他の一時的なもの。

core.excludesfile

.gitignore(ディレクトリごと)と.git/info/excludeに加えて、Gitはこのファイルを調べて、追跡対象ではないファイルのパターンを探します。 「~/」は$HOMEの値に展開され、「~user/」は指定されたユーザーのホームディレクトリに展開されます。デフォルト値は$XDG_CONFIG_HOME/git/ignoreです。 $XDG_CONFIG_HOMEが設定されていないか空の場合、代わりに$HOME/.config/git/ignoreが使用されます。 gitignore(5) を参照してください。

回避策

ブランチごとの除外ファイルの最良の近似は post-checkoutフック を使用して達成され、シンボリックリンクを介して.gitignoreを実現すると私は信じています。

各ブランチには、たとえば対応するブランチにちなんで名付けられたファイルを含む.gitignoresディレクトリ。次に、デフォルトで使用される.gitignores/__defaultファイルがあります。 .gitignoreはすべての除外ファイルによって除外され、チェックアウト後のフックによって.gitignoresの対応するファイルへのシンボリックリンクとして作成されます。

除外ファイルを追跡したくない場合は、.git/info/excludeファイルを.git/info/excludes/__defaultへのシンボリックリンクとして使用して、同様に行うことができます。

28
Palec

これを行うために私が書いたスクリプトは次のとおりです。

#!/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 <<< "$@"

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
2
Jeremy John