Skip to content

Commit a54255e

Browse files
committed
Add actualize-work command
The command aims to simplify work with obsolete branches as it provides a convenient way to actualize them.
1 parent 1642f1c commit a54255e

8 files changed

Lines changed: 233 additions & 2 deletions

File tree

completions/_git-elegant

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ _git-elegant (){
1414
'accept-work:adds modifications to the default development branch'
1515
'acquire-git:configures your Git installation'
1616
'acquire-repository:configures the current local Git repository'
17+
'actualize-work:actualizes the current branch with upstream commits'
1718
'amend-work:amends the last commit'
1819
'clone-repository:clones a remote repository and configures it'
1920
'deliver-work:publishes HEAD to a remote repository'
@@ -64,7 +65,7 @@ __ge_complete_commands () {
6465
# default completion is empty
6566
case ${line[1]} in
6667
obtain-work) __ge_remotes ;;
67-
accept-work) __ge_all_branches ;;
68+
accept-work|actualize-work) __ge_all_branches ;;
6869
show-release-notes) __ge_show_release_notes ;;
6970
start-work) __ge_start_work ;;
7071
make-workflow) __ge_make_workflow ;;

completions/git-elegant.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ _git_elegant() {
3232
$(compgen -W "${opts[*]}" -- ${cursor})
3333
)
3434
;;
35-
accept-work)
35+
accept-work|actualize-work)
3636
local opts=(
3737
${gecops}
3838
$(git branch --all --format='%(refname:short)')

docs/commands.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ There are commands used in various situations such as
3434
amend-work Amends the last commit.
3535
show-work Prints HEAD state.
3636
polish-work Rebases HEAD interactively.
37+
actualize-work Actualizes the current branch with upstream commits.
3738
3839
interact with others
3940
deliver-work Publishes HEAD to a remote repository.
@@ -132,6 +133,34 @@ applies all configurations to the current local repository.
132133
To find out what will be configured, please visit
133134
<https://elegant-git.bees-hive.org/en/latest/configuration/>
134135

136+
# `actualize-work`
137+
138+
```bash
139+
usage: git elegant actualize-work [branch-name]
140+
```
141+
142+
Rebases the head of the upstream branch into the current one. By default, the
143+
upstream branch is the default development branch.
144+
145+
A `[branch-name]` argument allows you to redefine the upstream branch. It
146+
supports both local and remote branches.
147+
148+
If the upstream branch has a remote-tracking branch or is a remote branch, it
149+
fetches before making a rebase.
150+
151+
If there is a rebase in progress initiated by this command, it will be
152+
continued prior to running the main logic.
153+
154+
The command uses stash pipe to preserve the current Git state prior to execution
155+
and restore after.
156+
157+
Approximate commands flow is
158+
```bash
159+
==>> git elegant actualize-work origin/some-work
160+
git fetch
161+
git rebase origin/some-work
162+
```
163+
135164
# `amend-work`
136165

137166
```bash

libexec/git-elegant

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ $(--print-command-in-usage save-work)
8282
$(--print-command-in-usage amend-work)
8383
$(--print-command-in-usage show-work)
8484
$(--print-command-in-usage polish-work)
85+
$(--print-command-in-usage actualize-work)
8586
8687
interact with others
8788
$(--print-command-in-usage deliver-work)

libexec/git-elegant-actualize-work

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
command-purpose() {
5+
cat <<MESSAGE
6+
Actualizes the current branch with upstream commits.
7+
MESSAGE
8+
}
9+
10+
command-synopsis() {
11+
cat <<MESSAGE
12+
usage: git elegant actualize-work [branch-name]
13+
MESSAGE
14+
}
15+
16+
command-description() {
17+
cat<<MESSAGE
18+
Rebases the head of the upstream branch into the current one. By default, the
19+
upstream branch is the default development branch.
20+
21+
A \`[branch-name]\` argument allows you to redefine the upstream branch. It
22+
supports both local and remote branches.
23+
24+
If the upstream branch has a remote-tracking branch or is a remote branch, it
25+
fetches before making a rebase.
26+
27+
If there is a rebase in progress initiated by this command, it will be
28+
continued prior to running the main logic.
29+
30+
The command uses stash pipe to preserve the current Git state prior to execution
31+
and restore after.
32+
33+
Approximate commands flow is
34+
\`\`\`bash
35+
==>> git elegant actualize-work origin/some-work
36+
git fetch
37+
git rebase origin/some-work
38+
\`\`\`
39+
MESSAGE
40+
}
41+
42+
--fetch() {
43+
git-verbose fetch || info-text "Unable to fetch. The last local revision will be used."
44+
}
45+
46+
--logic() {
47+
source ${BINS}/plugins/state
48+
if is-there-active-rebase
49+
then
50+
git-verbose rebase --continue
51+
fi
52+
source ${BINS}/plugins/configuration-default-branches
53+
source ${BINS}/plugins/state
54+
if test -n "${1}"
55+
then
56+
if is-remote-branch ${1}
57+
then
58+
--fetch
59+
git-verbose rebase ${1}
60+
elif is-there-upstream-for ${1}
61+
then
62+
--fetch
63+
git-verbose rebase $(upstream-of ${1}) ${1}
64+
git-verbose rebase ${1}
65+
else
66+
git-verbose rebase ${1}
67+
fi
68+
elif are-there-remotes
69+
then
70+
--fetch
71+
git-verbose rebase ${DEFAULT_REMOTE_TRACKING_BRANCH}
72+
else
73+
git-verbose rebase ${DEFAULT_BRANCH}
74+
fi
75+
}
76+
77+
default() {
78+
stash-pipe --logic "${@}"
79+
}

libexec/plugins/state

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ is-there-upstream-for() {
3434
git rev-parse --abbrev-ref ${1}@{upstream} >/dev/null 2>&1
3535
}
3636

37+
upstream-of() {
38+
# usage: $(upstream-of <branch ref>)
39+
git rev-parse --abbrev-ref ${1}@{upstream} 2>/dev/null || true
40+
}
41+
42+
is-remote-branch() {
43+
# usage: is-remote-branch <branch ref>
44+
test -n "$(git for-each-ref refs/remotes/${1})"
45+
}
46+
3747
are-there-remotes() {
3848
if test -z "$(git remote)"; then
3949
return 1
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env bats
2+
3+
load addons-common
4+
load addons-fake
5+
load addons-repo
6+
7+
setup() {
8+
repo-new
9+
}
10+
11+
teardown() {
12+
repo-clean
13+
fake-clean
14+
}
15+
16+
@test "'actualize-work': makes a rebase of the default local branch if there is no remote repository" {
17+
fake-pass "git rebase master"
18+
check git-elegant actualize-work
19+
[[ ${status} -eq 0 ]]
20+
[[ ! ${lines[*]} =~ "git fetch" ]]
21+
[[ ${lines[*]} =~ "git rebase master" ]]
22+
}
23+
24+
@test "'actualize-work': makes a rebase of the default remote branch if there is a remote repository" {
25+
fake-pass "git remote" "origin"
26+
fake-pass "git rebase origin/master"
27+
fake-fail "git rebase master"
28+
check git-elegant actualize-work
29+
[[ ${status} -eq 0 ]]
30+
[[ ${lines[*]} =~ "git fetch" ]]
31+
[[ ${lines[*]} =~ "git rebase origin/master" ]]
32+
}
33+
34+
@test "'actualize-work': uses local revision of the default remote branch if the fetch is failed" {
35+
fake-pass "git remote" "origin"
36+
fake-fail "git fetch"
37+
fake-pass "git rebase origin/master"
38+
fake-fail "git rebase master"
39+
check git-elegant actualize-work
40+
[[ ${status} -eq 0 ]]
41+
[[ ${lines[*]} =~ "git fetch" ]]
42+
[[ ${lines[*]} =~ "Unable to fetch. The last local revision will be used." ]]
43+
[[ ${lines[*]} =~ "git rebase origin/master" ]]
44+
}
45+
46+
@test "'actualize-work': makes a rebase of the given local branch without remote-tracking branch" {
47+
fake-pass "git rebase branch"
48+
check git-elegant actualize-work branch
49+
[[ ${status} -eq 0 ]]
50+
[[ ${lines[*]} =~ "git rebase branch" ]]
51+
[[ ! ${lines[*]} =~ "git fetch" ]]
52+
}
53+
54+
@test "'actualize-work': makes a rebase of the given local branch with remote-tracking branch" {
55+
fake-pass "git rev-parse --abbrev-ref rt@{upstream}"
56+
fake-pass "git fetch"
57+
fake-pass "git rev-parse --abbrev-ref rt@{upstream}" "origin/rt"
58+
fake-pass "git rebase origin/rt rt"
59+
fake-pass "git rebase rt"
60+
check git-elegant actualize-work rt
61+
[[ ${status} -eq 0 ]]
62+
[[ ${lines[*]} =~ "git fetch" ]]
63+
[[ ${lines[*]} =~ "git rebase origin/rt rt" ]]
64+
[[ ${lines[*]} =~ "git rebase rt" ]]
65+
}
66+
67+
@test "'actualize-work': makes a rebase of the given remote-tracking branch" {
68+
fake-pass "git for-each-ref refs/remotes/only/remote" "true"
69+
fake-pass "git fetch"
70+
fake-pass "git rebase only/remote"
71+
check git-elegant actualize-work only/remote
72+
[[ ${status} -eq 0 ]]
73+
[[ ${lines[*]} =~ "git fetch" ]]
74+
[[ ${lines[*]} =~ "git rebase only/remote" ]]
75+
}
76+
77+
@test "'actualize-work': uses local revision of thegiven remote-tracking branch if the fetch is failed" {
78+
fake-pass "git rev-parse --abbrev-ref rt@{upstream}"
79+
fake-fail "git fetch"
80+
fake-pass "git rev-parse --abbrev-ref rt@{upstream}" "origin/rt"
81+
fake-pass "git rebase origin/rt rt"
82+
fake-pass "git rebase rt"
83+
check git-elegant actualize-work rt
84+
[[ ${status} -eq 0 ]]
85+
[[ ${lines[*]} =~ "git fetch" ]]
86+
[[ ${lines[*]} =~ "Unable to fetch. The last local revision will be used." ]]
87+
[[ ${lines[*]} =~ "git rebase origin/rt rt" ]]
88+
[[ ${lines[*]} =~ "git rebase rt" ]]
89+
}
90+
91+
@test "'actualize-work': uses stash pipe if uncommited changes are present" {
92+
repo-non-staged-change "A new line..."
93+
check git-elegant actualize-work
94+
[[ ${status} -eq 0 ]]
95+
[[ ${lines[@]} =~ "git stash push --message git-elegant actualize-work auto-stash:" ]]
96+
[[ ! ${lines[*]} =~ "git fetch" ]]
97+
[[ ${lines[*]} =~ "git rebase master" ]]
98+
[[ ${lines[@]} =~ "git stash pop" ]]
99+
}
100+
101+
@test "'actualize-work': continues an existing rebase process there is an active rebase process" {
102+
repo "git checkout -b feature1"
103+
repo "git commit --allow-empty --message First"
104+
repo "git commit --allow-empty --message Second"
105+
repo "git rebase --exec 'grep bla-bla *.txt' @~1 || true "
106+
check git-elegant actualize-work
107+
[[ ${status} -eq 0 ]]
108+
[[ ${lines[@]} =~ "git rebase --continue" ]]
109+
[[ ${lines[@]} =~ "git rebase master" ]]
110+
}

tests/git-elegant-show-commands.bats

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ teardown() {
3232
"show-workflows"
3333
"make-workflow"
3434
"polish-workflow"
35+
"actualize-work"
3536
)
3637
check git-elegant show-commands
3738
[[ ${#lines[@]} -eq ${#COMMANDS[@]} ]]

0 commit comments

Comments
 (0)