{"id":17679982,"url":"https://github.com/costajob/git_commands","last_synced_at":"2026-04-30T01:39:11.241Z","repository":{"id":13710619,"uuid":"16404586","full_name":"costajob/git_commands","owner":"costajob","description":"Utility library to rebase and aggregate your project branches","archived":false,"fork":false,"pushed_at":"2020-07-09T07:42:56.000Z","size":104,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-14T21:46:42.685Z","etag":null,"topics":["git","ruby","scm","workflow"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/costajob.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}},"created_at":"2014-01-31T09:56:31.000Z","updated_at":"2020-07-09T07:42:58.000Z","dependencies_parsed_at":"2022-09-06T11:11:25.811Z","dependency_job_id":null,"html_url":"https://github.com/costajob/git_commands","commit_stats":null,"previous_names":["costajob/git_utils"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/costajob/git_commands","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fgit_commands","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fgit_commands/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fgit_commands/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fgit_commands/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/costajob","download_url":"https://codeload.github.com/costajob/git_commands/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/costajob%2Fgit_commands/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32451481,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"ssl_error","status_checked_at":"2026-04-29T22:10:49.234Z","response_time":110,"last_error":"SSL_read: 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":["git","ruby","scm","workflow"],"created_at":"2024-10-24T09:05:01.046Z","updated_at":"2026-04-30T01:39:11.223Z","avatar_url":"https://github.com/costajob.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Table of Contents\n* [Workflow](#workflow)\n* [Scope](#scope)\n* [Installation](#installation)\n  * [GIT](#git)\n* [Usage](#usage)\n  * [Arguments](#help)\n    * [Help](#help)\n    * [Repository](#repository)\n    * [Branches](#branches)\n  * [Commands](#commands)\n    * [Rebase](#rebase)\n    * [Remove](#remove)\n    * [Aggregate](#aggregate)\n\n## Workflow\nThis script facilitates adopting a subset of the branch-featuring workflow characterised by:\n* each feature will have its own branch\n* integration of feature branch with defaukt one happens via rebasing to maintain a straight commits line\n* is not an issue to `force-with-lease` push feature pranch to origin\n* release branches are created aggregating multiple branches\n\n## Scope\nThe scope of this gem is helping out in the following cases:\n* you have multiple feature branches waiting for release due to some reason (i.e. long QA time...), and need to keep them aligned with master\n* you need to quickly aggregate branches for a release\n* you want to cleanup local and remote branches upon release\n\n## Installation\nJust install the gem to use the binaries commands.\n```\ngem install git_commands\n```\n\n### GIT\nThe library uses the Ruby command line execution to invoke the **git** command as a separate process.  \nI assume you have the GIT program on your path.\n\n## Usage\nHere are the main commands:\n\n### Arguments\nAll of the available commands come with the same set of arguments:\n\n#### Help\nDisplay the help of a specific command by:\n\n```\nrebase --help\nUsage: rebase --repo=/Users/Elvis/greatest_hits --origin=upstream --default=production --branches=feature/love_me_tender,fetaure/teddybear\n    -r, --repo=REPO                  The path to the existing GIT repository\n    -o, --origin=ORIGIN              Specify the remote alias (origin)\n    -d, --default=DEFAULT            Specify the default branch (master)\n    -b, --branches=BRANCHES          Specify branches as: 1. a comma-separated list of names 2. the path to a file containing names on each line 3. via pattern matching\n    -h, --help                       Prints this help\n```\n\n#### Repository\nYou have to specify the absolute path to the GIT repository you want to work with. The path must be a folder initialized as a valid GIT repository (a check via *rev-parse* is performed), otherwise an error is raised:\n\n```\nrebase --repo=invalid\n'invalid' is not a valid GIT repository!\n```\n\n#### Branches\nAs with the repository you always have to specify the list of branches you want to work with. There are different options:\n\n##### List of branches\nSpecify a comma separated list of branch names:\n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=feature/love_me_tender,feature/teddybear,feature/return_to_sender\n\nLoading branches file...\nSuccessfully loaded 3 branches:\n01. feature/love_me_tender\n02. feature/teddybear\n03. feature/return_to_sender\n```\n\n##### Path to a names file\nSpecify an absolute path to a file containing the branches names on each line:\n\nFile */Users/Elvis/greatest_hits/.branches*:\n```\nfeature/love_me_tender\nfeature/teddybear\nfeature/return_to_sender\nfeature/in_the_ghetto\n```\n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=/Users/Elvis/greatest_hits/.branches\n\nLoading branches file...\nSuccessfully loaded 4 branches:\n01. feature/love_me_tender\n02. feature/teddybear\n03. feature/return_to_sender\n04. feature/in_the_ghetto\n```\n\n##### Pattern matching\nIn case you want to work with a set of branches with a common pattern, you have to specify a greedy operator with the wild card you want to match.  \nJust consider you have not to specify *origin/* as the name of the branch, since is managed by the script for you: \n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=*der\n\nLoading branches file...\nSuccessfully loaded 2 branches:\n01. feature/love_me_tender\n02. feature/return_to_sender\n```\n\n##### Checking\nEach loaded branch is validated for existence (but for branches loaded via pattern matching, already fetched from origin).   \nIn case the validation fails, the branch is filtered from the resulting list.\n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=noent,feature/love_me_tender\n\nLoading branches file...\nSuccessfully loaded 1 branch:\n01. feature/love_me_tender\n```\n\nIn case no branches have been loaded, an error is raised:\n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=noent1,noent2\nNo branches loaded!\n```\n\n##### Default branch\nDefault branch cannot be included into the branches list for obvious reasons:\n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=master,feature/love_me_tender\n\nLoading branches file...\nSuccessfully loaded 1 branch:\n01. feature/love_me_tender\n```\n\n### Commands\nHere are the available GIT commands:\n\n#### Rebase\nThis command is useful in case you have to rebase several branches with _origin/master_ (or another specified default) frequently.\nA confirmation is asked to before rebasing.  \n\n```\nrebase --repo=/Users/Elvis/greatest_hits --branches=feature/love_me_tender,feature/teddybear,feature/return_to_sender\n...\n```\n\n##### Changing origin\nThe rebasing runs considering `master` branch as the default one and `origin` as the remote alias.  \nIn case you need to rebase against a different origin and default branch you can specify them by command line:\n```\nrebase --repo=/Users/Elvis/greatest_hits --origin=upstream --default=production --branches=feature/love_me_tender\n\nLoading branches file...\nSuccessfully loaded 1 branch:\n01. feature/love_me_tender\n\nProceed rebasing these branches with upstream/production (Y/N)?\n```\n\n#### Remove\nThis command remove the specified branches locally and remotely.  \nA confirmation is asked before removal.  \n\n```\nremove --repo=/temp/top_20 --branches=*obsolete*\n...\n```\n\n#### Aggregate\nThis command aggregates all of the specified branches into a single one in case you want to create a release branch.  \nA confirmation is asked before aggregating.  \n\n```\naggregate --repo=/Users/Elvis/greatest_hits --branches=*ready*\n...\n```\n\n##### Aggregate naming\nThe created aggregate branch follows a default naming convention pattern: \n`release/\u003ctimestamp\u003e` \n\nEach of the term within the `\u003c` and `\u003e` chars are replaced by related (upcased) environment variables, but for the `timestamp`, that is computed at runtime in the `yyyymmdd` format.  \nConsider a valid pattern should at least contain one replaceable part within the `\u003c` and `\u003e` chars.\n\nYou can overwrite the naming pattern by specifying the following environment variables:\n* `AGGREGATE_NAME` - the name to be used directly for the aggregator branch, without any pattern replacements\n* `AGGREGATE_PATTERN` - change the default pattern by specifying the related environment variables for each parts within the `\u003c` and `\u003e` chars\n\n###### Examples\nPassing directly the aggregate name:\n```shell\nAGGREGATE_NAME=my_aggregate aggregate --repo=/Users/Elvis/greatest_hits --branches=*ready*\n...\nAggregate branches into my_aggregate (Y/N)?\n```\n\nUsing the default pattern:\n```shell\naggregate --repo=/Users/Elvis/greatest_hits --branches=*ready*\n...\nAggregate branches into release/20170307 (Y/N)?\n```\n\nUsing a custom pattern:\n```shell\nRELEASE_TYPE=bugfix \\\nRISK=HIGH \\\nPROGRESSIVE=3 \\\nAGGREGATE_PATTERN=\"release/rc-\u003cprogressive\u003e.\u003crelease_type\u003e_\u003crisk\u003e_\u003ctimestamp\u003e\" aggregate --repo=/Users/Elvis/greatest_hits --branches=*ready*\n...\nAggregate branches into release/rc-3.bugfix_HIGH_20170307 (Y/N)?\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcostajob%2Fgit_commands","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcostajob%2Fgit_commands","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcostajob%2Fgit_commands/lists"}