-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-breakout
executable file
·71 lines (53 loc) · 1.99 KB
/
git-breakout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/bin/bash
set -Eeuo pipefail
if [ $# -lt 2 ]; then
cat <<-EOT
Usage: git breakout <branch_name> <commit>...
This command creates a PR that contains some commits taken from the
current branch (or anywhere else, really) and applied on top of the current
branch's upstream branch.
The broken out commits will form a new branch which will only get a branch
head in the »origin« repository, but not in the local repository.
This command operates directly on git objects, isolated from the current branch,
working tree and index, so you can use it a any point,
and it's faster than rebasing.
The drawback is that if any commit's patch doesn't apply cleanly, it will
make the whole operation fail, as there's no mechanism to resolve conflicts.
<commit> may be given as either individual commits or commit ranges.
There are almost no sanity checks, use at your own risk!
Good luck!
EOT
exit 1
fi
BRANCH=$1
shift
SIGN_FLAG=
if [[ $(git config --get --type bool commit.gpgSign) == true ]]; then
SIGN_FLAG=-S
fi
GIT_INDEX_FILE=$(git rev-parse --git-dir)/breakout-index
export GIT_INDEX_FILE
trap "rm $GIT_INDEX_FILE" EXIT
PREV=$(git rev-parse origin/HEAD)
git read-tree $PREV
for COMMIT in $(git rev-list --reverse --no-walk "$@"); do
git show -s --format='Applying %t %s' $COMMIT
if ! git diff-tree -p $COMMIT | git apply --cached; then
echo Could not apply changes....
echo Aborting...
exit 1
fi
TREE=$(git write-tree)
PREV=$(git show -s --format='%B' $COMMIT | env \
GIT_AUTHOR_NAME="$(git show -s --format='%an' $COMMIT)" \
GIT_AUTHOR_EMAIL="$(git show -s --format='%ae' $COMMIT)" \
GIT_AUTHOR_DATE="$(git show -s --format='%ad' $COMMIT)" \
git commit-tree $SIGN_FLAG -p $PREV $TREE)
done
git push origin $PREV:refs/heads/${BRANCH};
if command -v gh &>/dev/null; then
gh pr create -w --head ${BRANCH}
else
echo GitHub CLI not installed, please manually open the web interface to create the PR
fi
exit 0