git-feature: add configurable branch separator (#1072)

* git-feature: add configurable branch separator

Closes #1069

This allows the use of a separator other than `/` for feature or other
alias branches. While a command-line option has been provided (`-s` or
`--separator`), this will most often be used via
`git-extras.feature.separator`.

* Significant update to bin/git-feature

- Changed option parsing so that `--alias` requires an argument and will
  fail with an error unless provided. Applied the same logic to
  `--separator`.

- Changed `finish` parsing to capture it as a variable flag during
  argument parsing.

  This could be extended so that if `finish` is already true, a second
  `finish` results in the word being added to the argument list.

  ```console
  $ git feature -- finish remote
  $ git feature finish finish remote
  ```

  This has not been done because it is a bit of an inconsistent handling
  for documentation purposes.

- Add handling of `--` to permit options or `finish` to be made part of
  the feature branch name.

- Since `finish` is now a variable flag, simplify the name-building
  logic to always use `concatargs "${argv[@]}"`. This means that
  `git feature finish ...` and `git feature ...` behave the same in
  terms of feature branch name building.

- Basically rewrote the man page to include better descriptions of the
  options as well as adding a GIT CONFIG section and additional EXAMPLES
  for the new features/behaviour.
This commit is contained in:
Austin Ziegler 2023-09-18 23:10:59 -04:00 committed by GitHub
parent 76cd9bdf45
commit 49650eda62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 280 additions and 98 deletions

View file

@ -6,22 +6,30 @@ if [ -z "$branch_prefix" ]; then
branch_prefix="feature"
fi
branch_separator=$(git config --get git-extras.feature.separator)
if [ -z "$branch_separator" ]; then
branch_separator="/"
fi
merge_mode="--no-ff"
finish=false
declare -a argv
while test $# != 0
do
case $1 in
-a|--alias )
if [[ -n $2 ]]
if [[ -n $2 ]] && [[ $2 != -- ]]
then
shift # shift -a|-alias
branch_prefix=$1
else
argv+=("$1") # treat tail '-a' as <name>
echo >&2 "option $1 requires a value"
exit 1
fi
;;
-r|--remote )
if [[ -n $2 ]]
if [[ -n $2 ]] && [[ $2 != -- ]]
then
remote=$2
shift
@ -29,6 +37,16 @@ do
remote="origin"
fi
;;
-s|--separator )
if [[ -n $2 ]] && [[ $2 != -- ]]
then
branch_separator=$2
shift
else
echo >&2 "option $1 requires a value"
exit 1
fi
;;
--squash )
merge_mode="--squash"
;;
@ -36,6 +54,15 @@ do
start_point=$2
shift
;;
-- )
# terminate argument parsing
shift
argv+=("$@")
break
;;
finish )
finish=true
;;
* )
argv+=("$1")
;;
@ -45,21 +72,17 @@ done
concatargs() {
str=$(IFS='-'; echo "$*")
branch="$branch_prefix"/$str
branch="$branch_prefix$branch_separator$str"
}
if test "${argv[0]}" = "finish"; then
test -z "${argv[1]}" && echo "$branch_prefix" "<name> required." 1>&2 && exit 1
branch="$branch_prefix"/"${argv[1]}"
test -z "${argv[0]}" && echo "$branch_prefix" "<name> required." 1>&2 && exit 1
concatargs "${argv[@]}"
if "${finish}"
then
git merge ${merge_mode} "$branch" && git delete-branch "$branch"
else
test -z "${argv[0]}" && echo "$branch_prefix" "<name> required." 1>&2 && exit 1
if test -n "${argv[1]}"; then
concatargs "${argv[@]}"
else
branch="$branch_prefix"/"${argv[0]}"
fi
if [[ -n $remote ]] && [[ -z $start_point ]]
then
git create-branch -r "$remote" "$branch"

View file

