Git: symlink/ссылка на файл во внешнем репозитории

Возможно ли в git иметь ссылку на конкретный файл в репозитории git? Как то, что git подмодули делают для папок, но мой вопрос касается определенного файла, а не полного каталога:

my-project/
    class1.java
    class2.java
    logback.xml (link to a particular file, say https://github.com/theHilikus/JRoboCom/blob/master/jrobocom-core/src/main/resources/logback.xml)

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

В качестве примечания это не имеет ничего общего с символическими ссылками файловой системы; Я говорю о ссылке на файл в другом проекте, репо, ветке или что-то еще. это нормально, если содержимое файла является дубликатом, а не символической файловой системой

Ответы

Ответ 1

Git имеет функции, которые вы можете использовать для достижения того, что вам нужно. Он поддерживает символические ссылки файловой системы и поддерживает подмодули. Субмодули уже являются стандартным способом обработки ссылок на другие репозитории. Вы можете использовать их вместе со способом локального обращения к файлам. Это можно обрабатывать напрямую, используя относительные символические ссылки или косвенно используя script, который копирует файлы из подмодуля туда, где они вам нужны.

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

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

Использование подмодуля и символической ссылки

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

Запустите это в оболочке в каталоге проекта:

$ git submodule add https://github.com/theHilikus/JRoboCom
$ ln -s JRoboCom/jrobocom-core/src/main/resources/logback.xml
$ git add .gitmodules logback.xml
$ git commit -m "add a symbolic link to logback.xml with the respective submodule"

Теперь у вас есть символическая ссылка:

logback.xml -> JRoboCom/jrobocom-core/src/main/resources/logback.xml

Используя подмодуль и a script

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

Создайте файл bootstrap.sh, содержащий:

#!/bin/sh
git submodule init
git submodule update

cp JRoboCom/jrobocom-core/src/main/resources/logback.xml .

Запустите это в оболочке в каталоге проекта:

$ git submodule add https://github.com/theHilikus/JRoboCom
$ git add .gitmodules bootstrap.sh
$ git commit -m "add a script to fetch logback.xml from the respective submodule"

Обратите внимание, что мы не добавляем файл logback.xml к Git, так как он будет извлечен из подмодуля.

Попросите пользователей репозитория сначала запустить script выше. Он подготовит свои репозитории для использования подмодулей, выберет данные подмодуля и скопирует файл в его местоположение. Иногда в проекте уже есть какой-то загрузочный файл script.

Использование script для извлечения одного файла через протокол git

Нашел другое решение для git >= 1.7.9.5, используя git archive.

Создайте файл bootstrap.sh, содержащий:

#!/bin/sh
git archive --remote=https://github.com/theHilikus/JRoboCom master:JRoboCom/jrobocom-core/src/main/resources logback.xml | tar -x

Запустите это в оболочке в каталоге проекта:

$ git add bootstrap.sh
$ git commit -m "add a script to fetch logback.xml directly from the remote project"

Использование script для извлечения одного файла через HTTP

Если служба хостинга репозитория также обслуживает отдельные файлы через HTTP, вы можете просто использовать curl или wget для их загрузки.

Создайте файл bootstrap.sh, содержащий:

#!/bin/sh
curl -O https://raw.githubusercontent.com/theHilikus/JRoboCom/master/jrobocom-core/src/main/resources/logback.xml

Запустите это в оболочке в каталоге проекта:

$ git add bootstrap.sh
$ git commit -m "add a script to fetch logback.xml directly from github"

Заметки о загрузке отдельных файлов

Вы также можете сохранить ссылки в файлах с определенным расширением (например, *.url) или сохранить список ссылок в одном файле (например, .references в каталоге проекта) и создать более полный script, который будет через все ссылки и загружает соответствующие файлы.

Ответ 2

Принятый ответ кажется вводящим в заблуждение, так как Git может обрабатывать символические ссылки просто отлично, пока операционная система, используемая всеми разработчиками, поддерживает их.

Git по умолчанию пытается сохранить символические ссылки, а не следовать им (для компактности и, как правило, того, что люди хотят).

Когда вы проверяете дерево, содержащее ссылку, оно восстанавливает объект как символическую ссылку, независимо от того, существует ли объект целевой файловой системы или нет.

Если вы используете файловую систему, такую ​​как FAT, которая не поддерживает символические ссылки, а ваш репозиторий использует их, вы можете установить переменную конфигурации core.symlinks в false, а символические ссылки будут проверяться как небольшие текстовые файлы, содержащие текст ссылки.

SO Ссылки:

Как git обрабатывать символические ссылки?

Git - как обращаться с символическими ссылками

Как я могу заставить git следовать символическим ссылкам?

Ответ 3

К сожалению, нет. Единственный тип внешней ссылки, которую вы можете иметь в git, - это подмодули, которые помещают всю ветвь в каталог. Вам нужно будет создать script или что-то, что поможет извлечь файл из нужного места и поместить его в рабочее дерево.