Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,20 @@ $ git graft new_feature dev
$ git graft new_feature
```

## git-squash <src-branch> [msg]
## git-squash <src-branch|commit ref> [msg]

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.
Merge commits from `src-branch` into the current branch as a _single_ commit.
Also works if a commit reference from the current branch is provided.
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.

```bash
$ git squash fixed-cursor-styling
$ git squash fixed-cursor-styling "Fixed cursor styling"
$ git squash 95b7c52
$ git squash HEAD~3
$ git squash HEAD~3 "Work on a feature"
```

## git-changelog
Expand Down
73 changes: 44 additions & 29 deletions bin/git-squash
Original file line number Diff line number Diff line change
@@ -1,38 +1,53 @@
#!/bin/sh
#!/bin/bash

src=$1
msg=$2
src="$1"
msg="$2"

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

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

if [[ $1 == "--me" ]]; then
msg=$3
branch=`git rev-parse --abbrev-ref HEAD`

# merge against target branch or master
git checkout ${2-master}

git checkout -B squash-tmp
git squash $branch
git branch -D $branch
git checkout -B $branch
git branch -D squash-tmp
is_on_current_branch() {
local commit_sha=`git rev-parse "$src"`
git rev-list HEAD |
grep -q "$commit_sha"
}

commit_if_msg_provided() {
if test -n "$msg"; then
git commit -a -m "$msg"
fi

exit
fi

# squash $src

git merge --squash $src

if test -n "$msg"; then
git commit -a -m "$msg" && git branch -D $src
}

prompt_continuation_if_squashing_master() {
if [[ $src =~ ^master$ ]]; then
read -p "Warning: squashing '$src'! Continue [y/N]? " -r
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Exiting"
exit 1
fi
fi
}

squash_branch() {
prompt_continuation_if_squashing_master
git merge --squash "$src" || exit 1 # quits if `git merge` fails
commit_if_msg_provided
}

squash_current_branch() {
git reset --soft "$src" || exit 1 # quits if `git reset` fails
commit_if_msg_provided
}

if `is_branch`; then
squash_branch
elif `is_commit_reference` && `is_on_current_branch`; then
squash_current_branch
else
echo "Source branch or commit reference required." 1>&2 && exit 1
fi
17 changes: 11 additions & 6 deletions man/git-squash.1
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
.\" generated with Ronn/v0.7.3
.\" https://github.com/rtomayko/ronn/tree/0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-SQUASH" "1" "July 2012" "" ""
.TH "GIT\-SQUASH" "1" "July 2014" "" ""
.
.SH "NAME"
\fBgit\-squash\fR \- Import changes from a branch
\fBgit\-squash\fR \- Import changes form a branch
.
.SH "SYNOPSIS"
\fBgit\-squash\fR <source\-branch> [<commit\-message>]
\fBgit\-squash\fR <source\-branch|commit ref> [<commit\-message>]
.
.SH "DESCRIPTION"
Produce the working tree and index state as if a real merge happened without the commit or merge marks\.
Expand All @@ -19,6 +19,9 @@ Produce the working tree and index state as if a real merge happened without the
Branch to squash on the actual branch\.
.
.P
<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\.
.
.P
<commit\-message>
.
.P
Expand All @@ -35,14 +38,16 @@ Squash commit \-\- not updating HEAD
my\-changed\-file | 1 +
1 file changed, 1 insertion(+)
$ git commit \-m "New commit without a real merge"

$ git squash HEAD~3 "Commit message"
.
.fi
.
.SH "AUTHOR"
Written by Jesús Espino <\fIjespinog@gmail\.com\fR>
.
.SH "REPORTING BUGS"
<\fIhttp://github\.com/visionmedia/git\-extras/issues\fR>
<\fIhttps://github\.com/visionmedia/git\-extras/issues\fR>
.
.SH "SEE ALSO"
<\fIhttp://github\.com/visionmedia/git\-extras\fR>
<\fIhttps://github\.com/visionmedia/git\-extras\fR>
14 changes: 10 additions & 4 deletions man/git-squash.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion man/git-squash.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ git-squash(1) -- Import changes form a branch

## SYNOPSIS

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

## DESCRIPTION

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

Branch to squash on the actual branch.

&lt;commit reference&gt;
A commit reference (has to be from the current branch) can also be used as the
first argument. A range of commits <sha>..HEAD will be squashed.

&lt;commit-message&gt;

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

$ git squash HEAD~3 "Commit message"

## AUTHOR

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