{"id":39798068,"url":"https://github.com/mulle-sde/mulle-fetch","last_synced_at":"2026-01-18T12:26:49.325Z","repository":{"id":139651402,"uuid":"116178353","full_name":"mulle-sde/mulle-fetch","owner":"mulle-sde","description":" 🏃🏿 Download and unpack repositories or archives ","archived":false,"fork":false,"pushed_at":"2025-04-27T21:36:26.000Z","size":1062,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-27T22:26:33.475Z","etag":null,"topics":["bash","command-line-tool","curl","git","mirroring","mulle-sde","tar","unpack-repositories","zip"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mulle-sde.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-01-03T20:20:55.000Z","updated_at":"2025-01-23T10:39:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"7610eb4a-235d-4382-bd9e-e7f37ce590b1","html_url":"https://github.com/mulle-sde/mulle-fetch","commit_stats":null,"previous_names":[],"tags_count":74,"template":false,"template_full_name":null,"purl":"pkg:github/mulle-sde/mulle-fetch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-fetch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-fetch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-fetch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-fetch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mulle-sde","download_url":"https://codeload.github.com/mulle-sde/mulle-fetch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mulle-sde%2Fmulle-fetch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28536002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T10:13:46.436Z","status":"ssl_error","status_checked_at":"2026-01-18T10:13:11.045Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","command-line-tool","curl","git","mirroring","mulle-sde","tar","unpack-repositories","zip"],"created_at":"2026-01-18T12:26:49.235Z","updated_at":"2026-01-18T12:26:49.312Z","avatar_url":"https://github.com/mulle-sde.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🏃🏿 Download and unpack source repositories or archives\n\n... for Android, BSDs, Linux, macOS, SunOS, Windows (MinGW, WSL)\n\nDownloads [zip](http://eab.abime.net/showthread.php?t=5025) and\n[tar](http://www.grumpynerd.com/?p=132) archives.\nClones [git](//enux.pl/article/en/2014-01-21/why-git-sucks) repositories and it\ncan also checkout [svn](//andreasjacobsen.com/2008/10/26/subversion-sucks-get-over-it/).\nCan search for and symlink local projects in favor over fetching \"stuff\".\n\n![GIF](opti.gif)\n\n| Release Version                                       | Release Notes\n|-------------------------------------------------------|--------------\n| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-sde/mulle-fetch.svg)  | [RELEASENOTES](RELEASENOTES.md) |\n\n\n\n\n\n## What mulle-fetch does\n\nEssentially, `mulle-fetch` is a shortcut for:\n\n``` sh\ncurl -o download.tgz ${URL}\ntar xfz download.tgz\nmv download \"${DST}\"\n```\n\nOne invariably specifies the **url** to download from and the **destination**\ndirectory to download to. The destination directory must not exist yet.\n\n\n#### Download and unpack a tar archive:\n\nHere the version is specified in the URL\n\n``` sh\nmulle-fetch fetch -s tar https://github.com/mulle-nat/mulle-c11/archive/1.3.5.tar.gz mulle-c11\n```\n\n\n#### Clone a git repository:\n\nUse a tag to checkout a specific version:\n\n``` sh\nmulle-fetch fetch -t '1.3.5' https://github.com/mulle-nat/mulle-c11.git mulle-c11\n```\n\n#### Or even more convenient:\n\nmulle-fetch can often guess the correct type and project-name of an URL. Just\ngive it the URL and let the magic happen:\n\n``` sh\nmulle-fetch https://github.com/mulle-nat/mulle-c11/archive/1.3.5.tar.gz\n```\n\n\n## Reduce bandwidth\n\n\nA typical setup might look like this:\n\n![](dox/mulle-fetch-fs.svg)\n\n\n### Use a mirror for git repositories\n\nIf you clone certain (git) repositories often, it can be useful to use a mirror\nto lighten the bandwidth load with `--mirror-dir`:\n\n``` sh\nmulle-fetch fetch --mirror-dir ~/.cache/mulle-fetch/git-mirror/ \\\n   https://github.com/mulle-nat/mulle-c11.git mulle-c11\n```\n\nThis will still create network connections to update the mirror. If you don't\nwant that to happen, when a repository has a mirror use the `--no-refresh`\noption.\n\n``` sh\nmulle-fetch fetch --no-refresh --mirror-dir ~/.cache/mulle-fetch/git-mirror/ \\\n   https://github.com/mulle-nat/mulle-c11.git mulle-c11\n```\n\n\u003e You can also set the environment variable `MULLE_FETCH_MIRROR_DIR`.\n\n\n### Use a cache for archives\n\nIf you download archives often, it can be useful to cache them, to lighten the\nbandwidth load with `--cache-dir`:\n\n```\nmulle-fetch fetch --cache-dir ~/.cache/mulle-fetch/archive \\\n   https://github.com/mulle-nat/mulle-c11/archive/1.3.5.tar.gz mulle-c11\n```\n\n\u003e You can also set the environment variable `MULLE_FETCH_ARCHIVE_DIR`.\n\n\n### Use a search path for local repositories\n\nBefore actually cloning or checking out a repository, you can let\n**mulle-fetch** search through some local directories to find a matching\nrepository. This is an alternative to mirroring and especially useful for\nrepositories that are only locally available.\n\nIn the next example the option `--search-path` instructs **mulle-fetch** to\nlook for a repository named `mulle-c11` in `${HOME}/src` and\nthen in `/usr/local/src`. If nothing is found the repository is cloned from\n`https://github.com/mulle-nat/mulle-c11.git`:\n\n``` sh\nmulle-fetch fetch --search-path ${HOME}/src:/usr/local/src \\\n   https://github.com/mulle-nat/mulle-c11.git mulle-c11\n```\n\n\u003e You can also set the environment variable `MULLE_FETCH_SEARCH_PATH`.\n\n### Create symbolic links to local projects\n\n\u003e Symbolic links are not available on mingw.\n\nIt may be inconvenient to clone a local project repository, when its\ndevelopment is still ongoing. You'd have to sync the clone to often.\nYou can allow **mulle-fetch** with `--symlink` to install a symlink instead with:\n\n``` sh\nmulle-fetch fetch --symlink --search-path ${HOME}/src:/usr/local/src \\\n   https://github.com/mulle-nat/mulle-c11.git mulle-c11\n```\n\nSince one is not actually cloning anything the found project directory, does\nnot need to be under version control.\n\n\n\n### Search for best matching URL\n\nFor github archives and repositories you can search for the best fitting\nrelease archive with a special \"tag filter\" syntax, that expresses version\nranges. For this to work the releases must be tagged in [semantic versioning]\nstyle.\n\nFor example '\u003e= 1.0.0 AND \u003c 2.0.0' would get you the latest version 1. A tag\nfilter is of the form\n\n| Filter                      | Description\n|-----------------------------|-------------------\n| 'newest:' \u0026lt;qualifier\u0026gt; | Use the newest compatible version\n| 'oldest:' \u0026lt;qualifier\u0026gt; | Use the oldest compatible version\n| \u0026lt;qualifier\u0026gt;           | same as `newest:`, just shorter\n\n\n| Qualifier                 | Description\n|---------------------------|-----------------------\n| \u0026lt;unary qualifier\u0026gt;   | These qualifiers compare the github version with your value\n| \u0026lt;binary qualifier\u0026gt;  | Boolean logic AND and OR\n| `(` \u0026lt;qualifier\u0026gt; `)` | As there is no precedence, use parentheses to express it\n\n\n| Unary Qualifier      | Example\n|----------------------|-------------\n| `\u003e=` \u0026lt;version\u0026gt; | `\u003e= 1.0.0`  of [ 0.0.0, 1.0.0, 2.0.0 ] gives 2.0.0\n| `\u003c=` \u0026lt;version\u0026gt; | `\u003c= 1.0.0`  of [ 0.0.0, 1.0.0, 2.0.0 ] gives 1.0.0\n| `\u003c`  \u0026lt;version\u0026gt; | `\u003c 1.0.0`   of [ 0.0.0, 1.0.0, 2.0.0 ] gives 0.0.0\n| `\u003e`  \u0026lt;version\u0026gt; | `\u003e 1.0.0`   of [ 0.0.0, 1.0.0, 2.0.0 ] gives 2.0.0\n| `!=` \u0026lt;version\u0026gt; | `!= 1.0.0`  of [ 0.0.0, 1.0.0, 2.0.0 ] gives 2.0.0\n| `==`  \u0026lt;version\u0026gt;| `== 1.0.0`  of [ 0.0.0, 1.0.0, 2.0.0 ] gives 1.0.0\n| \u0026lt;version\u0026gt;      | same as `==`\n\n\n| Binary Qualifier                          | Example\n|-------------------------------------------|-----------------\n| \u0026lt;qualifier\u0026gt; `AND` \u0026lt;qualifier\u0026gt; | `\u003e= 1.0.0 AND \u003c 2.0.0`  of [ 0.0.0, 1.0.0, 2.0.0 ] gives 1.0.0\n| \u0026lt;qualifier\u0026gt; `OR` \u0026lt;qualifier\u0026gt;  | `\u003e= 1.0.0 OR == 0.0.0` of [ 0.0.0, 1.0.0, 2.0.0 ] gives 0.0.0\n\n\n| Version                  | Description\n|--------------------------|-------------------------------------------\n| [0-9]+'.'[0-9]+'.'[0-9]+ | A version is a semantic versioning triple\n\n\n### Examples\n\nUse version 3.2.x or better up to but not including version 3.3:\n\n``` sh\nmulle-fetch url \\\n      --scm tar \\\n   '\u003e= 3.2.0 AND \u003c 3.3.0' \\\n   https://github.com/mulle-c/mulle-c11\n```\n\nUse version 1 or better up, but skip known problem versions 1.0.2 and 1.0.3\n\n\n``` sh\nmulle-fetch url \\\n      --scm zip \\\n   '\u003e= 1.0.0 AND != 1.0.2 AND != 1.0.3' \\\n   https://github.com/mulle-c/mulle-allocator\n```\n\n\n\n\n\n\n\n## Install\n\nSee [mulle-sde-developer](//github.com/mulle-sde/mulle-sde-developer) how to\ninstall mulle-sde, which will also install mulle-fetch with required\ndependencies.\n\nThe command to install only the latest mulle-fetch into\n`/usr/local` (with **sudo**) is:\n\n``` bash\ncurl -L 'https://github.com/mulle-sde/mulle-fetch/archive/latest.tar.gz' \\\n | tar xfz - \u0026\u0026 cd 'mulle-fetch-latest' \u0026\u0026 sudo ./bin/installer /usr/local\n```\n\n\n\n## Author\n\n[Nat!](https://mulle-kybernetik.com/weblog) for Mulle kybernetiK\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmulle-sde%2Fmulle-fetch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmulle-sde%2Fmulle-fetch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmulle-sde%2Fmulle-fetch/lists"}