Чи можна мати власний .gitignore? Доступ лише для читання?


79

Я працюю в командному середовищі, і .gitignoreфайл вже є .

Я хочу додати до .gitignoreфайлу більше елементів , але я не хочу перевіряти цей файл ні в одному. Можна встановити власні файли ігнорування, які стосуються лише мене?

Крім того, я хочу надати комусь доступ лише для читання до приватного сховища git на нашому сервері, якщо я додам свій ключ SSH на наш сервер, вони отримають повний доступ, як і всі інші. Як я можу обмежити його лише для читання, жодні коміти не дозволяються.


Відповіді:


122
  1. Введіть свої приватні правила ігнорування .git/info/exclude. Див gitignore(5).
  2. Для доступу тільки для читання, використання git-daemon, на веб - сервері , або Gitosis або Gitolite.

а щоб погіршити ситуацію, я хочу, щоб цей gitignore був для конкретного проекту, а не глобальної обстановки.
Blankman

7
@Blankman: помістіть це в .git/info/exclude кореневу директорію проекту .
Fred Foo

1
Зробіть це повним: за допомогою опції конфігурації core.excludesfileви можете вказати глобальний файл виключення.
KingCrunch

1
Для будь-якої нової установки, я погоджуюсь із Саймоном, вам слід використовувати гітоліт, а не гітоз.
ebneter

1
Корисний спосіб використання: по- перше -> ln -s .git/info/exclude .personalGitignoreПотім ми можемо додати # ln -s .git/info/exclude .personalGitignore \n .personalGitignoreдо .gitignore
Josu Жени

18

Я знаю, що я трохи запізнився з розмовою, але ви можете розглянути можливість використання

git update-index --assume-unchanged [ FILE ]

Як зазначено у довідковому документі git:

Коли ввімкнено біт "припустити незмінним", git припиняє перевірку файлів робочого дерева на можливі зміни , тому вам потрібно вручну зняти біт, щоб повідомити git при зміні робочого файлу дерева ...

Акцент мій. Далі йдеться

Цей параметр можна ... використовувати як механізм грубого рівня файлу, щоб ігнорувати незмінені зміни у відстежуваних файлах (подібне до того, що робить .gitignore для невідстежених файлів). Git не вдасться (витончено) у випадку, якщо йому потрібно буде змінити цей файл в індексі, наприклад, при об'єднанні у коміті; таким чином, у випадку, якщо передбачуваний файл, що не відстежується, буде змінено вгору за течією, вам потрібно буде впоратися з ситуацією вручну .

Тож майте на увазі, що вам доведеться знати про будь-які зміни, внесені до цих файлів.

У випадку, якщо ви хочете знову розпочати відстеження файлу, все, що вам потрібно зробити, це використовувати

git update-index --no-assume-unchange [ FILE ]

Сподіваюся, це допоможе будь-яким майбутнім глядачам цього допису.



2

Як сказав Фред Фродо, ви можете розмістити свої приватні правила виключення в .git/info/excludeсховищі.

Якщо ви хочете застосувати однакові правила виключення до всіх сховищ на вашому комп'ютері, ви можете додати наступне у .gitconfigфайл у своєму каталозі користувача.

[core]       
    excludesfile = /home/<myusername>/.gitexclude 

Потім додайте свої шаблони виключення до ~/.gitexclude.


1

Вас може зацікавити гачок оновлення, який написав Хуніо і який покращив Карл. Помістіть код нижче $GIT_DIR/hooks/updateі не забудьте увімкнути його за допомогою chmod +x.

#!/bin/bash

umask 002

# If you are having trouble with this access control hook script
# you can try setting this to true.  It will tell you exactly
# why a user is being allowed/denied access.

verbose=false

# Default shell globbing messes things up downstream
GLOBIGNORE=*

function grant {
  $verbose && echo >&2 "-Grant-     $1"
  echo grant
  exit 0
}

function deny {
  $verbose && echo >&2 "-Deny-      $1"
  echo deny
  exit 1
}

function info {
  $verbose && echo >&2 "-Info-      $1"
}

