{"id":13566598,"url":"https://github.com/StreakyCobra/gws","last_synced_at":"2025-04-04T00:31:14.548Z","repository":{"id":13098104,"uuid":"15779526","full_name":"StreakyCobra/gws","owner":"StreakyCobra","description":"Colorful KISS helper for git workspaces","archived":false,"fork":false,"pushed_at":"2020-02-28T16:19:27.000Z","size":1647,"stargazers_count":234,"open_issues_count":14,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-04-16T07:48:26.941Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://streakycobra.github.io/gws/","language":"Shell","has_issues":true,"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/StreakyCobra.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-09T21:08:25.000Z","updated_at":"2024-04-06T19:34:21.000Z","dependencies_parsed_at":"2022-09-13T22:20:18.516Z","dependency_job_id":null,"html_url":"https://github.com/StreakyCobra/gws","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StreakyCobra%2Fgws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StreakyCobra%2Fgws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StreakyCobra%2Fgws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StreakyCobra%2Fgws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StreakyCobra","download_url":"https://codeload.github.com/StreakyCobra/gws/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223067257,"owners_count":17082250,"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":[],"created_at":"2024-08-01T13:02:12.785Z","updated_at":"2024-11-04T20:32:18.411Z","avatar_url":"https://github.com/StreakyCobra.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"gws\n===\n\n`gws` is a KISS, bash, colorful helper to manage workspaces composed of Git\nrepositories.\n\nSHOW ME PICTURES!\n-----------------\n\nHere are some screen captures of `gws`:\n\n![gws](http://streakycobra.github.io/gws/images/001.png)\n\n![gws](http://streakycobra.github.io/gws/images/002.png)\n\n![gws](http://streakycobra.github.io/gws/images/003.png)\n\n![gws](http://streakycobra.github.io/gws/images/004.png)\n\n![gws](http://streakycobra.github.io/gws/images/005.png)\n\nInstallation\n------------\n\n**Requirements:** `git`, `bash \u003e 4.0`\n\n* **Arch Linux**: Install the [gws](https://aur.archlinux.org/packages/gws/)\n  package from AUR\n\n* **openSUSE**: Install the [gws](https://software.opensuse.org/package/gws/)\n  package from the devel:tools repository\n\n* **Mac**:\n\n  * On Mac OS X, it may be necessary to upgrade bash to have a version `\u003e 4.0`.\n    It could be done with: `brew install bash`.\n\n  * There is currently a [bug](https://github.com/StreakyCobra/gws/issues/17) in\n    version `0.1.8`. The script uses some options that are specific to GNU\n    `sed` and `cut`, which are not available to OS X versions. A workaround is\n    to install `coreutils` and `gnu-sed` with `brew` (`brew install gnu-sed\n    coreutils`) and then define the following alias in your `~/.bashrc`:\n\n    ```bash\n    alias gws=\"PATH=/usr/local/opt/coreutils/libexec/gnubin:usr/local/opt/gnu-sed/libexec/gnubin:$PATH gws\"\n    ```\n\n* **Other Linux**: You simply need to have the `src/gws` bash script\n  somewhere in your `$PATH`:\n\n  * If someone made a package for your distribution you are lucky.\n\n  * You can put it directly in `/bin` as root user, but it is complicated to\n    keep it up-to-date.\n\n  * It is also possible to put it in your home folder, for example in\n    `~/.local/bin`. You have to be sure that this folder is in your `$PATH`. For\n    `bash` you can include any directory on your `$PATH` by including `export\n    PATH=\"$PATH:/path/to/scripts/dir\"` in your `~/.bashrc`.\n\n\nOn a side note, I could also suggest you to have a look at\n[peru](https://github.com/buildinspace/peru) which lets you keep files from\ndifferent sources up to date with one command.\n\nQuick Start\n----------\n\n* Create a file named `.projects.gws` in a desired workspace folder (e.g.\n  `~/dev`) and fill it with project definitions (see [Syntaxes](#projectsgws)\n  below):\n\n        # Work related\n        work/tools/q | https://github.com/harelba/q.git\n\n        # Other\n        contrib/gws  | https://github.com/StreakyCobra/gws.git\n        contrib/peru | https://github.com/buildinspace/peru\n\n**or**\n\n* Let `gws` detect existing repositories and create the `.projects.gws` for\n  you:\n\n        $ cd path/to/your/workspace\n        $ gws init\n\n**and then**\n\n* Clone all missing repositories with `gws update`, or some specific ones with\n  `gws clone`.\n\n* Do some hacking.\n\n* Show the status of the workspace with `gws`. It reveals which repositories\n  are clean, which ones have uncommited changes, and even which ones are not\n  up-to-date with `origin`.\n\n### But better\n\nLet's say you made a `~/dev/` workspace folder and you created your\n`.projects.gws` list in it. Then your workspace became really easy to replicate!\nJust make this `~/dev` folder a Git repository, add two files and commit them:\n`.projects.gws` and the following `.gitignore`:\n\n    # Ignore everything, so all repositories in our case\n    *\n\n    # But not these files\n    !.projects.gws\n    !.gitignore\n\nNow, when you need to get your workspace on another computer, just clone\nthe `dev` repository, for instance again to the `~/dev` folder. Go into it and\ndo a `gws update`. Everything is cloned and ready to be hacked!\n\nYou want to add a new project into your workspace? Add it to the\n`.projects.gws` list, do a `gws update` to get it. Then commit and push the\n`.projects.gws` file, so when you arrive at work for instance, you just need to\n`git pull` on the `~/dev` folder and then `gws update` to get the same\nworkspace structure that you had at home.\n\nWhy?\n----\n\nIf you are, like me, a Linux programmer/hacker/coder who uses Git a lot, you\ncertainly have a directory in your home folder named `dev`, `workspace`, `code`\nor something else that contains all the projects you are working on. For\ninstance my current organisation is:\n\n    dev\n    ├── archlinux\n    │   ├── aur\n    │   └── habs\n    ├── perso\n    │   ├── gws\n    │   ├── imaxplore\n    │   └── teafree\n    └── config\n\nwhere `aur`, `habs`, `gws`, `imaxplore`, `teafree`, `config` are Git\nrepositories.\n\nSince I use at least three different computers - one laptop, one at home and\none at work - I like to have the same folder structure on all of them. Of\ncourse remembering which project was added recently on other computers and in\nwhich folder is tedious.\n\nSo I started to think about using Git submodules to register all projects on\nwhich I am working and syncing them with Git between the two computers. But\nclearly Git submodules are not usable because they are work with specific\ncommits and not by following branches.\n\nNo worry. The problem is pretty trivial, so I decided to start write a little\nbash (YOLO) script that reads a simple list of repositories, and clones them if\nthey don't exist. And then, commit by commit, the script as grown to finally\nbecome a helper to sync, monitor and check workspaces.\n\nI thought it can be useful to other people, so I made a little cleanup, wrote\nsome small documentation, and there it is. I hope you will enjoy it!\n\nFeatures\n--------\n\nThis tool offers some features, including:\n\n* It uses a list of projects, named `.projects.gws`, containing many projects\n  described by their names, their repository URLs, and optionaly an upstream\n  URL (mapped as a Git remote named `upstream`), like:\n\n        work/theSoftware | git@github.com:You/theSoftware.git\n        perso/gws        | git@github.com:You/gws.git         | git@github.com:StreakyCobra/gws.git\n\n* It can use an ignore list, named `.ignore.gws`, containing regular\n  expressions which discard some specific projects, for instance to disable on\n  your home computer the work-related projects.\n\n        ^work/\n\n* It can detect already existing repositories and create the projects list\n  from that.\n\n        $ gws init\n\n* It can clone missing repositories from the projects list (but not\n  delete ones removed from the list, you have to do that manually for safety.\n  Note that there is the `check` command to identify unlisted repositories).\n\n        $ gws update\n\n  `update` accepts the `--only-changes` option. If present, repos that have at\n  least one remote and are unaffected by the update will not be printed.\n\n* It can also clone a specified selection of missing repositories from the\n  projects list, if you don't need all of them right now.\n\n        $ gws clone work/theSoftware\n\n* It can monitor all listed repositories in one command, showing uncommitted\n  changes, untracked changes and branches not synced with origin.\n\n        $ gws status\n\n  or simply\n\n        $ gws\n\n  `gws status` and `gws` accept the `--only-changes` option. If present, missing\n  repos as well as repos that have at least one remote and only clean branches\n  will not be shown.\n\n* It can fetch the modifications from `origin` for all repositories. It is\n  useful to make sure you have the latest modifications, for instance before\n  getting on a train with no internet connection:\n\n        $ gws fetch\n\n  `fetch` accepts the `--only-changes` option, which has the same effect as for\n  `status`.\n\n* It can also (for the same reasons) pull the modifications from origin for\n  all repositories (but fast-forward only). Same as `gws fetch`, but also does\n  fast-forward merges.\n\n        $ gws ff    # Mnemonic: ff=fast-forward\n\n  `ff` accepts the `--only-changes` option, which has the same effect as for\n  `status`.\n\n* It can check the workspace for all repositories (known, unknown, ignored,\n  missing). Note: This command can be quite slow in large repositories (e.g.\n  home folder), because it needs to search the entire space for unknown\n  repositories. Mainly used from time to time to check workspace consistency:\n\n        $ gws check\n\n\nSyntaxes\n--------\n\n### .projects.gws\n\nOne project per line. Must be of the form\n\n    \u003cany/folder/path\u003e | \u003cremote_url1\u003e \u003cremote_name1\u003e [ | \u003cremote_url2\u003e \u003cremote_name2\u003e [ |  ... ]]\n\nwhere\n\n* the `\u003cremote_name1\u003e` can be skipped and `origin` will be used instead.\n\n* the `\u003cremote_name2\u003e` can be skipped and `upstream` will be used instead.\n\n* there must be at least one `\u003cremote_name\u003e` mapping to `origin`.\n\n* there can also be blank lines, comments or inline comments. Comments start\n  with `#` and continue to the end of the line.\n\n* the *folder path* can be any valid linux folder path not containing `|`, `#`\n  or spaces.\n\n* the *remote names* can be any string not containing `|`, `#` or spaces.\n\n* the *remote URLs* are passed to Git as-is, so they can be anything accepted\n  by Git but must not contain `|`, `#` or spaces. For instance if you have SSH\n  aliases in your config they are accepted.\n\n### .ignore.gws\n\nOne regular expression per line. The regular expression will be matched against\neach project's *folder path*. Some examples:\n\n* Ignore the folder `work` and all its subfolders:\n\n        ^work/\n\n* Ignore all repositories ending with `-work`:\n\n        -work$\n\n* Ignore all repos containing an `a` inside:\n\n        a\n\nThis function is really useful for locally ignoring some projects that are not\nneeded or not accessible.\n\n\n### Theme file\n\nYou can customise the color scheme by placing a shell script at one of the\nfollowing locations:\n\n 1. `./.git/theme.gws`\n 2. `${HOME}/.theme.gws`\n 3. `${HOME}/.config/gws/theme`\n\nThe first existing file in the above order, if any, will be `source`d into the\nmain `gws` script if standard output is a terminal. In the theme script you can\nredefine the color codes set as `C_*` near the beginning of the main script.\n\n\u003e -Why can't I put this in the projects directory with `.projects.gws` and\n  `.ignore.gws`?\n\nBecause then if you sync your `.projects.gws` via Git you could inadvertently\npull a commit that writes a theme file containing arbitrary shell code, which\n`gws` would then blindly run. You're still owned in other ways if an attacker\nhas arbitrary write access in your home directory, but this way the write can't\nbe done remotely over Git.\n\n\nOther thoughts\n--------------\n\n* Except for cloning repositories, this script does not have as a goal to\n  interact with your repositories. So no `pull all`, `push all`, `delete all\n  unused`, features will be implemented (except fast-forward). This will imply\n  too much checking to prevent data loss. Instead, just look at the status of\n  the repositories and perform any needed actions manually on regular basis.\n\n* You can use the commands from any subfolder of the workspace (as `git` does\n  for instance).\n\n* The file `.projects.gws` can easily be verisoned to sync the list of\n  projects between different computers.\n\n* The file `.ignore.gws` allows for keeping the same `.projects.gws` list on\n  all computers, but to locally disable some projects (for instance\n  work-related projects at home because they are unneeded or even not\n  accessible from there).\n\n* `gws check` can be quite slow (for instance if the workspace is the home\n  folder) because it searches all existing Git projects recursively.\n\nFuture\n------\n\nThis project aims to stay simple. I will try to keep the project as alive as\npossible for a bash script, by correcting bugs and maybe some improvements.\nAlso, maybe one day, if I have time, I will rewrite all of this script in\nPython or other more maintainable language.\n\n*Edit:* It seems there will be a continuation of this idea, and it will be\nwritten in OCaml! I'll let you know if the project matures! In any case this\nproject will stay here for users who want something simple and portable.\n\nMaintainers\n-----------\n\nThe project is currently maintained by Emil Lundberg (emlun), after being\nstarted by Fabien Dubosson (StreakyCobra).\n\nContributors\n------------\n\nMany thanks to these people for contributions:\n\n- Frédéric Mahé\n- Blount\n- Alex Sanchez\n- Antoine Belvire\n- Pascal Obry\n- Thomas Pérennou\n- Emil Lundberg\n- François Fleur\n- Thomas Lemaire\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStreakyCobra%2Fgws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStreakyCobra%2Fgws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStreakyCobra%2Fgws/lists"}