Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
rebasing-merge: specify all commits explicitly
Browse files Browse the repository at this point in the history
The earlier attempt to specify additional commits included way too many
commits. So let's start to specify all of the commits explicitly.

While at it, refactor a little and offer a --graph mode that does not
perform the rebasing merge, but shows the commits to be rebased intead.

In the end, it looks like a complete rewrite of the logic, though.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Aug 6, 2011
1 parent e68531d commit 28d08e5
Showing 1 changed file with 70 additions and 35 deletions.
105 changes: 70 additions & 35 deletions share/msysGit/rebasing-merge.sh
@@ -1,7 +1,26 @@
#!/bin/sh

force=
case "$1" in -f|--force) shift; force=t;; esac
graph=
while test $# -gt 0
do
case "$1" in
-f|--force)
force=t
;;
-s|--show|-g|--graph)
graph=t
;;
-*)
echo "Unknown option: $1" >&2
exit 1
;;
*)
break
;;
esac
shift
done

TO=${1:-junio/next}

Expand Down Expand Up @@ -35,58 +54,74 @@ HEAD) ;; # okay
;;
esac

# Find old rebasing merge, if any
is_ours_merge () {
test "$(git rev-parse $1:)" = "$(git rev-parse "$1^:")"
}

rm -f "$TODO_EXTRA"
list_merges () {
git rev-list --parents "$@" | sed -n 's/ .* .*//p'
}

MERGE=
for commit in $(git rev-list --parents $TO.. | sed -n 's/ .* .*//p')
# Find old rebasing merge, if any

PREVIOUS_REBASING=
for commit in $(list_merges $TO..)
do
if test "$(git rev-parse $commit:)" = "$(git rev-parse "$commit^:")"
if is_ours_merge $commit
then
MERGE=$commit
PREVIOUS_REBASING=$commit
break
fi
done

if test -n "$MERGE"
TO_SHA1=$(git rev-parse --short $TO)
MESSAGE="Rebasing merge to $TO ($TO_SHA1)"
RANGE=$TO.. &&
if test -n "$PREVIOUS_REBASING"
then
MESSAGE="$(printf "%s\n\n%s" "$MESSAGE" \
"Previous rebasing merge: $PREVIOUS_REBASING")"
RANGE="$RANGE ^$PREVIOUS_REBASING^2"
for commit in $(list_merges $RANGE)
do
test $commit != $PREVIOUS_REBASING &&
is_ours_merge $commit &&
RANGE="$RANGE ^$commit"
done
fi

if test -n "$graph"
then
ORIG_HEAD=$(git rev-parse HEAD) &&
# Find prior merges to $TO
EXCLUDE=$(git rev-list --parents $TO..$MERGE^ |
sed -n 's/^\([^ ]*\) .* .*/^\1/p') &&
# Get commits from previous rebasing merge
git rev-list --pretty=oneline --abbrev-commit --abbrev=7 --reverse \
--no-merges $TO..$MERGE^ $EXCLUDE |
sed 's/^/pick /' > "$TODO_EXTRA" &&
TMP_EDITOR="$(git rev-parse --git-dir)/rebasing-editor.sh" &&
cat > "$TMP_EDITOR" << EOF &&
git log --graph --oneline --boundary $RANGE
exit
fi

ORIG_HEAD=$(git rev-parse HEAD)
# Get commits to rebase
git rev-list --format='pick %h %s (%an)' --reverse --no-merges $RANGE |
grep -v '^commit ' > "$TODO_EXTRA" &&
TMP_EDITOR="$(git rev-parse --git-dir)/rebasing-editor.sh" &&
cat > "$TMP_EDITOR" << EOF &&
#!/bin/sh
case "\$1" in
*/git-rebase-todo)
cat "\$1" >> "$TODO_EXTRA" &&
sed -e '/^[^#]/d' < "\$1" >> "$TODO_EXTRA" &&
mv "$TODO_EXTRA" "\$1"
esac &&
exec "$(git var GIT_EDITOR)" "\$@"
EOF
TO_SHA1=$(git rev-parse --short $TO) &&
chmod a+x "$TMP_EDITOR" &&
if GIT_EDITOR="$TMP_EDITOR" git rebase -i --onto $TO $MERGE
then
git merge -s ours -m "Rebasing merge to $TO ($TO_SHA1)" \
$ORIG_HEAD
else
FINISH="$(git rev-parse --git-dir)/finish-rebasing-merge.sh"
cat > "$FINISH" << EOF
git merge -s ours -m "Rebasing merge to $TO ($TO_SHA1)" $ORIG_HEAD
chmod a+x "$TMP_EDITOR" &&
if GIT_EDITOR="$TMP_EDITOR" git rebase --autosquash -i --onto $TO HEAD^
then
git merge -s ours -m "$MESSAGE" $ORIG_HEAD
else
FINISH="$(git rev-parse --git-dir)/finish-rebasing-merge.sh"
cat > "$FINISH" << EOF
git merge -s ours -m '$MESSAGE' $ORIG_HEAD
EOF
chmod a+x "$FINISH"
cat << EOF
chmod a+x "$FINISH"
cat << EOF
After the rebase, call '$FINISH' manually
EOF
fi

else
git rebase --autosquash -i $TO
fi

0 comments on commit 28d08e5

Please sign in to comment.