0

I would like to modify the git clone command -- such that it use a local cache -- by creating a wrapper that does the following:

  1. If a repository doesn't exist in the cache, clone it.
  2. Copy it to the desired location.

But how do I parse the git clone command-line arguments to get the value of repository? It seems trivial; but I can't find a good solution.

It seems like this is due to a lack of structure in command-line arguments - some could be a switch, some could follow with a value etc. In git's case <repository> can be followed by an optional <directory> argument, so I can't always go by the last argument. It would have been great if CLI arguments are more structured like dictionary etc.

Is there a way to atleast specify the syntax specified in docs so that, I can get the repository argument automatically with tools like getopts?

Note: I use multiple tools -- Jenkins, Buildout etc., -- that downloads git repositories automatically, using the git command; so I thought a wrapper would be best solution.

There are some git specific solutions worth checking out like local git server, URL rewrites etc., as well.

1
  • 1
    How about using a git caching proxy such as Goblet instead? Commented May 22, 2021 at 15:29

2 Answers 2

1

You can loop through the arguments of the command to search for @ or https:// in the command to find the repo, then parse the URL to extract what you need

For example in Python :


import sys

if len(sys.argv) > 1:
    for i in sys.argv:
        # Do whatever you want (parsing the URL...)

4
  • Yeah thanks, something like that is worth a try.
    – Nishant
    Commented May 22, 2021 at 15:52
  • @Nishant This is actually a great idea, feel free to hook me up if you need help Commented May 22, 2021 at 15:53
  • 1
    Sure thank you :-)
    – Nishant
    Commented May 22, 2021 at 15:54
  • I made that into a bash script. Do have a look :-).
    – Nishant
    Commented May 22, 2021 at 17:57
1

I came up with a hacky script: /usr/local/bin/git that uses the idea mentioned by Nicholas. It relies on the --reference-if-able and --dissociate features available in recent versions of Git.

#!/usr/bin/env bash

# The real executable is located at /usr/local/bin/tig.

command=$1

cache=$HOME/.cache/git/repositories

if [[ ! $command == "clone" ]]; then
    /usr/local/bin/tig "$@"
    exit
fi

caching=false

for argument in "${@:2}"; do
    case $argument in
        --reference | --reference-if-able)
            caching=false
            break
            ;;
        *[email protected]:*)
            caching=true
            [[ $argument == *.git ]] && argument=${argument%.git}
            folder=$cache/$argument
            ;;
    esac
done

if $caching; then
    echo "INFO: Using cache: $folder"
    /usr/local/bin/tig clone \
        --reference-if-able "$folder" --dissociate "${@:2}"
else
    /usr/local/bin/tig "$@"
fi

Disclaimer: This is good for development uses only. The best way is to use a Git proxy server like Goblet, as suggested by Stephen.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .