впрыскивать файлы в репозиторий git без проверки - PullRequest
3 голосов
/ 23 марта 2012

Я работаю над структурой локализации, которая управляет текстовыми ресурсами для нескольких приложений (wpf, android, ios) в библиотеке. Мы используем git как систему контроля версий для всех приложений. Теперь я хочу экспортировать эти активы прямо в git-репозиторий.

Проблема в том, что я не хочу клонировать / извлекать весь репозиторий каждый раз, когда я экспортирую ресурсы в репозитории git. На самом деле я не хочу знать ни о каких файлах, кроме этих активов. Я уже понял, что проверить подкаталоги невозможно с помощью git, но есть ли способ «внедрить» или «форсировать» эти изменения в хранилище без необходимости извлечения всех других изменений и файлов? (Примечание: ресурсы изменяются только здесь и не редактируются разработчиками напрямую) Он должен в основном игнорировать все, что происходит вне папки ресурсов. Еще одним важным моментом является то, что он не должен изменять рабочий процесс для наших разработчиков, поэтому субмодули на самом деле не вариант, так как им придется постоянно тянуть подмодуль.

Есть ли хороший способ сделать это с помощью git, кроме? Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 23 марта 2012

Можно написать сценарий, который может внедрять BLOB-объекты без необходимости извлекать рабочее дерево, если сам репозиторий доступен локально. Это не тривиально, хотя. Ранее я написал такой скрипт, который я опущу из-за его длины и недоступности для общего доступа, но в основном он включает в себя выполнение следующих команд git в цикле (перезапуск цикла в случае сбоя):

# Find the current head.
head="$(GIT_DIR="$repo" git show-ref --heads --hash master)"
# Get the current version of the file.
GIT_DIR="$repo" git cat-file blob "$head:path/to/file" >"$tmpdir/tempfile"
# [Modify the file if necessary.]
# Write the blob into the repository.
blob="$(GIT_DIR="$repo" git hash-object -w "$tmpdir/tempfile")"
# Read the tree into an index file.
GIT_INDEX_FILE="$index" GIT_DIR="$repo" git read-tree "$head"
# Add the ref of the blob into the index file.
GIT_INDEX_FILE="$index" GIT_DIR="$repo" git update-index --add \
    --cacheinfo 100644 "$blob" path/to/file
# Write the index file into the repo as a tree.
tree="$(GIT_INDEX_FILE="$index" GIT_DIR="$repo" git write-tree)"
# Write a commit to the repo.
commit="$(echo "autocommit" |GIT_DIR="$repo" git comm   it-tree "$tree" -p "$head")"
# Update the head of the repository to be the new commit.
GIT_DIR="$repo" git update-ref refs/heads/master "$commit" "$head"

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

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

2 голосов
/ 23 марта 2012

В git объект фиксации ссылается на объект дерева . Этот объект дерева затем ссылается на объекты BLOB-объектов . Каждый BLOB-объект (обычно) представляет собой файл в вашей рабочей копии.

Идентификатор коммита - это хеш объекта коммита, который содержит хэш объекта дерева, который сам содержит хэш всех BLOB-объектов.

Итак, чтобы сделать коммит, вы должны знать состояние всех BLOB-объектов в коммите . Фактически, фиксация - это моментальный снимок всей рабочей копии (технически индекс). Это означает, что вы не можете просто «игнорировать изменения вне dir X», потому что если вы это сделаете, ваш коммит создаст рабочую копию либо без этих файлов (если вы не включили их в объект дерева), либо с устаревшими копиями ( если вы проверите один раз, а затем предположите, что они не изменились, поместите устаревшие хеши в объект дерева).

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

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

Если это не удастся, вы можете сделать свои «активы» отдельным репозиторием (возможно, подмодулем git, они не требуют значительного «изменения рабочего процесса разработчиков», на самом деле). Тогда вам нужно только клонировать репозиторий «assets», чтобы совершать там коммиты.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...