git: symlink/reference to a file in an external repository

Git has features that you can use to achieve what you need. It supports file system symlinks and it supports submodules. Submodules is already a standard way to handle references to other repositories. You can use them in conjunction with a way to reference files locally. That can be handled directly using relative symbolic links or indirectly using a script that copies over files from the submodule to where you need them.

You should have one submodule per external git tree and you should treat the submodules with care, as they are not only links to external repositories but also to their specific commits. The following to solutions will show you how to use individual files from an external repostiory but still maintain all the advantages of submodules.

An alternative way is to fetch the files directly but then you will lose the advantage of submodules entirely or you will have to build the features yourself. As I already stated, submodules are the standard way to handle this sort of task and you should use it unless you have special needs like to avoid downloading other files at all cost.

Using a submodule and a symlink

Once you have a submodule ready, you can just add filesystem symlinks pointing into the submodule directory structure.

Run this in a shell in your project directory:

$ 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"

Now you have a symlink:

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

Using a submodule and a script

As an alternative, you can use custom scripts that copy over ordinary files from your submodules. In very special cases you could handle the external repositories from the script without submodules but I would normally not recommend it.

Create a file bootstrap.sh containing:

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

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

Run this in a shell in your project directory:

$ 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"

Note that we are not adding the logback.xml file to Git, as it will be fetched from the submodule.

Instruct users of the repository to first run the script above. It will prepare their repositories for using submodules, will fetch the submodule data and will copy the file to its location. Sometimes there’s already some sort of bootstrap script in the project.

Using a script to fetch a single file via git protocol

Found another solution for Git >= 1.7.9.5 using git archive.

Create a file bootstrap.sh containing:

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

Run this in a shell in your project directory:

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

Using a script to fetch a single file via HTTP

If the repository hosting service also serves the individual files via HTTP, you can simply use curl or wget to download them.

Create a file bootstrap.sh containing:

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

Run this in a shell in your project directory:

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

Notes on scripts fetching single files

You could also store the references in files with a specific extention (like *.url) or maintain the list of references in one file (like .references in your project directory) and build a more comprehensive script that goes through all the references and downloads the respective files.

Leave a Comment