-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial import of my precious helper tools for working with git-{svn,…
…tfs}
- Loading branch information
Peter Baumann
committed
May 28, 2018
0 parents
commit cf5abe9
Showing
4 changed files
with
440 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
#!/bin/bash | ||
# Copyright © Peter Baumann, 2011-2018 | ||
|
||
# Wrapper script around git svn dcommit, which adds some useful functionality | ||
# | ||
# This script will prevent accidentally commiting some commits not yet ready | ||
# into SVN. Commits starting with (case insensitive) debug, wip, fixup are | ||
# considered not appropriate for putting them into SVN. The main reason for | ||
# this functionality is the specific workflow I use. I always have some | ||
# internal debug commits (e.g. enhanced debug logging) or simply work in progress | ||
# commits which should never be put into SVN. | ||
# | ||
# To avoid putting those into SVN, I rebase all commits so that my WIP/DEBUG commits | ||
# are on top of the commits ment for SVN. | ||
# Calling this script via "git dcommit" after the rebase makes sure only commits | ||
# beneath the WIP commits are considered for SVN. | ||
# Furthermore, a shortlog of commits ment for SVN is shown and the user has | ||
# to confirm before actually putting them into SVN. | ||
# | ||
# If this script is called via a specific commit (e.g. via its SHA1) as parameter, | ||
# then only commits beneath and including the commit itself are committet to SVN. | ||
|
||
|
||
SUBDIRECTORY_OK=Yes | ||
|
||
. git-sh-setup | ||
require_work_tree | ||
require_clean_work_tree | ||
cd_to_toplevel || die "foo" | ||
|
||
if [ "$1" = "--version" ]; then | ||
echo "git dcommit - Version 1.1" | ||
echo "Copyright (C) 2012 Peter Baumann" | ||
exit 0 | ||
fi | ||
|
||
# Stop at this commit | ||
last= | ||
if [ ! -z $1 ]; then | ||
last=$(git rev-parse $1^{commit}) | ||
echo "$last" | ||
fi | ||
|
||
# The latest git commit we want to commit SVN | ||
commit= | ||
|
||
# Remembers the original head | ||
orig_head= | ||
if branch=$(git symbolic-ref -q HEAD) | ||
then | ||
orig_head=${branch#refs/heads/} | ||
else | ||
orig_head='(detached head)' | ||
fi | ||
|
||
function get_last_svn_upstream_commit() | ||
{ | ||
git log -1 --first-parent --grep git-svn --pretty="%H" | ||
} | ||
|
||
function get_upstream_svn_branch() | ||
{ | ||
git svn dcommit -n 2> /dev/null|head -1|sed -e 's#.*/platform/##'|sed -e 's# *\.\.\.$##' | ||
} | ||
|
||
# Print upstream branch name in red in case it is not 'trunk' | ||
function highlight_upstream_svn_branch() | ||
{ | ||
COLOR_BRIGHT_RED="[1;31m" | ||
NO_COLOR="[0m" | ||
|
||
local upstream_branch=$(get_upstream_svn_branch) | ||
if [ "$upstream_branch" != "trunk" ]; then | ||
upstream_branch="${COLOR_BRIGHT_RED}${upstream_branch}${NO_COLOR}" | ||
fi | ||
|
||
echo "$upstream_branch" | ||
} | ||
|
||
function run() | ||
{ | ||
#echo "DEBUG: $@" | ||
$@ | ||
} | ||
|
||
# Upstream ref | ||
upstream=$(get_last_svn_upstream_commit) | ||
|
||
|
||
IFS=' | ||
' | ||
for c in $(git log --first-parent --reverse --pretty="%H %s" HEAD --not "${upstream}"); do | ||
# Split the log output into its fields | ||
sha1="${c:0:40}" | ||
msg="${c:41}" | ||
|
||
# Check if the commit subject matches (case insenstive) to one of the | ||
# following patterns. Leading whitespace is fine | ||
# debug | ||
# wip | ||
# fixup! | ||
if echo "$msg"|egrep -i -q '^\s*(debug|wip|fixup)'; then | ||
break | ||
fi | ||
commit=${sha1} | ||
|
||
if [ "x${commit}" = "x${last}" ]; then | ||
break | ||
fi | ||
done | ||
|
||
if [ "x${commit}" == "x" ]; then | ||
die "Nothing to commit - Perhaps you have only stuff not ready for SVN?" | ||
fi | ||
|
||
echo ">>>> Committing the folling GIT commits to SVN <<<<" | ||
git --no-pager log --first-parent --pretty=oneline ${commit} --not "${upstream}" | ||
echo | ||
|
||
# Show the latest commit we are going to submit to SVN | ||
#git show ${commit} | ||
|
||
echo | ||
echo "Commit to SVN branch '$(highlight_upstream_svn_branch)' (y/N)?" | ||
read yesno || die "Aborting" | ||
|
||
if [ "x${yesno}" == "xy" ] || [ "x$yesno" == "xY" ]; then | ||
run git checkout -q "${commit}" || die "Checkout failed" | ||
run git svn dcommit || die "Aborting - git svn dcommit failed!" | ||
|
||
if [ "${orig_head}" != "(detached head)" ]; then | ||
echo "Rebasing your changes onto HEAD:" | ||
run git rebase --onto HEAD HEAD ${orig_head} | ||
else | ||
echo "You have started this script being on a detached HEAD." | ||
echo "Please rebase manually!" | ||
fi | ||
fi |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#!/bin/bash | ||
# git-fixup (https://github.com/keis/git-fixup) | ||
|
||
SUBDIRECTORY_OK=yes | ||
. "$(git --exec-path)/git-sh-setup" | ||
|
||
# Define a sed program that turns `git diff` output into a stream of filenames | ||
# and sections within those files. | ||
grok_diff='/^--- .*/p ; | ||
s/^@@ -\([0-9]*\),\([0-9]*\).*/\1 \2/p' | ||
|
||
# Produce suggestion of commits by finding the sections of files with changes | ||
# staged (U1 to diff is used to give some context for when adding items to | ||
# lists etc) and looking up the previous commits touching those sections. | ||
function fixup_candidates_lines () { | ||
git diff --cached -U1 --no-prefix | sed -n "$grok_diff" | ( | ||
file='' | ||
while read offs len; do | ||
if test "$offs" == '---'; then | ||
file="$len" | ||
else | ||
if test "$len" != '0'; then | ||
if test "$file" != '/dev/null'; then | ||
git blame -sl -L "$offs,+$len" $rev_range -- "$file" | ||
fi | ||
fi | ||
fi | ||
done | ||
) | grep -v "^^" | cut -d' ' -f 1 | sed 's/^/L /g' | ||
} | ||
|
||
# Produce suggestion of commits by taking the latest commit to each file with | ||
# staged changes | ||
function fixup_candidates_files () { | ||
git diff --cached --name-only | ( | ||
while read file; do | ||
git rev-list $rev_range -- $file \ | ||
| grep -v -f <(git rev-list -E --grep='^(fixup|squash)' $rev_range -- $file ) | ||
done | ||
) | sed 's/^/F /g' | ||
} | ||
|
||
# Pretty print details of a commit | ||
function print_sha () { | ||
local sha=$1 | ||
local type=$2 | ||
|
||
git --no-pager log --format="%H [$type] %s <%ae>" -n 1 "$sha" | ||
} | ||
|
||
op="fixup" | ||
case "$1" in | ||
-s|--squash) | ||
op="squash" | ||
shift | ||
;; | ||
esac | ||
|
||
if test $# -eq 1; then | ||
git commit --$op=$1 | ||
exit | ||
fi | ||
|
||
if git diff --cached --quiet; then | ||
echo 'No staged changes. Use git add -p to add them.' >&2 | ||
exit 1 | ||
fi | ||
|
||
cd_to_toplevel | ||
upstream=`git rev-parse @{upstream} 2>/dev/null` | ||
head=`git rev-parse HEAD 2>/dev/null` | ||
if test -z "$upstream" -o "$upstream" = "$head"; then | ||
rev_range="HEAD" | ||
else | ||
rev_range="@{upstream}..HEAD" | ||
fi | ||
|
||
( | ||
fixup_candidates_lines | ||
fixup_candidates_files | ||
) | sort -uk2 | while read type sha; do | ||
if test "$sha" != ""; then | ||
print_sha "$sha" "$type" | ||
fi | ||
done |
Oops, something went wrong.