diff --git a/Readme.md b/Readme.md index f097ad6..23f4649 100644 --- a/Readme.md +++ b/Readme.md @@ -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 diff --git a/bin/git-squash b/bin/git-squash index ec53183..7408eb5 100755 --- a/bin/git-squash +++ b/bin/git-squash @@ -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 diff --git a/man/git-squash.1 b/man/git-squash.1 index 5dd3253..07ecde2 100644 --- a/man/git-squash.1 +++ b/man/git-squash.1 @@ -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 [] +\fBgit\-squash\fR [] . .SH "DESCRIPTION" 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 Branch to squash on the actual branch\. . .P + 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 . .P @@ -35,6 +38,8 @@ 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 . @@ -42,7 +47,7 @@ $ git commit \-m "New commit without a real merge" 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> diff --git a/man/git-squash.html b/man/git-squash.html index e312959..091cd46 100644 --- a/man/git-squash.html +++ b/man/git-squash.html @@ -2,7 +2,7 @@ - + git-squash(1) - Import changes form a branch