Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/LucasLarson/gunstage

🔫  `git unstage` as a service: a Git plugin for the shell that automagically remembers all the different commands there are to remove files from staging and when to use each
https://github.com/LucasLarson/gunstage

git-add git-addons git-plugin git-undo git-unstage gunstage hacktoberfest lucaslarson oh-my-zsh-plugin ohmyzsh-plugin omz-plugin posix-compliant zsh-plugin zsh-plugins

Last synced: about 1 month ago
JSON representation

🔫  `git unstage` as a service: a Git plugin for the shell that automagically remembers all the different commands there are to remove files from staging and when to use each

Awesome Lists containing this project

README

        

gunstage
--------

🔫 `git unstage` as a service

https://github.com/unixorn/awesome-zsh-plugins[image:https://github.com/sindresorhus/awesome/raw/a90737eb91368b3be912d1759f9573203ef9e70d/media/mentioned-badge.svg[🕶
Mentioned in Awesome,title="🕶 Mentioned in Awesome"]]
https://github.com/LucasLarson/gunstage/actions?query=workflow:Super-Linter[image:https://github.com/LucasLarson/gunstage/workflows/Super-Linter/badge.svg[GitHub
Super-Linter]]
https://github.com/LucasLarson/gunstage/blob/main/license.adoc[image:https://shields.io/badge/license-GPLP-blue[GPLP,title="GNU
General Public License for Pedants"]]
https://doi.org/10.5281/zenodo.6581323[image:https://zenodo.org/badge/DOI/10.5281/zenodo.6581323.svg[doi:10.5281/zenodo.6581323,title="Digital
Object Identifier"]]

What
~~~~
There are at least nine ways to unstage files in a Git repository.
Remembering which versions of Git support which syntax, under which
circumstances, reduced my productivity enough to publish this software
in response.

This is a command-line shell plugin for undoing `git add`. Too many
staged files? Can’t remember if it’s `git reset HEAD` or
`git restore --staged --`? Just remember `gunstage` or `git unstage`.

`gunstage` works exactly as you would expect it to as it performs the opposite
of `git add`. You can unstage directories and specific files in as few
commands as you’d like:
`gunstage file1.txt file2.txt directory/`.

Want to unstage everything? Well that’s as easy as
`gunstage --all` or `gunstage -A`.

Why
~~~
There is no `git unstage` command packaged as part of Git’s
default tooling. While `git restore --staged` often performs the task,
it’s not an obvious formula based on Git’s other commands.
`git restore --staged` is also unreliable, having
https://web.archive.org/web/20201214132901id_/github.blog/2019-08-16-highlights-from-git-2-23/#experimental-alternatives-for-git-checkout[entered
Git’s vocabulary in 2019^], after some 14 years of releases
without it. Many older releases remain in the wild and `git restore`
causes them to fail and choke. This software gracefully and silently accounts
for those situations by always sending the syntax that Git used from 2005 until
2019: `git reset`.

Instead of keeping up with the latest incarnation of Git, whose manual says
`git restore` “IS EXPERIMENTAL” and “THE BEHAVIOR MAY CHANGE” (emphasis
https://git-scm.com/docs/git-restore/2.30.0#_description[in original^]), you
can let this script do the remembering for you.

Minutiæ of the pedantic and querulous variety
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To unstage content in a Git repository – that is, to undo a
`git add` – you must remember https://stackoverflow.com/q/58003030[which
commands^] are still in use out of the many I’m aware of having been
recommended so far:

1. `git restore --staged` (https://stackoverflow.com/a/16044987[source^]),
1. `git reset HEAD` (https://stackoverflow.com/a/6790291[source^]),
1. `git reset -q HEAD --` (https://github.com/gggritso/gggritso.com/blob/a07b620/_posts/2015-08-23-human-git-aliases.md#L45[source^] (https://news.ycombinator.com/item?id=17987033#17987696[via^]))
1. `git reset` (https://stackoverflow.com/a/6790285[source^]),
1. `git restore --staged --` (https://github.com/iain/dotfiles/commit/4c8f8cf7b849d723cbd0e029457dd24c42ea6263[source^]),
1. `git reset HEAD --` (https://stackoverflow.com/a/5798967[source^]),
1. `git rm --cached` (https://stackoverflow.com/a/5798967[source^]),
1. `git reset --` (https://stackoverflow.com/a/6919257[source^]), and even
1. `git rm --cached -- # ffs` (https://stackoverflow.com/a/30231316[source^]).

Next, you must be aware of repository context: if the repository is new
and no commit has occurred yet, then `git restore --staged` won’t work,
but `gunstage` will.

.Enter
[source,zsh]
----
gunstage # 🔫 git unstage as a service
git unstage # 🔫 it just works!
----
Its name is an abbreviation and portmanteau of `git unstage` arising by
analog from
https://github.com/ohmyzsh/ohmyzsh/blob/c99f3c50fa46a93be28be88632889404fff3b958/plugins/git/README.md#aliases[Oh My Zsh’s
other Git aliases^].

How
~~~
The scripts are written in Bourne shell-flavored, KornShell- and Zsh-compatible
Bash, which is masquerading as Z shell with a `.zsh` filename extension so
Oh My Zsh recognizes it as a plugin. What does that mean? The
syntax is
https://github.com/mcornella/dotfiles/blob/51feef648a2d68a82348ed4753ac3d6b65972510/zshenv#L10-L11[as
low-tech as possible^] while performing sophisticated work to do one thing and
do it well: `git unstage`.

Installation
^^^^^^^^^^^^
`gunstage` can be
https://gist.github.com/06009589d7887617e061481e22cf5a4a[installed as a
plugin^], https://fig.io/plugins/other/gunstage_LucasLarson[installed
using Fig^], or you can just clone this repository, run the following
command, and then restart your terminal:
[source,zsh]
----
$ printf '%s\n' '. /path/to/gunstage.plugin.zsh' \
>>"${HOME%/}"'/.'"${SHELL##*[-./]}"'rc'
----

Requirements
~~~~~~~~~~~~
* https://github.com/zsh-users/zsh/tree/zsh-5.8[Zsh 5.8^] (or
https://github.com/att/ast/tree/ksh93u[Ksh 93^] (or
https://git.sv.gnu.org/cgit/bash.git/commit/?h=bash-5.0[Bash 5.0^])),
and
* https://github.com/git/git/tree/v2.17.0[Git 2.17^].

Testing
~~~~~~~
I tested `gunstage` atop Zsh 5.8 and Bash 3.2 using Git:

* 2.17 on Ubuntu 18.04,
* 2.20 on Debian 9.12,
* 2.28, 2.29, and 2.30 on macOS 11.0 and Alpine 3.11 and 3.12,
and

From macOS, I use https://github.com/gnachman/iTerm2[iTerm2^]; from iOS, I
use https://github.com/ish-app/ish[iSH^].

Credit
~~~~~~
This repository’s
https://web.archive.org/web/20220120220252/socialsharepreview.com/?url=https%3A%2F%2Fgithub.com%2FLucasLarson%2Fgunstage[preview
image^] was created by
https://github.com/twitter/twemoji/blob/7c1d3e9/2/svg/1f52b.svg[Twitter^]
in 2018.