@ -1,56 +1,85 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-FEATURE" "1" "November 2020" "" "Git Extras"
.TH "GIT\-FEATURE" "1" "September 2023" "" "Git Extras"
.
.SH "NAME"
\fBgit\-feature\fR \- Create/Merge feature branch
.
.SH "SYNOPSIS"
\fBgit\-feature\fR [\-a|\-\-alias branch_prefix] [\-r|\-\-remote [remote_name]] <name>
\fBgit\-feature\fR [\-a|\-\-alias \fIPREFIX\fR] [\-s|\-\-separator \fISEPARATOR\fR] [\-r|\-\-remote [REMOTE_NAME]] [\-\-from START_POINT] \fINAME\fR\.\.\.
.
.br
\fBgit\-feature\fR [\-a|\-\-alias branch_prefix] finish [\-\-squash] <name>
.P
\fBgit\-feature\fR [\-a|\-\-alias \fIPREFIX\fR] [\-s|\-\-separator \fISEPARATOR\fR] finish [\-\-squash] \fINAME\fR\.\.\.
.
.SH "DESCRIPTION"
Create/Merge the given feature branch
Create or merge the given feature branch\. The feature branch name is made from the \fIPREFIX\fR, the \fISEPARATOR\fR, and the \fINAME\fR joined together\.
.
.P
The default \fIPREFIX\fR is \fBfeature\fR and \fISEPARATOR\fR is \fB/\fR, which can be changed (see OPTIONS and GIT CONFIG for details)\.
.
.P
The branch \fINAME\fR may be specified as multiple words which will be joined with \fB\-\fR\. If the branch name contains the word \fBfinish\fR or is another OPTION, \fB\-\-\fR should be passed to stop OPTION parsing\. See the EXAMPLES for details\.
.
.SH "OPTIONS"
<\-a|\-\-alias branch_prefix>
.
.P
use \fBbranch_prefix\fR instead of \fBfeature\fR
.TP
\fB\-a\fR \fIPREFIX\fR, \fB\-\-alias\fR \fIPREFIX\fR:
.
.P
<\-r|\-\-remote [remote_name]>
.IP
The branch prefix to use, or \fBfeature\fR if not supplied\.
.
.P
.TP
\fB\-s\fR \fISEPARATOR\fR, \fB\-\-separator\fR \fISEPARATOR\fR:
.
.IP
The separator to use for joining the branch prefix and the branch name, or \fB/\fR if not supplied\.
.
.TP
\fB\-r\fR [REMOTE_NAME], \fB\-\-remote\fR [REMOTE_NAME]:
.
.IP
Setup a remote tracking branch using \fBremote_name\fR\. If \fBremote_name\fR is not supplied, use \fBorigin\fR by default\.
.
.P
<\-\-from [start_point]>
.TP
\fB\-\-from\fR START_POINT:
.
.P
Setup a start point when the branch created\. If \fB\-\-from\fR is not supplied, use the current branch by default\.
.IP
Setup a start point when the branch created\. If \fB\-\-from\fR is not supplied, use the current branch by default\. This option will be ignored when \fBfinish\fRing a branch\.
.
.P
<finish>
.TP
\fBfinish\fR:
.
.P
.IP
Merge and delete the feature branch\.
.
.P
<\-\-squash>
.TP
\fB\-\-squash\fR:
.
.P
Run a squash merge\.
.IP
Run a squash merge when \fBfinish\fRing the feature branch\.
.
.P
<name>
.TP
\fINAME\fR:
.
.P
.IP
The name of the feature branch\.
.
.SH "GIT CONFIG"
You can configure the default branch prefix and separator via git config options\.
.
.TP
\fBgit\-extras\.feature\.prefix\fR:
.
.IP
$ git config \-\-global add git\-extras\.feature\.prefix "prefix"
.
.TP
\fBgit\-extras\.feature\.separator\fR:
.
.IP
$ git config \-\-global add git\-extras\.feature\.separator "\-"
.
.SH "EXAMPLES"
.
.TP
@ -107,6 +136,54 @@ $ (features/dependencies) git checkout master
.br
$ git features finish dependencies
.
.TP
Use custom branch separator:
.
.IP
$ git feature \-s \- dependencies
.
.br
$ (feature\-dependencies) \.\.\.
.
.br
$ (feature\-dependencies) git checkout master
.
.br
$ git feature \-s \- finish dependencies
.
.TP
Use custom branch prefix and separator from git config with multiple words:
.
.IP
$ git config \-\-global \-\-add git\-extras\.feature\.prefix "features"
.
.br
$ git config \-\-global \-\-add git\-extras\.feature\.separator "\."
.
.br
$ git feature dependency tracking
.
.br
$ (features\.dependency\-tracking) \.\.\.
.
.br
$ (features\.dependency\-tracking) git checkout master
.
.br
$ git feature finish dependency tracking
.
.TP
Use a \fBgit\-feature\fR option flag as part of a branch name:
.
.IP
$ git feature \-\- finish remote
.
.br
\&\.\.\.
.
.br
$ (feature/finish\-remote) git commit \-m "Some changes"
.
.SH "AUTHOR"
Written by Jesús Espino <\fIjespinog@gmail\.com\fR>
.
@ -116,8 +193,11 @@ Modified by Mark Pitman <\fImark\.pitman@gmail\.com\fR>
.br
Modified by Carlos Prado <\fIcarlos\.prado@cpradog\.com\fR>
.
.br
Modified by Austin Ziegler <\fIhalostatue@gmail\.com\fR>
.
.SH "REPORTING BUGS"
<\fIhttps://github\.com/tj/git\-extras/issues\fR>
.
.SH "SEE ALSO"
<\fIhttps://github\.com/tj/git\-extras\fR>
<\fIhttps://github\.com/tj/git\-extras\fR>, git\-create\-branch(1), git\-delete\-branch(1)

