Skip to content

Commit 1f8971b

Browse files
committed
Merge pull request #239 from bruno-/refactor_git_squash
Refactor and improve `git squash`.
2 parents 458c08d + b2576ad commit 1f8971b

File tree

5 files changed

+81
-42
lines changed

5 files changed

+81
-42
lines changed

Readme.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,13 +505,20 @@ $ git graft new_feature dev
505505
$ git graft new_feature
506506
```
507507
508-
## git-squash <src-branch> [msg]
508+
## git-squash <src-branch|commit ref> [msg]
509509
510-
Merge commits from `src-branch` into the current branch as a _single_ commit. When `[msg]` is given `git-commit(1)` will be invoked with that message. This is useful when small individual commits within a topic branch are irrelevant and you want to consider the topic as a single change.
510+
Merge commits from `src-branch` into the current branch as a _single_ commit.
511+
Also works if a commit reference from the current branch is provided.
512+
When `[msg]` is given `git-commit(1)` will be invoked with that message. This is
513+
useful when small individual commits within a topic branch are irrelevant and
514+
you want to consider the topic as a single change.
511515
512516
```bash
513517
$ git squash fixed-cursor-styling
514518
$ git squash fixed-cursor-styling "Fixed cursor styling"
519+
$ git squash 95b7c52
520+
$ git squash HEAD~3
521+
$ git squash HEAD~3 "Work on a feature"
515522
```
516523
517524
## git-changelog

bin/git-squash

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,53 @@
1-
#!/bin/sh
1+
#!/bin/bash
22

3-
src=$1
4-
msg=$2
3+
src="$1"
4+
msg="$2"
55

6-
test -z $src && echo "source branch required, or use --me." && exit 1
6+
is_branch() {
7+
git show-ref --verify --quiet "refs/heads/$src"
8+
}
79

8-
# squash current branch
9-
# TODO: do this in a less hacky way
10-
# TODO: less sketchy arguments
10+
is_commit_reference() {
11+
git rev-parse --verify --quiet "$src" > /dev/null 2>&1
12+
}
1113

12-
if [[ $1 == "--me" ]]; then
13-
msg=$3
14-
branch=`git rev-parse --abbrev-ref HEAD`
15-
16-
# merge against target branch or master
17-
git checkout ${2-master}
18-
19-
git checkout -B squash-tmp
20-
git squash $branch
21-
git branch -D $branch
22-
git checkout -B $branch
23-
git branch -D squash-tmp
14+
is_on_current_branch() {
15+
local commit_sha=`git rev-parse "$src"`
16+
git rev-list HEAD |
17+
grep -q "$commit_sha"
18+
}
2419

20+
commit_if_msg_provided() {
2521
if test -n "$msg"; then
2622
git commit -a -m "$msg"
2723
fi
28-
29-
exit
30-
fi
31-
32-
# squash $src
33-
34-
git merge --squash $src
35-
36-
if test -n "$msg"; then
37-
git commit -a -m "$msg" && git branch -D $src
24+
}
25+
26+
prompt_continuation_if_squashing_master() {
27+
if [[ $src =~ ^master$ ]]; then
28+
read -p "Warning: squashing '$src'! Continue [y/N]? " -r
29+
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
30+
echo "Exiting"
31+
exit 1
32+
fi
33+
fi
34+
}
35+
36+
squash_branch() {
37+
prompt_continuation_if_squashing_master
38+
git merge --squash "$src" || exit 1 # quits if `git merge` fails
39+
commit_if_msg_provided
40+
}
41+
42+
squash_current_branch() {
43+
git reset --soft "$src" || exit 1 # quits if `git reset` fails
44+
commit_if_msg_provided
45+
}
46+
47+
if `is_branch`; then
48+
squash_branch
49+
elif `is_commit_reference` && `is_on_current_branch`; then
50+
squash_current_branch
51+
else
52+
echo "Source branch or commit reference required." 1>&2 && exit 1
3853
fi

man/git-squash.1

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
.\" generated with Ronn/v0.7.3
2-
.\" https://github.com/rtomayko/ronn/tree/0.7.3
2+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
33
.
4-
.TH "GIT\-SQUASH" "1" "July 2012" "" ""
4+
.TH "GIT\-SQUASH" "1" "July 2014" "" ""
55
.
66
.SH "NAME"
7-
\fBgit\-squash\fR \- Import changes from a branch
7+
\fBgit\-squash\fR \- Import changes form a branch
88
.
99
.SH "SYNOPSIS"
10-
\fBgit\-squash\fR <source\-branch> [<commit\-message>]
10+
\fBgit\-squash\fR <source\-branch|commit ref> [<commit\-message>]
1111
.
1212
.SH "DESCRIPTION"
1313
Produce the working tree and index state as if a real merge happened without the commit or merge marks\.
@@ -19,6 +19,9 @@ Produce the working tree and index state as if a real merge happened without the
1919
Branch to squash on the actual branch\.
2020
.
2121
.P
22+
<commit reference> A commit reference (has to be from the current branch) can also be used as the first argument\. A range of commits \fIsha\fR\.\.HEAD will be squashed\.
23+
.
24+
.P
2225
<commit\-message>
2326
.
2427
.P
@@ -35,14 +38,16 @@ Squash commit \-\- not updating HEAD
3538
my\-changed\-file | 1 +
3639
1 file changed, 1 insertion(+)
3740
$ git commit \-m "New commit without a real merge"
41+
42+
$ git squash HEAD~3 "Commit message"
3843
.
3944
.fi
4045
.
4146
.SH "AUTHOR"
4247
Written by Jesús Espino <\fIjespinog@gmail\.com\fR>
4348
.
4449
.SH "REPORTING BUGS"
45-
<\fIhttp://github\.com/visionmedia/git\-extras/issues\fR>
50+
<\fIhttps://github\.com/visionmedia/git\-extras/issues\fR>
4651
.
4752
.SH "SEE ALSO"
48-
<\fIhttp://github\.com/visionmedia/git\-extras\fR>
53+
<\fIhttps://github\.com/visionmedia/git\-extras\fR>

man/git-squash.html

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/git-squash.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ git-squash(1) -- Import changes form a branch
33

44
## SYNOPSIS
55

6-
`git-squash` &lt;source-branch&gt; [&lt;commit-message&gt;]
6+
`git-squash` &lt;source-branch|commit ref&gt; [&lt;commit-message&gt;]
77

88
## DESCRIPTION
99

@@ -16,6 +16,10 @@ git-squash(1) -- Import changes form a branch
1616

1717
Branch to squash on the actual branch.
1818

19+
&lt;commit reference&gt;
20+
A commit reference (has to be from the current branch) can also be used as the
21+
first argument. A range of commits <sha>..HEAD will be squashed.
22+
1923
&lt;commit-message&gt;
2024

2125
If commit-message is given, commit the squash result and delete the source-branch.
@@ -30,6 +34,8 @@ git-squash(1) -- Import changes form a branch
3034
1 file changed, 1 insertion(+)
3135
$ git commit -m "New commit without a real merge"
3236

37+
$ git squash HEAD~3 "Commit message"
38+
3339
## AUTHOR
3440

3541
Written by Jesús Espino &lt;<[email protected]>&gt;

0 commit comments

Comments
 (0)