# Implement generic branch and tag policies.
# - Tags should not be updated once created.
# - Branches should only be fast-forwarded unless their pattern starts with '+'
case "$1" in
  refs/tags/*)
    git rev-parse --verify -q "$1" &&
    deny >/dev/null "You can't overwrite an existing tag"
    ;;
  refs/heads/*)
    # No rebasing or rewinding
    if expr "$2" : '0*$' >/dev/null; then
      info "The branch '$1' is new..."
    else
      # updating -- make sure it is a fast-forward
      mb=$(git-merge-base "$2" "$3")
      case "$mb,$2" in
        "$2,$mb") info "Update is fast-forward" ;;
    *)    noff=y; info "This is not a fast-forward update.";;
      esac
    fi
    ;;
  *)
    deny >/dev/null \
    "Branch is not under refs/heads or refs/tags.  What are you trying to do?"
    ;;
esac

# Implement per-branch controls based on username
allowed_users_file=$GIT_DIR/info/allowed-users
username=$(id -u -n)
info "The user is: '$username'"

if test -f "$allowed_users_file"
then
  rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |
    while read heads user_patterns
    do
      # does this rule apply to us?
      head_pattern=${heads#+}
      matchlen=$(expr "$1" : "${head_pattern#+}")
      test "$matchlen" = ${#1} || continue

      # if non-ff, $heads must be with the '+' prefix
      test -n "$noff" &&
      test "$head_pattern" = "$heads" && continue

      info "Found matching head pattern: '$head_pattern'"
      for user_pattern in $user_patterns; do
    info "Checking user: '$username' against pattern: '$user_pattern'"
    matchlen=$(expr "$username" : "$user_pattern")
    if test "$matchlen" = "${#username}"
    then
      grant "Allowing user: '$username' with pattern: '$user_pattern'"
    fi
      done
      deny "The user is not in the access list for this branch"
    done
  )
  case "$rc" in
    grant) grant >/dev/null "Granting access based on $allowed_users_file" ;;
    deny)  deny  >/dev/null "Denying  access based on $allowed_users_file" ;;
    *) ;;
  esac
fi

allowed_groups_file=$GIT_DIR/info/allowed-groups
groups=$(id -G -n)
info "The user belongs to the following groups:"
info "'$groups'"

if test -f "$allowed_groups_file"
then
  rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |
    while read heads group_patterns
    do
      # does this rule apply to us?
      head_pattern=${heads#+}
      matchlen=$(expr "$1" : "${head_pattern#+}")
      test "$matchlen" = ${#1} || continue

      # if non-ff, $heads must be with the '+' prefix
      test -n "$noff" &&
      test "$head_pattern" = "$heads" && continue

      info "Found matching head pattern: '$head_pattern'"
      for group_pattern in $group_patterns; do
    for groupname in $groups; do
      info "Checking group: '$groupname' against pattern: '$group_pattern'"
      matchlen=$(expr "$groupname" : "$group_pattern")
      if test "$matchlen" = "${#groupname}"
      then
        grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
      fi
        done
      done
      deny "None of the user's groups are in the access list for this branch"
    done
  )
  case "$rc" in
    grant) grant >/dev/null "Granting access based on $allowed_groups_file" ;;
    deny)  deny  >/dev/null "Denying  access based on $allowed_groups_file" ;;
    *) ;;
  esac
fi

deny >/dev/null "There are no more rules to check.  Denying access"

За допомогою цього гачка ви надаєте певним користувачам чи групам можливість вносити зміни до сховища. Будь-хто, хто може бачити його, має доступ лише для читання.

Для цього використовуються два файли $GIT_DIR/info/allowed-usersі allowed-groups, щоб описати, в які голови хто може заштовхнути. Формат кожного файлу буде виглядати так:

refs/heads/master  junio
+refs/heads/pu     junio
refs/heads/cogito$ pasky
refs/heads/bw/.*   linus
refs/heads/tmp/.*  .*
refs/tags/v[0-9].* junio

При цьому, Лінус може штовхати або створювати bw/penguinабо bw/zebraабо bw/pandaгілку, Pasky може зробити тільки cogito, і JC може зробити masterі puгілка і зробити версіровани тег. І будь-хто може робити tmp/blahгілки. Знак "+" на puзаписі означає, що JC може робити нешвидкі натискання на нього вперед.

Якщо ця особа ще не має доступу до хосту, де живе ваше сховище, можливо, ця особа повинна мати лише git-shellдоступ, а не необмежений доступ. Створіть спеціального користувача git та ~git/.ssh/authorized_keysдодайте сторонній SSH-ключ у наступну форму. Зверніть увагу, що ключ повинен знаходитися на одному довгому рядку, але я обернув його нижче, щоб допомогти презентації.

no-agent-forwarding, no-port-forwarding, no-pty, no-X11-forwarding,
command = "env myorg_git_user = joeuser / usr / local / bin / git-shell -c
\ "$ {SSH_ORIGINAL_COMMAND: -} \" "ssh-rsa AAAAB3 ... 2iQ == joeuser@foo.invalid

Залежно від локальних налаштувань, можливо, вам доведеться відкоригувати шлях до git-shell. Пам'ятайте, що sshdце дуже параноїчно щодо дозволів .sshкаталогу, тому вимкніть його біти для групового запису та всі файли під ним.

Спрямування всіх через користувача git означає, що ви повинні вміти розрізняти людей, і в цьому полягає myorg_git_userзмінна середовища. Замість того, щоб покладатися на безумовний username=$(id -u -n), налаштуйте гачок оновлення, щоб використовувати його:

# Implement per-branch controls based on username
allowed_users_file=$GIT_DIR/info/allowed-users
if [ -z "$myorg_git_user" ]; then
  username=$(id -u -n)
else
  username=$myorg_git_user
fi
info "The user is: '$username'"

За допомогою цього налаштування ваш друг із доступом лише для читання клонуватиме команду, схожу на наведену нижче. Конкретний шлях залежатиме від ваших налаштувань. Щоб приємний шлях працював, перенесіть своє сховище в домашній каталог користувача git або створіть символічне посилання, яке вказує на нього.

$ git клон git@blankman.com.invalid: coolproject.git

але не зможе робити оновлення.

$ git push походження mybranch 
Всього 0 (дельта 0), повторно використане 0 (дельта 0)
віддалений: помилка: хук відхилений для оновлення refs / heads / mybranch
На адресу git@blankman.com.invalid: coolproject.git
 ! [віддалено відхилено] mybranch -> mybranch (гачок відхилено)
помилка: не вдалося висунути деякі посилання на 'git@blankman.com.invalid: coolproject.git'

Ви сказали, що працюєте в командному середовищі, тому я припускаю, що ваше центральне сховище було створено за допомогою цієї --sharedопції. (Див core.sharedRepositoryв git configдокументації і --sharedв git initдокументації .) Переконайтеся , що новий користувач мерзотника є членом групи систем , яка дає всім вам доступ до вашого центральному сховищу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.