View file

@ -57,6 +57,7 @@
<a href="#SYNOPSIS">SYNOPSIS</a>
<a href="#DESCRIPTION">DESCRIPTION</a>
<a href="#OPTIONS">OPTIONS</a>
<a href="#GIT-CONFIG">GIT CONFIG</a>
<a href="#EXAMPLES">EXAMPLES</a>
<a href="#AUTHOR">AUTHOR</a>
<a href="#REPORTING-BUGS">REPORTING BUGS</a>
@ -76,38 +77,56 @@
<h2 id="SYNOPSIS">SYNOPSIS</h2>
<p><code>git-feature</code> [-a|--alias branch_prefix] [-r|--remote [remote_name]] &lt;name&gt;<br />
<code>git-feature</code> [-a|--alias branch_prefix] finish [--squash] &lt;name&gt;</p>
<p><code>git-feature</code> [-a|--alias branch_prefix] [-s|--separator branch_separator] [-r|--remote [remote_name]] &lt;name&gt;<br />
<code>git-feature</code> [-a|--alias branch_prefix] [-s|--separator branch_separator] finish [--squash] &lt;name&gt;</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p> Create/Merge the given feature branch</p>
<p>Create/Merge the given feature branch.</p>
<p>The branch <code>name</code> may be specified as multiple words which will be joined with <code>-</code> characters. If any word should start with a <code>-</code>, the name should be preceded by <code>--</code>, which will signal that option parsing should be ignored.</p>
<h2 id="OPTIONS">OPTIONS</h2>
<p> &lt;-a|--alias branch_prefix&gt;</p>
<p>&lt;-a|--alias branch_prefix&gt;</p>
<p> use <code>branch_prefix</code> instead of <code>feature</code></p>
<p>The branch prefix to use, or <code>feature</code> if not supplied.</p>
<p> &lt;-r|--remote [remote_name]&gt;</p>
<p>&lt;-s|--separator branch_separator&gt;</p>
<p> Setup a remote tracking branch using <code>remote_name</code>. If <code>remote_name</code> is not supplied, use <code>origin</code> by default.</p>
<p>The separator to use for joining the branch prefix and the branch name, or <code>/</code> if not supplied.</p>
<p> &lt;--from [start_point]&gt;</p>
<p>&lt;-r|--remote [remote_name]&gt;</p>
<p> Setup a start point when the branch created. If <code>--from</code> is not supplied, use the current branch by default.</p>
<p>Setup a remote tracking branch using <code>remote_name</code>. If <code>remote_name</code> is not supplied, use <code>origin</code> by default.</p>
<p> &lt;finish&gt;</p>
<p>&lt;--from [start_point]&gt;</p>
<p> Merge and delete the feature branch.</p>
<p>Setup a start point when the branch created. If <code>--from</code> is not supplied, use the current branch by default.</p>
<p> &lt;--squash&gt;</p>
<p>&lt;finish&gt;</p>
<p> Run a squash merge.</p>
<p>Merge and delete the feature branch.</p>
<p> &lt;name&gt;</p>
<p>&lt;--squash&gt;</p>
<p> The name of the feature branch.</p>
<p>Run a squash merge.</p>
<p>&lt;name&gt;</p>
<p>The name of the feature branch.</p>
<h2 id="GIT-CONFIG">GIT CONFIG</h2>
<p>You can configure the default branch prefix and separator via git config options.</p>
<p> $ git config --global add git-extras.feature.prefix "branch_prefix"</p>
<p>The default <code>branch_prefix</code> is <code>feature</code>.</p>
<p> $ git config --global add git-extras.feature.separator "-"</p>
<p>The default <code>branch_separator</code> is <code>/</code>.</p>
<h2 id="EXAMPLES">EXAMPLES</h2>
@ -135,14 +154,34 @@ $ git features dependencies<br />
$ (features/dependencies) ...<br />
$ (features/dependencies) git checkout master<br />
$ git features finish dependencies</p></dd>
<dt>Use custom branch separator:</dt><dd><p></p>
<p>$ git feature -s - dependencies<br />
$ (feature-dependencies) ...<br />
$ (feature-dependencies) git checkout master<br />
$ git feature -s - finish dependencies</p></dd>
<dt>Use custom branch prefix and separator from git config with multiple words:</dt><dd><p></p>
<p>$ git config --global --add git-extras.feature.prefix "features"<br />
$ git config --global --add git-extras.feature.separator "."<br />
$ git feature dependency tracking<br />
$ (features.dependency-tracking) ...<br />
$ (features.dependency-tracking) git checkout master<br />
$ git feature finish dependency tracking</p></dd>
<dt>Use a <code>git-feature</code> option flag as part of a branch name:</dt><dd><p></p>
<p>$ git feature -- --remote<br />
...<br />
$ (feature/--remote) git commit -m "Some changes"</p></dd>
</dl>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Written by Jesús Espino &lt;<a href="&#109;&#x61;&#105;&#108;&#116;&#111;&#x3a;&#x6a;&#x65;&#115;&#112;&#105;&#x6e;&#x6f;&#x67;&#64;&#x67;&#x6d;&#97;&#105;&#108;&#46;&#x63;&#x6f;&#109;" data-bare-link="true">&#106;&#101;&#115;&#112;&#105;&#x6e;&#111;&#x67;&#x40;&#103;&#x6d;&#x61;&#105;&#x6c;&#x2e;&#99;&#x6f;&#x6d;</a>&gt;<br />
Modified by Mark Pitman &lt;<a href="&#x6d;&#97;&#105;&#108;&#x74;&#x6f;&#58;&#x6d;&#97;&#114;&#x6b;&#x2e;&#x70;&#x69;&#x74;&#x6d;&#x61;&#x6e;&#64;&#103;&#x6d;&#97;&#105;&#108;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x6d;&#97;&#x72;&#107;&#x2e;&#x70;&#105;&#116;&#x6d;&#97;&#110;&#x40;&#x67;&#x6d;&#97;&#105;&#108;&#x2e;&#x63;&#111;&#x6d;</a>&gt;<br />
Modified by Carlos Prado &lt;<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#x63;&#97;&#x72;&#108;&#111;&#x73;&#46;&#x70;&#114;&#x61;&#100;&#x6f;&#x40;&#99;&#112;&#114;&#x61;&#100;&#111;&#x67;&#46;&#x63;&#x6f;&#x6d;" data-bare-link="true">&#x63;&#x61;&#x72;&#108;&#111;&#x73;&#x2e;&#x70;&#x72;&#x61;&#x64;&#111;&#64;&#x63;&#x70;&#114;&#97;&#x64;&#111;&#103;&#x2e;&#99;&#111;&#109;</a>&gt;</p>
<p>Written by Jesús Espino &lt;<a href="&#109;&#97;&#x69;&#x6c;&#x74;&#111;&#x3a;&#106;&#x65;&#115;&#x70;&#x69;&#110;&#x6f;&#x67;&#64;&#103;&#x6d;&#97;&#105;&#108;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#106;&#x65;&#115;&#112;&#x69;&#x6e;&#x6f;&#x67;&#x40;&#103;&#109;&#x61;&#x69;&#108;&#46;&#x63;&#x6f;&#x6d;</a>&gt;<br />
Modified by Mark Pitman &lt;<a href="&#109;&#97;&#x69;&#108;&#x74;&#111;&#x3a;&#x6d;&#97;&#114;&#x6b;&#46;&#x70;&#105;&#x74;&#x6d;&#97;&#110;&#64;&#x67;&#x6d;&#x61;&#105;&#108;&#46;&#x63;&#111;&#x6d;" data-bare-link="true">&#x6d;&#97;&#114;&#x6b;&#46;&#x70;&#x69;&#x74;&#x6d;&#97;&#x6e;&#x40;&#x67;&#109;&#x61;&#105;&#108;&#46;&#x63;&#x6f;&#109;</a>&gt;<br />
Modified by Carlos Prado &lt;<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&#99;&#97;&#114;&#x6c;&#111;&#x73;&#46;&#x70;&#114;&#x61;&#100;&#111;&#64;&#x63;&#x70;&#x72;&#97;&#x64;&#x6f;&#103;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#x63;&#97;&#114;&#108;&#111;&#115;&#46;&#112;&#114;&#97;&#x64;&#x6f;&#x40;&#x63;&#112;&#114;&#x61;&#100;&#111;&#x67;&#46;&#x63;&#111;&#109;</a>&gt;<br />
Modified by Austin Ziegler &lt;<a href="&#109;&#x61;&#105;&#108;&#x74;&#111;&#58;&#104;&#97;&#108;&#x6f;&#115;&#116;&#x61;&#x74;&#117;&#x65;&#64;&#x67;&#x6d;&#97;&#x69;&#x6c;&#x2e;&#99;&#x6f;&#109;" data-bare-link="true">&#104;&#97;&#108;&#111;&#x73;&#x74;&#97;&#x74;&#117;&#101;&#x40;&#103;&#109;&#x61;&#x69;&#x6c;&#x2e;&#99;&#111;&#x6d;</a>&gt;</p>
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
@ -155,7 +194,7 @@ Modified by Carlos Prado &lt;<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#111;&#x3a;&
<ol class='man-decor man-foot man foot'>
<li class='tl'></li>
<li class='tc'>November 2020</li>
<li class='tc'>September 2023</li>
<li class='tr'>git-feature(1)</li>
</ol>

