2015-02-14 2 views
3

Я новичок в git, страдающий от предыдущего опыта svn. Многие из моих проектов используют код из моих собственных библиотек, поэтому, естественно, я хочу использовать некоторые функции «externals-like» от git. В настоящее время я пытаюсь использовать подмодули.Создание файлов в подмодулях только для чтения

Но подмодули (насколько я понимаю) могут обеспечить большую боль, если вы используете их неправильно (например, смените файлы в подмодуле и забудьте нажать их или забыть их совершить).

Что делать, если я делаю все файлы в подмодулях только для чтения? Это достаточно хорошая защита от случайных изменений. И если я действительно хочу что-то изменить, я должен пойти и внести изменения в исходное репо.

Итак, мой вопрос:

  1. Это хорошая идея, или я пытаюсь изобретать колесо?
  2. Что это самый простой способ сделать это?

EDIT: Я надеюсь, что это может быть достигнуто с помощью git-крючков, но я не уверен, как именно. Я не могу использовать клиентские крючки при клонировании репо в первый раз, могу ли я?

EDIT2: С помощью SRobertz я смог придумать после оформления заказа крючка:

echo "you just checked out: $*" 
echo "submodules:" 
for p in `grep path .gitmodules | sed 's/.*= //'`; do # get submodules list 
    echo "making submodule directory $p read-only" 
    chmod -R a-w $p; 
    SAVEIFS=$IFS 
    IFS=$(echo -en "\n\b") #set delimeter to \n\b to handle whitespaces in filenames 
    for f in `ls $p`; do #get files in submodule dir 
     echo "making file $f in directory $p read-only" 
     chmod -R a-w $p\\$f; 
    done 
    IFS=$SAVEIFS #restore delimeter to default value 
done 

Теперь проблема заключается в том, что при клонировании нового репо, этот крючок срабатывает слишком рано, когда подмодуль каталогов уже созданы, но файлы в них еще не вытащены.

+0

Я думаю, что самый простой способ сделать это - это то, что вы предложили: не редактировать файлы в подмодулях; просто отредактируйте исходный репозиторий, а затем обновите свои подмодули. Я бы не стал пытаться делать вещи только для чтения. Просто не редактируйте их. – larsks

+0

Я действительно их редактировал случайно. Также я работаю с некоторыми людьми, которые могут игнорировать предупреждения от git. Таким образом, делать файлы readonly были бы удобными. – Amomum

+0

Клики на стороне клиента являются клиентскими, поэтому каждый пользователь должен их настроить. Но вы можете автоматизировать/пакет. См. Например, http://stackoverflow.com/questions/427207/can-git-hook-scripts-be-managed-along-with-the-repository, http://stackoverflow.com/questions/3462955/putting- ГИТ-крюки-в-хранилище. Некоторое обсуждение вопроса о том, почему вы должны установить крючки на стороне клиента: http://git.661346.n2.nabble.com/Is-there-any-way-to-make-hooks-part-of-the-repository-td7518033 .html | Но если у вас есть пользователи, которые «могут игнорировать предупреждения от git», подмодули могут быть не для вас, поскольку для этого требуется дисциплина, а также для обновления. – drRobertz

ответ

1

Если вы хотите svn-подобные внешние, вы можете захотеть посмотреть на giternal, https://github.com/patmaddox/giternal, либо использовать как есть, либо как отправную точку. Он написан в рубине и должен быть довольно легко адаптироваться к тому, что вы хотите, если команда freeze не совсем то, что вы хотите (чего, возможно, нет).

Краткое введение: http://www.rubyinside.com/giternal-easy-git-external-dependency-management-1322.html

Более длинная статья с некоторыми альтернативами в конце: https://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/

Edit: на стороне клиента крюк и его развертывания: Если вы знаете о причудах мерзавцем подмодулей и хотите использовать это (возможно, для стабильности, которую вы получаете от ссылки на конкретный коммит, а не HEAD), то это способ сделать его доступным только для чтения при клонировании или проверке.

стороне клиента крюк использовать это post-checkout и перебрать подмодулями, вдоль линий (вдохновленный List submodules in a git repository и git-clone and post-checkout hook. Я использовал Grep на .gitmodules, как это работает, прежде чем подмодуль inited.)

#!/bin/sh 
# An example post-checkout hook to make submodules read-only 

echo "you just checked out: $*" 
git submodule init 
git submodule update --recursive 
echo "submodules:" 
for p in `grep path .gitmodules | sed 's/.*= //'`; do 
    echo "making submodule directory $p read-only" 
    chmod -R a-w $p; 
done  

затем, чтобы развернуть крюк, один вариант заключается в создании каталога шаблонов для разработчиков, а затем заставить их сделать git clone --template=</your/template/dir> url-to-clone... (е, добавьте параметр --template=... в git clone, возможно, сделав это псевдоним, и каким-то образом поставить что в глобальной конфигурации каждого.

EDIT2: после обсуждения в комментариях:

Если подмодули были сделаны только для чтения, они должны быть доступны для записи перед обновлением (согласно комментариям, мерзавец на окнах делает это автоматически, но требуется на linux/macos). Чтобы сделать это на git pull, можно использовать крючок post-merge, как в следующем эскизе.

#!/bin/sh 
# An example post-merge hook to 
# 1. make submodules writable, 
# 2. init and update submodules, and 
# 3. make them read-only 

# make all (existing) submodule directories writable 
for p in `git submodule status | sed -e "s/^[+\ ][^\ ]*\ //" -e s/\ .*$//`; do 
    echo "making submodule directory $p writable" 
    chmod -R u+w $p; 
done 

echo "updating submodules:" 
git submodule init 
git submodule update --recursive 

# make all submodules read-only 
for p in `grep path .gitmodules | sed 's/.*= //'`; do 
    echo "making submodule directory $p read-only" 
    chmod -R a-w $p; 
done 

Это может быть уточнен, чтобы проверить, если подмодуль был обновлен в слиянии и обрабатывать только, что, вместо того, чтобы всегда перебирает все подмодули.

Caveat: как это взаимодействует с git pull --recurse-submodules, необходимо проверить, собираетесь ли вы его использовать.

Обратите внимание, что это инициирует и обновляет все подмодули и делает их доступными только для чтения после каждого слияния (pull).

Это, однако, не делает адрес git pull и т. Д. Внутри подмодулей. Для этого соответствующие крючки должны быть добавлены к .git/modules/*/hooks (для версий git> = 1.7.8) или <submodule>/.git/hooks (для более старых версий git).

+0

Я немного озадачен, почему клиентский крюк для использования - пост-обновление.Все, что мне удалось найти, это «Этот крюк вызывается git-receive-pack в удаленном репозитории, что происходит, когда git-push выполняется в локальном репозитории». Так это крюк, который срабатывает после толчка? Я попробовал хотя бы и не смог найти действие, которое должно его уволить. – Amomum

+0

К сожалению, это должно быть * post-checkout *. Будет редактировать. – drRobertz

+0

Вот и все! Одна проблема с вашим скриптом (по крайней мере на окнах), что создание папки только для чтения на самом деле ничего не значит; Я все еще могу изменять файлы в нем. Поэтому я должен немного изменить ваш сценарий, чтобы обратиться к этой проблеме. Однако с этой модификацией он не работает должным образом, когда клонирование - постобработка срабатывает, когда файлы субмодулей вытягиваются. Есть идеи? Я отредактирую вопрос, чтобы включить скрипт. – Amomum

Смежные вопросы