{"id":13432584,"url":"https://github.com/gleich/fgh","last_synced_at":"2025-04-04T22:04:44.375Z","repository":{"id":47542994,"uuid":"295070256","full_name":"gleich/fgh","owner":"gleich","description":"📁 Automate the lifecycle and organization of your cloned GitHub repositories","archived":false,"fork":false,"pushed_at":"2025-01-04T21:44:55.000Z","size":688,"stargazers_count":144,"open_issues_count":8,"forks_count":20,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-28T21:06:25.807Z","etag":null,"topics":["cli","fgh","github","golang","organization","repositories","repository-management","repository-tools"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gleich.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2020-09-13T03:25:04.000Z","updated_at":"2025-03-18T07:53:16.000Z","dependencies_parsed_at":"2025-03-21T20:20:30.000Z","dependency_job_id":null,"html_url":"https://github.com/gleich/fgh","commit_stats":null,"previous_names":["matt-gleich/fgh"],"tags_count":38,"template":false,"template_full_name":"gleich/go_template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleich%2Ffgh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleich%2Ffgh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleich%2Ffgh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gleich%2Ffgh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gleich","download_url":"https://codeload.github.com/gleich/fgh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256110,"owners_count":20909240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cli","fgh","github","golang","organization","repositories","repository-management","repository-tools"],"created_at":"2024-07-31T02:01:13.787Z","updated_at":"2025-04-04T22:04:44.360Z","avatar_url":"https://github.com/gleich.png","language":"Go","readme":"\u003c!-- DO NOT REMOVE - contributor_list:data:start:[\"gleich\", \"cjdenio\", \"quackduck\", \"safinsingh\", \"stratosgear\", \"imgbot[bot]\"]:end --\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg alt=\"logo\" src=\"./images/Entire%20Logo.png\" height=\"250px\"\u003e\n\n  \u003ch1\u003efgh\u003c/h1\u003e\n\n  \u003cimg alt=\"GitHub release (latest by date)\" src=\"https://img.shields.io/github/v/release/gleich/fgh\"\u003e\n  \u003cimg alt=\"GitHub go.mod Go version\" src=\"https://img.shields.io/github/go-mod/go-version/gleich/fgh\"\u003e\n  \u003cbr\u003e\n  \u003cimg alt=\"build\" src=\"https://github.com/gleich/fgh/workflows/build/badge.svg\" /\u003e\n  \u003cimg alt=\"test\" src=\"https://github.com/gleich/fgh/workflows/test/badge.svg\" /\u003e\n  \u003cimg alt=\"lint\" src=\"https://github.com/gleich/fgh/workflows/lint/badge.svg\" /\u003e\n  \u003cimg alt=\"release\" src=\"https://github.com/gleich/fgh/workflows/release/badge.svg\" /\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n  \u003ci\u003e📁 Automate the lifecycle and organization of your cloned GitHub repositories\u003c/i\u003e\n\u003c/div\u003e\n\n\u003chr /\u003e\n\n## 📜 Table of Contents\n\n- [📜 Table of Contents](#-table-of-contents)\n- [👋 Getting started](#-getting-started)\n  - [🚀 Install](#-install)\n    - [🍎 macOS](#-macos)\n    - [🐧 Linux and 🖥 Windows](#-linux-and--windows)\n  - [👀 Try out `fgh`'s automation](#-try-out-fghs-automation)\n- [📟 Commands](#-commands)\n  - [🔒 `fgh login`](#-fgh-login)\n  - [⚙️ `fgh configure`](#️-fgh-configure)\n  - [☁️ `fgh clone`](#️-fgh-clone)\n    - [🔠 Keywords](#-keywords)\n  - [🚚 `fgh migrate`](#-fgh-migrate)\n  - [⬆️ `fgh update`](#️-fgh-update)\n  - [🧼 `fgh clean`](#-fgh-clean)\n  - [🗑 `fgh remove`](#-fgh-remove)\n  - [🧭 `fgh ls`](#-fgh-ls)\n  - [⬇️ `fgh pull`](#️-fgh-pull)\n  - [📊 `fgh visualize`](#-fgh-visualize)\n- [💡 Tips](#-tips)\n  - [🤝 \u003cowner/name\u003e shorthand](#-ownername-shorthand)\n  - [🏎 `fgh ls` for `cd`](#-fgh-ls-for-cd)\n  - [☑️ Autocompletion](#️-autocompletion)\n  - [🛠 `fgh`'s vscode extension](#-fghs-vscode-extension)\n  - [🔐 Cloning over SSH](#-cloning-over-ssh)\n- [🗂 Custom Structures](#-custom-structures)\n  - [📁 `structure_root`](#-structure_root)\n  - [🗂 `structure`](#-structure)\n  - [💡 Example Config](#-example-config)\n  - [🚚 Moving Repos to New Structure](#-moving-repos-to-new-structure)\n- [🙌 Contributing](#-contributing)\n- [👥 Contributors](#-contributors)\n\n## 👋 Getting started\n\nAs you begin contributing to an increasing amount of GitHub repositories, you'll soon realize the effort it takes to organize and maintain them on your machine. `fgh` aims to solve this issue through the use of a CLI (command line interface) to automate the entire lifecycle of your cloned repos, saving you time _and_ helping you scale! Below is a list of the most useful automation commands:\n\n- [`fgh clone`](#️-fgh-clone)\n- [`fgh clean`](#-fgh-clean)\n- [`fgh update`](#️-fgh-update)\n- [`fgh ls`](#-fgh-ls)\n\n### 🚀 Install\n\n#### 🍎 macOS\n\n```bash\nbrew install gleich/homebrew-tap/fgh\n```\n\n#### 🐧 Linux and 🖥 Windows\n\nYou can grab the binary from the [latest release](https://github.com/gleich/fgh/releases/latest).\n\n### 👀 Try out `fgh`'s automation\n\n[`fgh remove`](#-fgh-remove), [`fgh clean`](#-fgh-clean), [`fgh ls`](#-fgh-ls), [`fgh pull`](#-fgh-pull), and [`fgh visualize`](#-fgh-visualize) can be tried out on your current repository structure with the addition of the `-p` flag. The value for this flag is the relative root path to the folder where all your git repos live. If we had the repo structure shown below and we were running `fgh` from `~` the root folder would be `./code/`. This root folder is then passed into the command: `fgh ls -p=./code/`.\n\n```\n~\n└─ code\n   ├─ fgh\n   ├─ dots\n   ├─ turtle-site\n   └─ work\n      ├─ super-secret-code\n      └─ website\n```\n\n## 📟 Commands\n\n### 🔒 `fgh login`\n\nBefore using `fgh`, you'll need to give it access to your GitHub repos. Simply run `fgh login` to quickly get set up! fgh only uses this access to get metadata about the repo (e.g. main language, if private) and to clone the repo. fgh needs the full `repo` scope to access private repos.\n\nIf you need to use a GitHub custom access token, like a PAT, edit the secret configuration file. In Windows it is located in `~\\.fgh\\secrets.yml` and `~/.config/fgh/secrets.yml` in Linux and macOS. You should change/add the `pat` as seen below:\n\n```yaml\npat: \u003cyour token here\u003e\n```\n\n### ⚙️ `fgh configure`\n\nTo configure other settings, run `fgh configure` for an interactive configuration experience.\n\n### ☁️ `fgh clone`\n\nTo begin using `fgh`, you'll need to clone a repository, which you can do by running the following in a terminal window:\n\n```bash\nfgh clone \u003cowner/name\u003e\n```\n\n**OR**\n\n```bash\nfgh clone \u003cname\u003e # if the repo is under your account\n```\n\nAll repositories are cloned into the following structure by default:\n\n```\n~\n└─ github\n   └─ OWNER\n      └─ TYPE\n         └─ MAIN_LANGUAGE\n            └─ NAME\n```\n\n#### 🔠 Keywords\n\nThese names correspond to the following **keywords**:\n\n- `OWNER` is the owner of the repository\n- `TYPE` is the type of the repository; one of the following:\n  - `public`\n  - `private`\n  - `template`\n  - `archived`\n  - `disabled`\n  - `mirror`\n  - `fork`\n- `MAIN_LANGUAGE` is The main language that the repository contains. If no language is detected, `fgh` will just set it to `Other`\n- `NAME` is the name of the repository\n\nIf you would like to use a custom structure see the [custom structures documentation](#-custom-structures). Usage of this command is as follows:\n\n```bash\nfgh clone \u003cowner/name\u003e\n```\n\nIf we were to run `fgh clone gleich/fgh` it would be cloned to `~/github/gleich/public/Go/fgh/` by default (`~` being your home directory). Once cloned, this path will be copied to your clipboard automatically (this can be turned off with [`fgh configure`](#️-fgh-configure) or just by editing the config file directly).\n\n\u003e NOTE: On Linux machines running the X Window System, this program requires the `xclip` or `xsel` packages.\n\nThis structure can be somewhat difficult to navigate in the terminal using conventional methods such as the use of the `cd` command. Because of this, we created the [`fgh ls` command](#-fgh-ls) and a way to [use it with cd](#fgh-ls-for-cd).\n\n### 🚚 `fgh migrate`\n\nWould you like to add your existing repositories to the fgh structure? All you have to do run the following command and it will move every single git repo in that directory and all subdirectories into the structure:\n\n```bash\nfgh migrate \u003cfolder\u003e\n```\n\nAn example would be:\n\n```\nfgh migrate code\n```\n\nThis would migrate all git repos in the `./code` folder into fgh's structure.\n\n### ⬆️ `fgh update`\n\nIf any of a repository's fields are changed, such as its type, main language, owner, or name, the path to your local repository won't match.\n\nRunning `fgh update` will iterate over your local repositories and checks if any of them need updates. If they do, `fgh` will ask you if you want to move the entire repository to that new path.\n\nFor example, If I had this repository cloned and later decided to archive it, its path would change from `~/github/gleich/public/Go/fgh/` to `~/github/gleich/archived/Go/fgh/`.\n\n### 🧼 `fgh clean`\n\nWhen you run this subcommand, `fgh` will check for the following on each repository:\n\n1. Has it modified locally in a certain amount of time?\n   \u003e By default, this \"amount of time\" is 2 months. However, it can be changed with a flag! See `fgh clean --help` for more info.\n2. Has the repository been deleted on GitHub?\n\nIf either of those conditions are met, `fgh` will ask you if you would like to remove the aforementioned repository. It'll additionally show you some information about the repository itself.\n\n\u003e NOTE: This only removes the repo locally!\n\n### 🗑 `fgh remove`\n\nRemove a selected cloned repository. Usage is as follows:\n\n```bash\nfgh remove \u003cowner/name\u003e\n```\n\n### 🧭 `fgh ls`\n\nGet the path of a cloned repository. Usage is as follows:\n\n```bash\nfgh ls \u003cowner/name\u003e\n```\n\nYou may omit `owner` if you own the repository, or if there is only one cloned repository with the given `name`.\n\n### ⬇️ `fgh pull`\n\nPull all repos that don't have any non-pushed changes. Usage is as follows:\n\n```bash\nfgh pull\n```\n\n### 📊 `fgh visualize`\n\nVisualize all of the cloned repos in a table. Usage is as follows:\n\n```bash\nfgh visualize\n```\n\n## 💡 Tips\n\n### 🤝 \u003cowner/name\u003e shorthand\n\nAny command that takes `\u003cowner/name\u003e` as an argument allows you to leave off the `owner` if the repo is under your account. For example, I own this repo so I can just do\n\n```bash\nfgh clone fgh\n```\n\ninstead of\n\n```bash\nfgh clone gleich/fgh\n```\n\n### 🏎 `fgh ls` for `cd`\n\n\u003e NOTE: This only works in macOS and Linux\n\nIf you would like to easily use the output of `fgh ls` for `cd` just add the following snippet to your `~/.zshrc` or `~/.bashrc`:\n\n```bash\n# cd with fgh (https://github.com/gleich/fgh)\nfcd() { cd \"$(fgh ls \"$@\" 2\u003e/dev/null)\" || ( echo \"Failed to find repository\" \u0026\u0026 return 1; ) }\n```\n\nIf you're using Fish, add the following to your `~/.config/fish/config.fish`:\n\n```fish\nfunction fcd --wraps \"fgh ls\"\n  if ! cd (fgh ls $argv) \u003e /dev/null\n    echo \"Failed to find repository\"; return 1\n  end\nend\n```\n\nOnce you add that and reload your terminal you can simply run `fcd \u003cowner/name\u003e` instead of `fgh ls \u003cowner/name\u003e`, copying the output to your clipboard, typing `cd`, and pasting the output. Much easier!\n\n### ☑️ Autocompletion\n\nYou can add autocompletion for fgh by running one of the following commands based on your shell:\n\n| Shell        | Command                                                      |\n| ------------ | ------------------------------------------------------------ |\n| zsh          | `fgh completion zsh \u003e \"${fpath[1]}/_fgh\"`                    |\n| fish         | `fgh completion fish \u003e ~/.config/fish/completions/fgh.fish`  |\n| bash (linux) | `fgh completion bash \u003e /etc/bash_completion.d/fgh`           |\n| bash (macOS) | `fgh completion bash \u003e /usr/local/etc/bash_completion.d/fgh` |\n\n### 🛠 `fgh`'s vscode extension\n\nThanks to the great work by [@cjdenio](https://github.com/cjdenio) fgh has a [visual studio code extension](https://github.com/cjdenio/fgh-code)! You can clone, open repos, and more right from vscode.\n\n### 🔐 Cloning over SSH\n\nTo clone over SSH instead of HTTPS, simply run `fgh configure` or set `ssh: true` in your `~/.config/fgh/config.yaml`!\n\n## 🗂 Custom Structures\n\nNot a fan of the default structure used by fgh? Don't worry, you can change it without losing any of fgh's automation! Configuring custom structures takes place in the general configuration file. This file is located in `~/.config/fgh/config.yaml` on Linux or macOS and `~\\.fgh\\config.yaml` on Windows (`~` is your home directory). There are two parts to creating custom structures:\n\n### 📁 `structure_root`\n\nThis is where the structure starts relative to your home folder. Make sure you use `\\` instead of `/` if you are on Windows. By default, the `structure_root` is `github`. Below is an example of what you would put in the general config file:\n\n```yaml\nstructure_root: 'Documents/code/'\n```\n\nIf we were to run `fgh clone gleich/fgh` with the config shown above it would be cloned to `~/Documents/code/gleich/public/Go/fgh`.\n\nBy default, the home directory will be appended to the front of the path. If you like to turn this off add `/` for macOS/Linux or `\\` for Windows to the beginning of your path. Below is an example:\n\n```yaml\nstructure_root: '/code/github'\n```\n\nIf we were to run `fgh clone gleich/fgh` with the config shown above it would be cloned to `/code/github/gleich/public/Go/fgh`.\n\n### 🗂 `structure`\n\nThis is the structure used inside of the [`structure_root`](#-structure_root) If you use the [keywords shown in the clone structure](#-keywords) it will automatically be replaced by the value for the repo and add the name of the repo to the end. Below is an example of what you would put in the general config file:\n\n```yaml\nstructure:\n  - OWNER\n  - repos\n  - MAIN_LANGUAGE\n```\n\nIf we were to run `fgh clone gleich/fgh` with just the config shown above it would be cloned to `~/github/gleich/repos/Go/fgh`.\n\n### 💡 Example Config\n\nSay we have the following config:\n\n```yaml\nstructure_root: 'code'\nstructure:\n  - OWNER\n```\n\nIf we were to run `fgh clone gleich/fgh` it would clone the repo to `~/code/gleich/fgh`.\n\n### 🚚 Moving Repos to New Structure\n\nJust run:\n\n```bash\nfgh migrate \u003cold project root\u003e\n```\n\n## 🙌 Contributing\n\nThank you for considering contributing to `fgh`! Before contributing, make sure to read the [CONTRIBUTING.md file](https://github.com/gleich/fgh/blob/master/CONTRIBUTING.md).\n\n\u003c!-- DO NOT REMOVE - contributor_list:start --\u003e\n\n## 👥 Contributors\n\n- **[@gleich](https://github.com/gleich)**\n\n- **[@cjdenio](https://github.com/cjdenio)**\n\n- **[@quackduck](https://github.com/quackduck)**\n\n- **[@safinsingh](https://github.com/safinsingh)**\n\n- **[@stratosgear](https://github.com/stratosgear)**\n\n- **[@imgbot[bot]](https://github.com/apps/imgbot)**\n\n\u003c!-- DO NOT REMOVE - contributor_list:end --\u003e\n","funding_links":[],"categories":["Go","CLI Tools"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgleich%2Ffgh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgleich%2Ffgh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgleich%2Ffgh/lists"}