View file

@ -1,81 +1,121 @@
git-feature(1) -- Create/Merge feature branch
=======================================
# git-feature(1) -- Create/Merge feature branch
## SYNOPSIS
`git-feature` [-a|--alias branch_prefix] [-r|--remote [remote_name]] &lt;name&gt;
`git-feature` [-a|--alias branch_prefix] finish [--squash] &lt;name&gt;
`git-feature` [-a|--alias <PREFIX>] [-s|--separator <SEPARATOR>] [-r|--remote [REMOTE_NAME]] [--from START_POINT] <NAME>...
`git-feature` [-a|--alias <PREFIX>] [-s|--separator <SEPARATOR>] finish [--squash] <NAME>...
## DESCRIPTION
Create/Merge the given feature branch
Create or merge the given feature branch. The feature branch name is made from the <PREFIX>, the <SEPARATOR>, and the <NAME> joined together.
The default <PREFIX> is `feature` and <SEPARATOR> is `/`, which can be changed (see OPTIONS and GIT CONFIG for details).
The branch <NAME> may be specified as multiple words which will be joined with `-`. If the branch name contains the word `finish` or is another OPTION, `--` should be passed to stop OPTION parsing. See the EXAMPLES for details.
## OPTIONS
&lt;-a|--alias branch_prefix&gt;
- `-a` <PREFIX>, `--alias` <PREFIX>:
use `branch_prefix` instead of `feature`
The branch prefix to use, or `feature` if not supplied.
&lt;-r|--remote [remote_name]&gt;
- `-s` <SEPARATOR>, `--separator` <SEPARATOR>:
The separator to use for joining the branch prefix and the branch name, or `/` if not supplied.
- `-r` [REMOTE_NAME], `--remote` [REMOTE_NAME]:
Setup a remote tracking branch using `remote_name`. If `remote_name` is not supplied, use `origin` by default.
&lt;--from [start_point]&gt;
- `--from` START_POINT:
Setup a start point when the branch created. If `--from` is not supplied, use the current branch by default.
Setup a start point when the branch created. If `--from` is not supplied, use the current branch by default. This option will be ignored when `finish`ing a branch.
&lt;finish&gt;
- `finish`:
Merge and delete the feature branch.
&lt;--squash&gt;
- `--squash`:
Run a squash merge.
Run a squash merge when `finish`ing the feature branch.
&lt;name&gt;
- <NAME>:
The name of the feature branch.
## GIT CONFIG
You can configure the default branch prefix and separator via git config options.
- `git-extras.feature.prefix`:
$ git config --global add git-extras.feature.prefix "prefix"
- `git-extras.feature.separator`:
$ git config --global add git-extras.feature.separator "-"
## EXAMPLES
* Start a new feature:
- Start a new feature:
$ git feature dependencies
...
$ (feature/dependencies) git commit -m "Some changes"
$ git feature dependencies
...
$ (feature/dependencies) git commit -m "Some changes"
* Finish a feature with --no-ff merge:
- Finish a feature with --no-ff merge:
$ (feature/dependencies) git checkout master
$ git feature finish dependencies
$ (feature/dependencies) git checkout master
$ git feature finish dependencies
* Finish a feature with --squash merge:
- Finish a feature with --squash merge:
$ (feature/dependencies) git checkout master
$ git feature finish --squash dependencies
$ (feature/dependencies) git checkout master
$ git feature finish --squash dependencies
* Publish a feature upstream:
- Publish a feature upstream:
$ git feature dependencies -r upstream
$ git feature dependencies -r upstream
* Use custom branch prefix:
- Use custom branch prefix:
$ git alias features "feature -a features"
$ git features dependencies
$ (features/dependencies) ...
$ (features/dependencies) git checkout master
$ git features finish dependencies
$ git alias features "feature -a features"
$ git features dependencies
$ (features/dependencies) ...
$ (features/dependencies) git checkout master
$ git features finish dependencies
- Use custom branch separator:
$ git feature -s - dependencies
$ (feature-dependencies) ...
$ (feature-dependencies) git checkout master
$ git feature -s - finish dependencies
- Use custom branch prefix and separator from git config with multiple words:
$ git config --global --add git-extras.feature.prefix "features"
$ git config --global --add git-extras.feature.separator "."
$ git feature dependency tracking
$ (features.dependency-tracking) ...
$ (features.dependency-tracking) git checkout master
$ git feature finish dependency tracking
- Use a `git-feature` option or the `finish` command as part of a branch name:
$ git feature -- finish remote
...
$ (feature/finish-remote) git commit -m "Some changes"
$ (feature/finish-remote) git checkout main
$ git feature finish -- finish remote
## AUTHOR
Written by Jesús Espino &lt;<jespinog@gmail.com>&gt;
Modified by Mark Pitman &lt;<mark.pitman@gmail.com>&gt;
Modified by Carlos Prado &lt;<carlos.prado@cpradog.com>&gt;
Modified by Carlos Prado &lt;<carlos.prado@cpradog.com>&gt;
Modified by Austin Ziegler &lt;<halostatue@gmail.com>&gt;
## REPORTING BUGS
@ -83,4 +123,4 @@ Modified by Carlos Prado &lt;<carlos.prado@cpradog.com>&gt;
## SEE ALSO
&lt;<https://github.com/tj/git-extras>&gt;
&lt;<https://github.com/tj/git-extras>&gt;, git-create-branch(1), git-delete-branch(1)