{"id":27996395,"url":"https://github.com/groupon/git-workflow","last_synced_at":"2025-05-08T21:41:51.529Z","repository":{"id":34924311,"uuid":"190944320","full_name":"groupon/git-workflow","owner":"groupon","description":null,"archived":true,"fork":false,"pushed_at":"2023-10-03T21:55:16.000Z","size":545,"stargazers_count":10,"open_issues_count":9,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-08T21:41:46.814Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/groupon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-06-08T23:23:16.000Z","updated_at":"2025-04-28T08:31:15.000Z","dependencies_parsed_at":"2023-09-29T00:54:42.525Z","dependency_job_id":null,"html_url":"https://github.com/groupon/git-workflow","commit_stats":{"total_commits":41,"total_committers":5,"mean_commits":8.2,"dds":0.6097560975609756,"last_synced_commit":"9dc4c5806ad4d54c77f3f9adc464c0fb3eabb43d"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/groupon%2Fgit-workflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/groupon%2Fgit-workflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/groupon%2Fgit-workflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/groupon%2Fgit-workflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/groupon","download_url":"https://codeload.github.com/groupon/git-workflow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253153596,"owners_count":21862375,"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":"2025-05-08T21:41:50.708Z","updated_at":"2025-05-08T21:41:51.514Z","avatar_url":"https://github.com/groupon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Branch Workflow CLI\n\nA cli that provides a set of `git wf` subcommands which simplify dealing with\nfeature branches \u0026 GitHub pull requests. Does not require a GH API token, as\nit just opens your browser to complete Pull Request operations.\n\n- creates named feature branches which track their intended \"parent\" (`start`)\n- opens pull requests against the intended parent branch (`pr`)\n- cleans up when done (`done`)\n- aborts abandoned branches cleanly (`abort`)\n- renames branches locally \u0026 on server (`rename`)\n- additional optional release management commands (`cut-release`, `qa`,\n  `hotfix`, `merge-back`)\n\n## \"master\" vs \"main\"\n\nBelow we use the term `main` to refer to your mainline branch; if you have a\n`main` branch in your local checkout, we'll assume that's the one you're using.\nIf not, we'll assume you're using `master`.\n\n## Installation\n\n```\n$ npm install -g git-wf\n```\n\nIf your GitHub username does not match `$USER` in your environment, you\nshould set the `$GH_USER` env var to your GitHub username wherever you\nset your shell's environment variables.\n\n## Usage\n\n```\n$ git wf --help\n```\n\n## Commands\n\nThe `start`, `pr`, `abort`, `rename`, and `done` commands can be used on **any**\nproject that has a master or main branch.\n\nAll of the other commands will enforce the existence and use of the `main`,\n`release`, and `hotfix` branch naming scheme.\n\n### `git wf start [--fork] \u003cname\u003e` - starts a new feature branch\n\nGiven you are currently on branch `\u003cparent\u003e`\n\n1. Updates the branch you currently have checked out with `git pull`\n1. Creates a new feature branch named `\u003cname\u003e` locally with\n   `git checkout -b \u003cname\u003e`\n1. If you specified `--fork` or already have a remote named `fork`:\n   1. verifies you have a remote named `fork`\n   1. if you don't, verifies that `\u003cyourusername\u003e/\u003creponame\u003e` exists on github,\n      and if not prompts you to create it\n   1. if you do have a github fork, creates the `fork` remote for you\n   1. Pushes your feature branch to `fork` as a branch named\n      `feature/\u003cparent\u003e/\u003cname\u003e` with\n      `git push -u fork \u003cname\u003e:feature/\u003cparent\u003e\u003cname\u003e`\n1. If you didn't, pushes your feature branch to `origin` as a branch named\n   `\u003cyourusername\u003e/feature/\u003cparent\u003e/\u003cname\u003e` with\n   `git push -u origin \u003cname\u003e:\u003cyourusername\u003e/feature/\u003cparent\u003e/\u003cname\u003e`\n\n### `git wf rename \u003cnewname\u003e` - renames a feature branch\n\nIf you decide you don't like your name, from a checked out feature\nbranch run this command, passing a new name, it will:\n\n1. Fetch the latest commits from the remote\n1. Create a new remote branch named correctly, based on the fetched\n   version of the old remote branch (no new commits from local)\n1. Create a new local branch with the new name, based on the current\n   local branch\n1. Make the former the upstream of the latter\n1. Delete the old local branch\n1. Delete the old remote branch\n\n### `git wf abort` - aborts a feature\n\nIf you decide you don't like your new feature, you may PERMANENTLY delete it,\nlocally and remotely, using `git wf abort`. This will:\n\n1. Commit any working tree changes as a commit with message \"WIP\"\n1. Save the SHA of whatever the final commit was\n1. Switch to the parent branch\n1. Delete the local branch, remote branch, and remote tracking branch.\n1. Output the final SHA in case you change your mind.\n\n### `git wf pr` - PRs a completed feature branch\n\nGiven you are currently on a feature branch named `\u003cname\u003e`, makes sure all your\nwork is pushed to `origin` or `fork`, then opens your browser to a GitHub PR\ncreation page to merge that back to its parent branch.\n\n### `git wf done` - cleans up a merged feature branch\n\nGiven you are currently on a feature branch named `\u003cname\u003e`\n\n1. Switches to inferred parent branch with `git checkout \u003cparent\u003e`\n1. Updates the parent branch with `git pull --no-rebase`\n1. Deletes the feature branch with `git branch -d \u003cname\u003e`\n1. Cleans up the corresponding remote branch with `git remote prune origin`\n\n### `git wf cut-release [branch]` - PRs starting a fresh release from main\n\n1. Runs `git wf merge-back` (see below)\n1. Opens a PR, as per `git wf pr` to merge `branch` (default: `main`) to\n   `release`\n\n### `git wf qa [branch]` - Tags build of _branch_\n\n1. If no `[branch]` is given, defaults to current branch\n1. If `[branch]` is `release`, runs `git wf merge-back`\n1. Switches to `[branch]` with `git checkout [branch]`\n1. Updates with `git pull --no-rebase`\n1. Tags `HEAD` of `[branch]` as `build-YYYY.mm.dd_HH.MM.SS` with\n   `git tag build-...`\n1. Pushes tag with `git push origin tag build-...`\n\n### `git wf hotfix \u003cbuild-tag\u003e` - Moves the hotfix branch to given tag\n\n1. Switches to `hotfix` branch\n1. Pulls latest updates\n1. Fast-forward merges `hotfix` to given build tag\n1. Pushes `hotfix` branch\n\n### `git wf merge-back` - Merges all changes back from main ← release ← hotfix\n\n1. Switches to `hotfix` branch\n1. Pulls latest updates\n1. Merges `hotfix` branch to `release` branch - if there are conflicts, it\n   creates a feature branch for you to clean up the results, and submit a PR.\n   If not, pushes the merged branch.\n1. As before, but this time merging `release` onto `main`\n\n## Example Flow\n\nHere's a narrative sequence of events in the life of a project:\n\n- The project starts with branches `main`, `release`, and `hotfix` all\n  pointing at the same place\n- On branch main, you `git wf start widget-fix`\n- Now on branch `widget-fix`, you make some commits, decide it's ready to PR,\n  and run `git wf pr`\n- The PR is tested, accepted, and merged, and at some point, while on branch\n  `widget-fix`, you run `git wf done`, which cleans it up\n- You start a new features, `git wf start bad-ideea`, make a few commits, then\n  realize you named it wrong, so you `git wf rename bad-idea` - which is fine\n  until you realize you don't want it at all, so you `git wf abort` and it's\n  all gone.\n- A few more good features go in, and it's time to `git wf cut-release` -\n  now your `release` branch is pointing up-to-date with `main`, and people\n  can resume adding features to `main`\n- It's time to QA your upcoming release, so you `git wf qa release` which\n  creates a `build-...` tag\n- Your shiny new `build-...` tag is available for deploying\n  however you do that, so you deploy it, QA it, and eventually release it\n  to production.\n- Everything's progressing along, there's new stuff on `main`, maybe a\n  new release has even been cut to `release`, when you realize there's\n  a problem on production, so you run `git wf hotfix build-...` with the\n  build tag that's currently on production. Your `hotfix` branch is now\n  ready for fixes.\n- From the `hotfix` branch, you `git wf start urgent-thingy` and now you're\n  on a feature branch off of `hotfix` - you make your commits to fix the\n  bug and `git wf pr`\n- People review and approve your PR, it's merged to the `hotfix` branch, you\n  `git wf done` to cleanup\n- `git wf qa hotfix` creates a new `build-...` tag off of the `hotfix` branch,\n  which can be QAed, then (quickly!) deployed to production\n- Now's a good time to run `git wf merge-back`, which will take those commits\n  sitting on `hotfix` and merge them back onto the `release` branch you had\n  in progress. This goes cleanly, so it just does it for you.\n- Then it goes to merge `release` back onto `main`, but uh-oh there are some\n  conflicts by now, because someone fixed the problem a different way on\n  `main`. No worries, `git wf` will detect that, create a feature branch\n  to resolve the conflicts, let you clean up the merge on that branch, and\n  then you `git wf pr` and it will open a PR to review the resolution.\n\nAt every stage, you don't need to stop your forward progress, forget which your\nnext planned release was, or anything else as you add new features and hotfix\nproduction issues.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgroupon%2Fgit-workflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgroupon%2Fgit-workflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgroupon%2Fgit-workflow/lists"}