feat: add git-continue (#1176)
Some checks are pending
ci / lint (push) Waiting to run
ci / typo (push) Waiting to run
ci / test (push) Waiting to run
ci / build (macos-latest) (push) Waiting to run
ci / build (ubuntu-latest) (push) Waiting to run

* feat: add git-continue

Also refactor `git-abort` to parse action from the called file name.

There's a promise for this in #865 but that was a long time ago.

* fix: add git-continue

address review comments, fix the script, remove unnecessary testpath
import.
This commit is contained in:
oikarinen 2024-11-28 10:50:29 +02:00 committed by GitHub
parent c23da8ae9c
commit 2f4b57d52b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 314 additions and 20 deletions

View file

@ -12,6 +12,7 @@
- [`git clear-soft`](#git-clear-soft)
- [`git coauthor`](#git-coauthor)
- [`git commits-since`](#git-commits-since)
- [`git continue`](#git-continue)
- [`git contrib`](#git-contrib)
- [`git count`](#git-count)
- [`git cp`](#git-cp)
@ -415,9 +416,9 @@ $ git coauthor user user@email.com
2 files changed, 145 insertions(+), 0 deletions(-)
create mode 100644 README.md
create mode 100644 CONTRIBUTING.md
$ git log -1
commit b62ceae2685e6ece071f3c3754e9b77fd0a35c88 (HEAD -> master)
Author: user person <userperson@email.com>
Date: Sat Aug 17 17:33:53 2019 -0500
@ -1368,7 +1369,7 @@ Switched to branch 'mr/51'
With full URL, the head is fetched from a temporary remote pointing to the base URL.
``` bash
$ git mr https://gitlab.com/owner/repository/merge_requests/51
$ git mr https://gitlab.com/owner/repository/merge_requests/51
From gitlab.com:owner/repository
* [new ref] refs/merge-requests/51/head -> mr/51
Switched to branch 'mr/51'
@ -1623,3 +1624,7 @@ Abort current revert, rebase, merge or cherry-pick, without the need to find exa
## git magic
Commits changes with a generated message.
## git continue
Continue current revert, rebase, merge or cherry-pick, without the need to find exact command in history.

View file

@ -1,17 +1,42 @@
#!/usr/bin/env bash
gitdir="$(git rev-parse --git-dir)" || exit
opfound=
fcnt=
for i in cherry-pick merge rebase revert; do
f=${i^^}
f=${f/-/_}
test -f "${gitdir}/${f}_HEAD" && fcnt=1$fcnt && opfound=$i
done
set -euo pipefail
if [ "${fcnt}" != 1 ]; then
echo "I don't know what to abort" >&2
exit 1
fi
function discover_op() {
local gitdir
# git rev-parse emits an error if not in a git repo so only need to bail out
gitdir="$(git rev-parse --git-dir)" || exit
local op
for op in cherry_pick merge rebase revert ; do
if [ -f "${gitdir}/${op^^}_HEAD" ]; then
echo "${op/_/-}"
fi
done
}
git "${opfound}" --abort
function validate_op() {
local op="$1"
if [ -z "$op" ]; then
echo "No active operation found" >&2
exit 1
fi
if [[ "$(echo "$op" | wc -l)" -gt 1 ]]; then
echo "Multiple active operations found: $op" >&2
exit 1
fi
}
function discover_action() {
local action=${1/git-/}
if [ "$action" != "abort" ] && [ "$action" != "continue" ]; then
echo "Invalid action: $1" >&2
exit 1
fi
echo "$action"
}
action=$(discover_action "$(basename "$0")")
op=$(discover_op)
validate_op "$op"
git "$op" "--$action"

1
bin/git-continue Symbolic link
View file

@ -0,0 +1 @@
git-abort

View file

@ -379,6 +379,7 @@ zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
clear:'rigorously clean up a repository' \
coauthor:'add a co-author to the last commit' \
commits-since:'show commit logs since some date' \
continue:'continue current revert, merge, rebase, or cherry-pick process' \
contrib:'show user contributions' \
count:'show commit count' \
create-branch:'create branches' \

19
man/git-continue.1 Normal file
View file

@ -0,0 +1,19 @@
.\" generated with Ronn-NG/v0.8.0
.\" http://github.com/apjanke/ronn-ng/tree/0.8.0
.TH "GIT\-CONTINUE" "1" "November 2024" "" "Git Extras"
.SH "NAME"
\fBgit\-continue\fR \- Continue current git operation
.SH "SYNOPSIS"
\fBgit\-continue\fR
.SH "DESCRIPTION"
Continue current git revert, rebase, merge or cherry\-pick process\.
.SH "OPTIONS"
There are no options, it just continues current operation\.
.SH "EXAMPLES"
\fBgit\-continue\fR
.SH "AUTHOR"
Written by oikarinen
.SH "REPORTING BUGS"
<\fI\%https://github\.com/tj/git\-extras/issues\fR>
.SH "SEE ALSO"
<\fI\%https://github\.com/tj/git\-extras\fR>

114
man/git-continue.html Normal file
View file

@ -0,0 +1,114 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf8'>
<meta name='generator' content='Ronn-NG/v0.8.0 (http://github.com/apjanke/ronn-ng/tree/0.8.0)'>
<title>git-continue(1) - Continue current git operation</title>
<style type='text/css' media='all'>
/* style: man */
body#manpage {margin:0}
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
.mp h2 {margin:10px 0 0 0}
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
.mp h3 {margin:0 0 0 4ex}
.mp dt {margin:0;clear:left}
.mp dt.flush {float:left;width:8ex}
.mp dd {margin:0 0 0 9ex}
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
.mp pre {margin-bottom:20px}
.mp pre+h2,.mp pre+h3 {margin-top:22px}
.mp h2+pre,.mp h3+pre {margin-top:5px}
.mp img {display:block;margin:auto}
.mp h1.man-title {display:none}
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
.mp h2 {font-size:16px;line-height:1.25}
.mp h1 {font-size:20px;line-height:2}
.mp {text-align:justify;background:#fff}
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
.mp u {text-decoration:underline}
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
.mp b.man-ref {font-weight:normal;color:#434241}
.mp pre {padding:0 4ex}
.mp pre code {font-weight:normal;color:#434241}
.mp h2+pre,h3+pre {padding-left:0}
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
ol.man-decor {width:100%}
ol.man-decor li.tl {text-align:left}
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
ol.man-decor li.tr {text-align:right;float:right}
</style>
</head>
<!--
The following styles are deprecated and will be removed at some point:
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
.man-navigation should be used instead.
-->
<body id='manpage'>
<div class='mp' id='man'>
<div class='man-navigation' style='display:none'>
<a href="#NAME">NAME</a>
<a href="#SYNOPSIS">SYNOPSIS</a>
<a href="#DESCRIPTION">DESCRIPTION</a>
<a href="#OPTIONS">OPTIONS</a>
<a href="#EXAMPLES">EXAMPLES</a>
<a href="#AUTHOR">AUTHOR</a>
<a href="#REPORTING-BUGS">REPORTING BUGS</a>
<a href="#SEE-ALSO">SEE ALSO</a>
</div>
<ol class='man-decor man-head man head'>
<li class='tl'>git-continue(1)</li>
<li class='tc'>Git Extras</li>
<li class='tr'>git-continue(1)</li>
</ol>
<h2 id="NAME">NAME</h2>
<p class="man-name">
<code>git-continue</code> - <span class="man-whatis">Continue current git operation</span>
</p>
<h2 id="SYNOPSIS">SYNOPSIS</h2>
<p><code>git-continue</code></p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p> Continue current git revert, rebase, merge or cherry-pick process.</p>
<h2 id="OPTIONS">OPTIONS</h2>
<p> There are no options, it just continues current operation.</p>
<h2 id="EXAMPLES">EXAMPLES</h2>
<p> <code>git-continue</code></p>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Written by oikarinen</p>
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
<p>&lt;<a href="https://github.com/tj/git-extras/issues" data-bare-link="true">https://github.com/tj/git-extras/issues</a>&gt;</p>
<h2 id="SEE-ALSO">SEE ALSO</h2>
<p>&lt;<a href="https://github.com/tj/git-extras" data-bare-link="true">https://github.com/tj/git-extras</a>&gt;</p>
<ol class='man-decor man-foot man foot'>
<li class='tl'></li>
<li class='tc'>November 2024</li>
<li class='tr'>git-continue(1)</li>
</ol>
</div>
</body>
</html>

30
man/git-continue.md Normal file
View file

@ -0,0 +1,30 @@
git-continue(1) -- Continue current git operation
================================
## SYNOPSIS
`git-continue`
## DESCRIPTION
Continue current git revert, rebase, merge or cherry-pick process.
## OPTIONS
There are no options, it just continues current operation.
## EXAMPLES
`git-continue`
## AUTHOR
Written by oikarinen
## REPORTING BUGS
&lt;<https://github.com/tj/git-extras/issues>&gt;
## SEE ALSO
&lt;<https://github.com/tj/git-extras>&gt;

View file

@ -49,6 +49,8 @@ Change the default branch to \fB$BRANCH\fR\. If \fBgit\-extras\.default\-branch\
.IP "\[ci]" 4
\fBgit\-commits\-since(1)\fR Show commit logs since some date
.IP "\[ci]" 4
\fBgit\-continue(1)\fR Continue current git operation
.IP "\[ci]" 4
\fBgit\-contrib(1)\fR Show user's contributions
.IP "\[ci]" 4
\fBgit\-count(1)\fR Show commit count

View file

@ -69,7 +69,7 @@
<li class='tr'>git-extras(1)</li>
</ol>
<h2 id="NAME">NAME</h2>
<p class="man-name">
@ -131,6 +131,8 @@
<li>
<strong><a class="man-ref" href="git-commits-since.html">git-commits-since<span class="s">(1)</span></a></strong> Show commit logs since some date</li>
<li>
<strong><a class="man-ref" href="git-continue.html">git-continue<span class="s">(1)</span></a></strong> Continue current git operation</li>
<li>
<strong><a class="man-ref" href="git-contrib.html">git-contrib<span class="s">(1)</span></a></strong> Show user's contributions</li>
<li>
<strong><a class="man-ref" href="git-count.html">git-count<span class="s">(1)</span></a></strong> Show commit count</li>

View file

@ -40,6 +40,7 @@ git-extras(1) -- Awesome GIT utilities
- **git-clear(1)** Rigorously clean up a repository
- **git-coauthor(1)** Add a co-author to the last commit
- **git-commits-since(1)** Show commit logs since some date
- **git-continue(1)** Continue current git operation
- **git-contrib(1)** Show user's contributions
- **git-count(1)** Show commit count
- **git-cp(1)** Copy a file keeping its history

View file

@ -13,6 +13,7 @@ git-clear(1) git-clear
git-coauthor(1) git-coauthor
git-commits-since(1) git-commits-since
git-contrib(1) git-contrib
git-continue(1) git-continue
git-count(1) git-count
git-cp(1) git-cp
git-create-branch(1) git-create-branch

View file

@ -22,7 +22,8 @@ It is done or go without `poetry`,
1. Install python >= 3.11
2. Install pytest >= 8.1.2
3. Install gitpython >= 3.1.43
4. Run `pytest`
4. Install testpath >= 0.6.0
5. Run `pytest`
The second way maybe blocked the some missing dependencies at someday, so the first one is recommended.

View file

@ -7,8 +7,8 @@ from helper import TempRepository
def create_repo(dirname=None):
repo = TempRepository(dirname)
repo.create_tmp_file()
repo.create_tmp_file()
repo.create_tmp_file() # tmp_file_a
repo.create_tmp_file() # tmp_file_b
repo.switch_cwd_under_repo()
return repo
@ -35,3 +35,11 @@ def named_temp_repo(request):
init_repo_git_status(repo)
yield repo
repo.teardown()
@pytest.fixture(scope="function")
def temp_repo_clean():
"""Create a temporary repository that is reset for each function call."""
repo = create_repo()
init_repo_git_status(repo)
return repo

View file

@ -0,0 +1,84 @@
from git import GitCommandError
class TestGitContinue:
@classmethod
def _init_repo(cls, repo):
git = repo.get_repo_git()
tmp_file = repo.get_file(0)
git.branch("A")
git.branch("B")
git.branch("C")
git.checkout("A")
repo.writefile(tmp_file, "a")
git.add(".")
git.commit("-m", "A")
git.checkout("B")
repo.writefile(tmp_file, "b")
git.add(".")
git.commit("-m", "B")
def test_init(self, temp_repo_clean):
TestGitContinue._init_repo(temp_repo_clean)
git = temp_repo_clean.get_repo_git()
git.status()
def test_cherry_pick(self, temp_repo_clean):
TestGitContinue._init_repo(temp_repo_clean)
git = temp_repo_clean.get_repo_git()
try:
git.cherry_pick("A")
except GitCommandError as err:
print(err)
result = git.status()
assert "Unmerged path" in result
git.add(".")
temp_repo_clean.invoke_extras_command("continue")
result = git.status()
assert "nothing to commit, working tree clean" in result
def test_merge(self, temp_repo_clean):
TestGitContinue._init_repo(temp_repo_clean)
git = temp_repo_clean.get_repo_git()
try:
git.merge("A")
except GitCommandError as err:
print(err)
result = git.status()
assert "Unmerged path" in result
git.add(".")
git.commit("-m", "resolve conflict")
temp_repo_clean.invoke_extras_command("continue")
result = git.status()
assert "nothing to commit, working tree clean" in result
def test_rebase(self, temp_repo_clean):
TestGitContinue._init_repo(temp_repo_clean)
git = temp_repo_clean.get_repo_git()
try:
git.rebase("A")
except GitCommandError as err:
print(err)
result = git.status()
assert "Unmerged path" in result
git.add(".")
git.commit("-m", "resolve conflict")
temp_repo_clean.invoke_extras_command("continue")
result = git.status()
assert "nothing to commit, working tree clean" in result
def test_revert(self, temp_repo_clean):
TestGitContinue._init_repo(temp_repo_clean)
git = temp_repo_clean.get_repo_git()
try:
git.revert("A")
except GitCommandError as err:
print(err)
result = git.status()
assert "Unmerged path" in result
git.add(".")
git.commit("-m", "resolve conflict")
temp_repo_clean.invoke_extras_command("continue")
result = git.status()
assert "nothing to commit, working tree clean" in result