Skip to content

Commit

Permalink
Provide a full or partial branch name when run accept-work
Browse files Browse the repository at this point in the history
Now `accept-work` can use either full or partial branch name. It's
because `obtain-work` is used as a checkout mechanism for the given
name.

This update has changed the previous implementation of `obtain-work`:
1. It works with remote branches only.
2. A local branch name is configurable.

#173
  • Loading branch information
extsoft committed Sep 3, 2019
1 parent 5fab792 commit adc329b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 70 deletions.
18 changes: 8 additions & 10 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Run `git elegant <command>` where `<command>` is one of
- [`save-work`](#save-work)
- [`deliver-work`](#deliver-work)
- [`accept-work`](#accept-work)
- [`pull`](#pull)
- [`obtain-work`](#obtain-work)
- [`clear-local`](#clear-local)
- [`amend-work`](#amend-work)
- [`commands`](#commands)
Expand Down Expand Up @@ -136,7 +136,7 @@ Accepts proposed work (remote work branch) on top of the fresh history of remote
successful work acceptance.

```bash
usage: git elegant accept-work <remote-branch>
usage: git elegant accept-work <full/partial branch name>
```
A sequence of original `git` commands:
```bash
Expand All @@ -152,21 +152,19 @@ git push origin --delete <remote-branch-name>
```

# `obtain-work`
Checkouts a local or remote branch matching against a pattern. It looks for local branches first, then for remotes ones.
If there are more then 1 matching branch, execution stops with a corresponding error message.
Checkouts a remote branch matching by a given full or partial name. If there are more then 1
matching branch, execution stops with a corresponding error message. By default, the name of the
local branch responds to the remote one. However, the name can be overridden by giving a second
command argument.

```bash
usage: git elegant obtain-work <pattern>
usage: git elegant obtain-work <full/partial branch name> [local branch name]
```

A sequence of original `git` commands:
```bash
# if a local branch matches a pattern
git checkout <branch name>
git pull
# if no local matches, seek through remotes
git fetch --all
git checkout <branch name>
git checkout -B <local branch> <remote branch>
```

# `amend-work`
Expand Down
5 changes: 5 additions & 0 deletions libexec/git-elegant
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ __batch() {
fi
}

branch-from-remote-reference() {
# usage: branch-from-remote-reference <full reference name>
echo ${1} | sed "s|^[a-zA-Z0-9_-]*/||g"
}

usage() {
echo "git elegant <command>"
git elegant commands
Expand Down
8 changes: 3 additions & 5 deletions libexec/git-elegant-accept-work
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ set -e


default() {
local WORK=${1}
_error-if-empty "${WORK}" "Please give a name of remote branch (like 'origin/123')."
local WORK_BRANCH="__eg"
boxtee git fetch --all --tags
boxtee git checkout --force -B ${WORK_BRANCH} ${WORK}
git elegant obtain-work "${1}" "${WORK_BRANCH}"
boxtee git status
boxtee git rebase ${RMASTER}
# @todo #137 Alternative flows of `accept-work`
Expand All @@ -16,9 +13,10 @@ default() {
# `${MASTER}` branch.
# 2. `git rebase` is completed (history of `${WORK_BRANCH}` and `${RMASTER}` are different),
# just work with `${MASTER}` branch.
local ACTUAL_REMOTE=$(git for-each-ref --format='%(upstream:short)' refs/heads/${WORK_BRANCH})
boxtee git checkout ${MASTER}
boxtee git merge --ff-only ${WORK_BRANCH}
boxtee git push ${REMOTE_NAME} ${MASTER}:${MASTER}
boxtee git branch --delete --force ${WORK_BRANCH}
boxtee git push ${REMOTE_NAME} --delete $(echo "${1}" | sed -e "s|${REMOTE_NAME}/||")
boxtee git push ${REMOTE_NAME} --delete $(branch-from-remote-reference ${ACTUAL_REMOTE})
}
41 changes: 18 additions & 23 deletions libexec/git-elegant-obtain-work
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
#!/usr/bin/env bash
set -e

--up-to-one-branch(){
local BRANCHES=(${@})
if [[ ${#BRANCHES[@]} > 1 ]]; then
default() {
local PATTERN=${1}
_error-if-empty "${PATTERN}" "Please provide a branch name or its part."
boxtee git fetch --all
local REMOTE_BRANCHES=(
$(git for-each-ref --format='%(refname:strip=2)' refs/remotes/** | grep "${PATTERN}")
)
if [[ ${#REMOTE_BRANCHES[@]} > 1 ]]; then
echo "The following branches are found:"
for branch in ${BRANCHES[@]}; do
for branch in ${REMOTE_BRANCHES[@]}; do
echo " - ${branch}"
done
box "Please re-run the command with concrete branch name from the list above!"
exit 43
fi
}

default() {
local PATTERN=${1}
_error-if-empty "${PATTERN}" "Please provide a branch name or its part."
local LOCAL_BRANCHES=($(git for-each-ref --format='%(refname:strip=2)' refs/heads/* | grep "${PATTERN}"))
--up-to-one-branch ${LOCAL_BRANCHES[@]}
if [[ ${#LOCAL_BRANCHES[@]} = 1 ]]; then
boxtee git checkout ${LOCAL_BRANCHES[0]}
boxtee git pull
else
boxtee git fetch --all
local REMOTE_BRANCHES=($(git for-each-ref --format='%(refname:strip=3)' refs/remotes/** | grep "${PATTERN}"))
--up-to-one-branch ${REMOTE_BRANCHES[@]}
if [[ ${#REMOTE_BRANCHES[@]} = 1 ]]; then
boxtee git checkout ${REMOTE_BRANCHES[0]}
else
box "There are no either remove or local branches which match '${PATTERN}' pattern."
exit 43
if [[ ${#REMOTE_BRANCHES[@]} = 1 ]]; then
local REMOTE=${REMOTE_BRANCHES[0]}
local LOCAL=${2}
if [[ -z ${LOCAL} ]]; then
LOCAL=$(branch-from-remote-reference ${REMOTE})
fi
boxtee git checkout -B ${LOCAL} ${REMOTE}
else
box "There is no branch that matches the '${PATTERN}' pattern."
exit 43
fi
}
14 changes: 5 additions & 9 deletions tests/git-elegant-accept-work.bats
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,21 @@ teardown() {
}

@test "'accept-work': a work is accepted successfully for given remote branch" {
fake-pass git "fetch --all --tags"
fake-pass git "checkout --force -B __eg origin/work"
fake-pass git "elegant obtain-work some __eg"
fake-pass git "status"
fake-pass git "rebase origin/master"
fake-pass git "checkout master"
fake-pass git "merge --ff-only __eg"
fake-pass git "push origin master:master"
fake-pass git "branch --delete --force __eg"
fake-pass git "push origin --delete work"
check git-elegant accept-work origin/work
fake-pass git "for-each-ref --format='%(upstream:short)' refs/heads/_eg}" "origin/some-work"
fake-pass git "push origin --delete some-work"

check git-elegant accept-work some
[[ "$status" -eq 0 ]]
}

@test "'accept-work': exit code is 45 when remote branch name isn't set" {
check git-elegant accept-work
[[ "$status" -eq 45 ]]
}

@test "'accept-work': print error message when remote branch name isn't set" {
check git-elegant accept-work
[[ "${lines[0]}" =~ "Please give a name of remote branch (like 'origin/123')." ]]
}
35 changes: 12 additions & 23 deletions tests/git-elegant-obtain-work.bats
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,38 @@ teardown() {
[[ "${lines[@]}" =~ "Please provide a branch name or its part." ]]
}

@test "'obtain-work': use found local branch when given pattern matches only one local branch" {
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/heads/*" "master\nfoo"
fake-pass git "checkout foo"
fake-pass git pull
@test "'obtain-work': use found remote branch when given pattern matches only one remote branch" {
fake-pass git "fetch --all"
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/remotes/**" "origin/rremote\norigin/master"
fake-pass git "checkout -B rremote origin/rremote"

check git-elegant obtain-work fo
check git-elegant obtain-work rr
[[ "$status" -eq 0 ]]
}

@test "'obtain-work': raise 43 error when given pattern matches several local branches" {
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/heads/*" "master\nfoo\nfo2\nfo3"

check git-elegant obtain-work fo
[[ "$status" -eq 43 ]]
[[ "${lines[@]}" =~ "Please re-run the command with concrete branch name from the list above!" ]]
}

@test "'obtain-work': use found remote branch when given pattern matches only one remote branch" {
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/heads/*"
@test "'obtain-work': use given local branch name when it is provided" {
fake-pass git "fetch --all"
fake-pass git "for-each-ref --format='%(refname:strip=3)' refs/remotes/**" "rremote\nmaster"
fake-pass git "checkout rremote"
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/remotes/**" "origin/rremote\norigin/master"
fake-pass git "checkout -B myname origin/rremote"

check git-elegant obtain-work rr
check git-elegant obtain-work rr myname
[[ "$status" -eq 0 ]]
}

@test "'obtain-work': raise 43 error when given pattern matches several remote branches" {
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/heads/*"
fake-pass git "fetch --all"
fake-pass git "for-each-ref --format='%(refname:strip=3)' refs/remotes/**" "rremote\nmaster\nbarr"
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/remotes/**" "origin/rremote\norigin/master\nother-upstream/barr"

check git-elegant obtain-work rr
[[ "$status" -eq 43 ]]
[[ "${lines[@]}" =~ "Please re-run the command with concrete branch name from the list above!" ]]
}

@test "'obtain-work': raise 43 error when given pattern matches zero remote branches" {
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/heads/*"
fake-pass git "fetch --all"
fake-pass git "for-each-ref --format='%(refname:strip=3)' refs/remotes/**" "rremote\nmaster\nbarr"
fake-pass git "for-each-ref --format='%(refname:strip=2)' refs/remotes/**" "origin/rremote\norigin/master\norigin/barr"

check git-elegant obtain-work aa
[[ "$status" -eq 43 ]]
[[ "${lines[@]}" =~ "There are no either remove or local branches which match 'aa' pattern." ]]
[[ "${lines[@]}" =~ "There is no branch that matches the 'aa' pattern." ]]
}

0 comments on commit adc329b

Please sign in to comment.