Created
November 5, 2011 08:21
-
-
Save vojtajina/1341268 to your computer and use it in GitHub Desktop.
Simple git script for rewriting history
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Simple script for rewriting history :-D | |
# Might be helpful when using "rebasing" strategy to keep your history nice and flat... | |
# | |
# Instalation | |
# >> sudo bash -c "curl https://raw.github.com/gist/1341268/git-edit.sh > /usr/local/bin/git-edit" | |
# >> sudo chmod a+x /usr/local/bin/git-edit | |
# | |
# Usage | |
# Let's say you are on "master" branch, which looks like this: | |
# A -> B -> C -> D(HEAD master) | |
# | |
# You decide you want to change commit "B"... | |
# | |
# >> git edit <B> | |
# | |
# Now, ammend the commit, add more commits, etc... | |
# Let's say you changed "B" to "B1" and added one more commit "B2" | |
# | |
# >> git edit --done | |
# Will rebase "master" branch on the top of your latest changes, so the result will be: | |
# A -> B1 -> B2 -> C -> D(HEAD master) | |
# | |
GIT_DIR=`git rev-parse --git-dir` | |
ORIGINAL_REF_FILE="$GIT_DIR/refs/EDIT_ORIGINAL" | |
BRANCH_NAME_FILE="$GIT_DIR/EDIT_BRANCH" | |
start() { | |
# edit commit | |
ORIGINAL_REF=`git rev-parse --verify $1 2> /dev/null` | |
if test "$ORIGINAL_REF" = ""; then | |
error "Unknown revision or path \"$1\"" | |
fi | |
# head | |
BRANCH_NAME=$(git_current_branch) | |
if test "$BRANCH_NAME" = ""; then | |
error "You are in 'detached HEAD' state, can not edit commit" | |
fi | |
# must be on the same path | |
if test `git merge-base $ORIGINAL_REF $BRANCH_NAME` != "$ORIGINAL_REF"; then | |
error "\"$ORIGINAL_REF\" is not predecessor of \"$BRANCH_NAME\" branch" | |
fi | |
git checkout -q $ORIGINAL_REF || exit 1 | |
echo "You are now on \"$ORIGINAL_REF\". Feel free to ammend or add new commits :-D" | |
echo "When done, to rebase \"$BRANCH_NAME\" branch, run:" | |
echo " git edit --done" | |
# save refs | |
echo $ORIGINAL_REF > $ORIGINAL_REF_FILE | |
echo $BRANCH_NAME > $BRANCH_NAME_FILE | |
} | |
finish() { | |
ORIGINAL_REF=`cat $ORIGINAL_REF_FILE 2> /dev/null` | |
BRANCH_NAME=`cat $BRANCH_NAME_FILE 2> /dev/null` | |
NEW_REF=`git rev-parse HEAD` | |
if test "$ORIGINAL_REF" = "" || test "$BRANCH_NAME" = ""; then | |
error "Not in the editing process" | |
fi | |
git checkout -q $BRANCH_NAME | |
git rebase --onto $NEW_REF $ORIGINAL_REF | |
# clean up | |
rm $ORIGINAL_REF_FILE | |
rm $BRANCH_NAME_FILE | |
} | |
git_current_branch() { | |
git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g' | |
} | |
error() { | |
echo "Error: $1 !" | |
exit 1 | |
} | |
if test $# -eq 0; then | |
echo "Usage: git edit [--done] [<commit-to-edit>]" | |
exit 1 | |
fi | |
if test "$1" = "--done"; then | |
finish | |
else | |
start $1 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment