mirror of
https://github.com/tj/git-extras.git
synced 2026-09-13 08:56:19 -04:00
Add persistent history to git-repl (#1226)
* persistent command history
* notes
* decision on which commands to save
* configurable history location
* fix history initialization in various scenarios
* documentation
* comment
* don't add whitespace or consecutive duplicates to history
* fix manpage output
* Update bin/git-repl
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
* Update bin/git-repl
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
* Update git-repl
* Update bin/git-repl
* Apply suggestions from code review
* Add `extglob` and generate docs
* Fix regex
* update docs
rm man/git-repl.{1,html}
touch man/git-repl.md
make man/git-repl.{1,html}
---------
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
This commit is contained in:
parent
5367101f2e
commit
032090e847
13
Commands.md
13
Commands.md
|
|
@ -392,6 +392,19 @@ Type `exit`, `quit`, or `q` to end the repl session.
|
|||
Any arguments to git repl will be taken as the first command to execute in
|
||||
the repl.
|
||||
|
||||
### CONFIGURATION
|
||||
|
||||
Commands entered in a repl session will be saved to a history file and be available in
|
||||
future sessions, similar to a shell or programming language repl. By default,
|
||||
there is one global history file, ~/.git_repl_history. You can specify that your projects
|
||||
each have their own independent history file. This file will be saved in .git_repl_history
|
||||
at the top level of the repo, and will need to be added to the repo or global .gitignore.
|
||||
|
||||
```bash
|
||||
# remove the --global flag to configure only an individual project to have its own history file
|
||||
git config --global git-extras.repl.use-local-history "true"
|
||||
```
|
||||
|
||||
You can specify a default command to run when hitting enter:
|
||||
|
||||
```bash
|
||||
|
|
|
|||
25
bin/git-repl
25
bin/git-repl
|
|
@ -1,9 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
shopt -s extglob
|
||||
|
||||
git version
|
||||
echo "git-extras version ""$(git-extras -v)"
|
||||
echo "Type 'ls' to ls files below current directory; '!command' to execute any command or just 'subcommand' to execute any git subcommand; 'quit', 'exit', 'q', ^D, or ^C to exit the git repl."
|
||||
|
||||
HISTIGNORE=${HISTIGNORE:-+([[:space:]])}
|
||||
HISTCONTROL=${HISTCONTROL:-ignoredups}
|
||||
use_local_history=$(git config --get --default 'false' git-extras.repl.use-local-history)
|
||||
if [[ "$use_local_history" == "true" ]]; then
|
||||
HISTFILE="$(git rev-parse --show-toplevel)/.git_extras_repl_history"
|
||||
else
|
||||
HISTFILE=${XDG_STATE_HOME:-$HOME/.local/state}/git_extras_repl_history
|
||||
fi
|
||||
|
||||
# file doesn't exist, is empty, or contains only whitespace
|
||||
if [[ ! -f "$HISTFILE" ]] || [[ ! -s "$HISTFILE" ]] || ! grep -q '[^[:space:]]' "$HISTFILE"; then
|
||||
# `history -r` .... `history -a` are not happy with an empty initial file in bash 3.2.57, which is what MacOS 26 ships with
|
||||
echo '!echo welcome to git-repl!' >> "$HISTFILE"
|
||||
fi
|
||||
history -r
|
||||
|
||||
while true; do
|
||||
# Current branch
|
||||
cur=$(git symbolic-ref HEAD 2> /dev/null | cut -d/ -f3-)
|
||||
|
|
@ -46,8 +63,10 @@ while true; do
|
|||
test $? -ne 0 && break
|
||||
fi
|
||||
|
||||
# History
|
||||
history -s "$cmd"
|
||||
# Add command to history if it is not all whitespace
|
||||
if [[ ! "$cmd" =~ ^[[:space:]]*$ ]]; then
|
||||
history -s "$cmd"
|
||||
fi
|
||||
|
||||
# Built-in commands
|
||||
case $cmd in
|
||||
|
|
@ -63,6 +82,8 @@ while true; do
|
|||
quit|exit|q) break;;
|
||||
esac
|
||||
|
||||
history -a
|
||||
|
||||
if [[ $cmd == !* ]]; then
|
||||
# shellcheck disable=SC2086
|
||||
eval ${cmd:1}
|
||||
|
|
|
|||
183
man/git-extras.1
183
man/git-extras.1
|
|
@ -1,183 +0,0 @@
|
|||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "GIT\-EXTRAS" "1" "May 2025" "" "Git Extras"
|
||||
.SH "NAME"
|
||||
\fBgit\-extras\fR \- Awesome GIT utilities
|
||||
.SH "SYNOPSIS"
|
||||
\fBgit\-extras\fR [\-v,\-\-version] [\-h,\-\-help] [update]
|
||||
.SH "OPTIONS"
|
||||
\-v, \-\-version
|
||||
.P
|
||||
Show git\-extras version number\.
|
||||
.P
|
||||
\-h, \-\-help
|
||||
.P
|
||||
Show this help\. This option can also be used for any of the extras commands\.
|
||||
.P
|
||||
update
|
||||
.P
|
||||
Self update\.
|
||||
.SH "ENVIRONMENT AND CONFIGURATION VARIABLES"
|
||||
\fBgit config \-\-add git\-extras\.default\-branch $BRANCH\fR
|
||||
.P
|
||||
Change the default branch to \fB$BRANCH\fR\. If \fBgit\-extras\.default\-branch\fR isn't set, \fBinit\.defaultBranch\fR is used instead\. If none of them are set it defaults to \fBmain\fR\.
|
||||
.SH "COMMANDS"
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-abort(1)\fR Abort current git operation
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-alias(1)\fR Define, search and show aliases
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-archive\-file(1)\fR Export the current HEAD of the git repository to an archive
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-authors(1)\fR Generate authors report
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-browse\-ci(1)\fR \fIView the web page for the current repository\fR
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-browse(1)\fR \fIView the web page for the current repository\fR
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-brv(1)\fR List branches sorted by their last commit date
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-bulk(1)\fR Run git commands on multiple repositories
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-changelog(1)\fR Generate a changelog report
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-clear\-soft(1)\fR Soft clean up a repository
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-clear(1)\fR Rigorously clean up a repository
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-coauthor(1)\fR Add a co\-author to the last commit
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-commits\-since(1)\fR Show commit logs since some date
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-continue(1)\fR Continue current git operation
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-contrib(1)\fR Show user's contributions
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-count(1)\fR Show commit count
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-cp(1)\fR Copy a file keeping its history
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-create\-branch(1)\fR Create branches
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-delete\-branch(1)\fR Delete branches
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-delete\-merged\-branches(1)\fR Delete merged branches
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-delete\-squashed\-branches(1)\fR Delete branches that were squashed
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-delete\-submodule(1)\fR Delete submodules
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-delete\-tag(1)\fR Delete tags
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-delta(1)\fR Lists changed files
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-effort(1)\fR Show effort statistics on file(s)
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-feature(1)\fR Create/Merge feature branch
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-force\-clone(1)\fR overwrite local repositories with clone
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-fork(1)\fR Fork a repo on github
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-fresh\-branch(1)\fR Create fresh branches
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-get(1)\fR Clone a Git repository under a configured directory
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-gh\-pages(1)\fR Create the GitHub Pages branch
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-graft(1)\fR Merge and destroy a given branch
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-guilt(1)\fR calculate change between two revisions
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-ignore\-io(1)\fR Get sample gitignore file
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-ignore(1)\fR Add \.gitignore patterns
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-info(1)\fR Returns information on current repository
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-local\-commits(1)\fR List local commits
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-lock(1)\fR Lock a file excluded from version control
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-locked(1)\fR ls files that have been locked
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-magic(1)\fR Automate add/commit/push routines
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-merge\-into(1)\fR Merge one branch into another
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-merge\-repo(1)\fR Merge two repo histories
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-missing(1)\fR Show commits missing from another branch
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-mr(1)\fR Checks out a merge request locally
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-obliterate(1)\fR rewrite past commits to remove some files
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-paste(1)\fR Send patches to pastebin for chat conversations
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-pr(1)\fR Checks out a pull request locally
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-psykorebase(1)\fR Rebase a branch with a merge commit
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-pull\-request(1)\fR Create pull request for GitHub project
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-reauthor(1)\fR Rewrite history to change author's identity
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-rebase\-patch(1)\fR Rebases a patch
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-release(1)\fR Commit, tag and push changes to the repository
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-rename\-branch(1)\fR rename local branch and push to remote
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-rename\-file(1)\fR Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case\-sensitivity\.
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-rename\-remote(1)\fR Rename a remote
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-rename\-tag(1)\fR Rename a tag
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-repl(1)\fR git read\-eval\-print\-loop
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-reset\-file(1)\fR Reset one file
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-root(1)\fR show path of root
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-scp(1)\fR Copy files to SSH compatible \fBgit\-remote\fR
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-sed(1)\fR replace patterns in git\-controlled files
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-setup(1)\fR Set up a git repository
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-show\-merged\-branches(1)\fR Show merged branches
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-show\-tree(1)\fR show branch tree of commit history
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-show\-unmerged\-branches(1)\fR Show unmerged branches
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-squash(1)\fR squash N last changes up to a ref'ed commit
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-stamp(1)\fR Stamp the last commit message
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-standup(1)\fR Recall the commit history
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-summary(1)\fR Show repository summary
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-sync(1)\fR Sync local branch with remote branch
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-touch(1)\fR Touch and add file to the index
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-undo(1)\fR Remove latest commits
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-unlock(1)\fR Unlock a file excluded from version control
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-unwip(1)\fR Undo a Work In Progress commit
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-utimes(1)\fR Change files modification time to their last commit date
|
||||
.IP "\(bu" 4
|
||||
\fBgit\-wip(1)\fR Create a Work In Progress commit
|
||||
.IP "" 0
|
||||
.SH "AUTHOR"
|
||||
Written by Tj Holowaychuk <\fItj@vision\-media\.ca\fR>
|
||||
.SH "REPORTING BUGS"
|
||||
<\fIhttps://github\.com/tj/git\-extras/issues\fR>
|
||||
.SH "SEE ALSO"
|
||||
<\fIhttps://github\.com/tj/git\-extras\fR>
|
||||
|
|
@ -273,7 +273,7 @@
|
|||
|
||||
<ol class='man-decor man-foot man foot'>
|
||||
<li class='tl'></li>
|
||||
<li class='tc'>May 2025</li>
|
||||
<li class='tc'>February 2026</li>
|
||||
<li class='tr'>git-extras(1)</li>
|
||||
</ol>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.\" generated with Ronn-NG/v0.10.1
|
||||
.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
|
||||
.TH "GIT\-REPL" "1" "January 2026" "" "Git Extras"
|
||||
.TH "GIT\-REPL" "1" "February 2026" "" "Git Extras"
|
||||
.SH "NAME"
|
||||
\fBgit\-repl\fR \- git read\-eval\-print\-loop
|
||||
.SH "SYNOPSIS"
|
||||
|
|
@ -32,6 +32,14 @@ exit|quit|q
|
|||
.P
|
||||
Ends the repl session\.
|
||||
.SH "CONFIGURATION"
|
||||
Commands entered in a repl session will be saved to a history file and be available in future sessions, similar to a shell or programming language repl\. By default, the global history file is at \fB~/\.local/state/git_extras_repl_history\fR\. You can specify that your projects each have their own independent history file\. This file will be saved in \.git_repl_history at the top level of the repo, and will need to be added to the repo or global \.gitignore\.
|
||||
.IP "" 4
|
||||
.nf
|
||||
# remove the \-\-global flag to configure only an individual project to have its own history file
|
||||
git config \-\-global git\-extras\.repl\.use\-local\-history "true"
|
||||
.fi
|
||||
.IP "" 0
|
||||
.P
|
||||
You can specify a default command to run when hitting enter:
|
||||
.P
|
||||
\fBgit config \-\-global git\-extras\.repl\.on\-enter\-command "git status \-sb"\fR
|
||||
|
|
|
|||
|
|
@ -115,6 +115,16 @@
|
|||
|
||||
<h2 id="CONFIGURATION">CONFIGURATION</h2>
|
||||
|
||||
<p>Commands entered in a repl session will be saved to a history file and be available in
|
||||
future sessions, similar to a shell or programming language repl. By default,
|
||||
the global history file is at <code>~/.local/state/git_extras_repl_history</code>. You can specify that your projects
|
||||
each have their own independent history file. This file will be saved in .git_repl_history
|
||||
at the top level of the repo, and will need to be added to the repo or global .gitignore.</p>
|
||||
|
||||
<pre><code class="language-bash"> # remove the --global flag to configure only an individual project to have its own history file
|
||||
git config --global git-extras.repl.use-local-history "true"
|
||||
</code></pre>
|
||||
|
||||
<p>You can specify a default command to run when hitting enter:</p>
|
||||
|
||||
<p><code>git config --global git-extras.repl.on-enter-command "git status -sb"</code></p>
|
||||
|
|
@ -170,7 +180,7 @@ git (master)> quit
|
|||
|
||||
<ol class='man-decor man-foot man foot'>
|
||||
<li class='tl'></li>
|
||||
<li class='tc'>January 2026</li>
|
||||
<li class='tc'>February 2026</li>
|
||||
<li class='tr'>git-repl(1)</li>
|
||||
</ol>
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,17 @@ git-repl(1) -- git read-eval-print-loop
|
|||
|
||||
## CONFIGURATION
|
||||
|
||||
Commands entered in a repl session will be saved to a history file and be available in
|
||||
future sessions, similar to a shell or programming language repl. By default,
|
||||
the global history file is at `~/.local/state/git_extras_repl_history`. You can specify that your projects
|
||||
each have their own independent history file. This file will be saved in .git_repl_history
|
||||
at the top level of the repo, and will need to be added to the repo or global .gitignore.
|
||||
|
||||
```bash
|
||||
# remove the --global flag to configure only an individual project to have its own history file
|
||||
git config --global git-extras.repl.use-local-history "true"
|
||||
```
|
||||
|
||||
You can specify a default command to run when hitting enter:
|
||||
|
||||
`git config --global git-extras.repl.on-enter-command "git status -sb"`
|
||||
|
|
|
|||
Loading…
Reference in a new issue