Re: [PATCH v2] git svn : hook before 'git svn dcommit'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 17, 2011 at 04:35:03PM +0200, Frédéric Heitzmann wrote:
> Hi all.
> 
> Maybe I should give some more context to explain why a hook could be a
> potential improvement.
> 
> Let's consider the following workflow :
> 1) git svn clone from the SVN server, then git checkout -b topic
> 2) git commit some "reference data", before starting some optimization
> or code refactoring.
> ** These reference data are not supposed to find their way to the SVN server **
> Committing such "reference data" is just a convenience because git
> does a great job to show how these data may or may not change during
> the development process.
> 3) hack, test, commit ...
> 3 bis) it may happen that reference data change for some very good
> reason (for instance some protocol change)
> New reference data are then commited.
> 
> back to 3 ...
> 
> 4) Before merging back to master and commitng to SVN, it is necessary
> to remove commits with reference data (git rebase -i --onto master
> master topic ...)
> 5) merge topic branch with master and git svn dcommit
> 
> -- end --
> 
> It is very easy to forget step 4, and svn commit lots of useless data.
> 
> Proposal 1)
> * commit reference data with some specific mark in the commit message
> (e.g. "NO_SVN")
> * use pre-svn-dcommit hook to detect such commits
> 
> Proposal 2) (not fully feasable for what I know)
> * git svn clone to a bare repo
> * clone a working repo from the the bare repo.
> * steps 2, 3, maybe 3bis, ... then 4
> * push commits to the bare repo, while using pre-receive or update
> hook to look for wrong commits, and abort if so.
> * use post-receive hook to trigger git svn dcommit
> 
> Main drawback for proposal 2 (appart from needing 2 repo instead of
> one) is that each time you want to update your working  repo, you have
> to git svn rebase the bare repo, then git pull.
> 
> Proposal 2bis)
> * add a pre-send hook on the bare repo, and trigger some git svn
> rebase with this hook.
> I am not sure to see all the potential consequences of such a hook though.
> 
> All things begin equal, proposal 1 seems to be the easier path, but it
> is highly debatable.
> 

I have written a local script for exactly the problem you described after looking
for a git svn dcommit hook I could use (as you did).
I attached it, so feel free to use it. Simply add it to your bin and run it
with   git dcommit    instead of  git svn dcommit

Pls read the comment for further explanation how this script is used.


#!/bin/bash
# Copyright © Peter Baumann, 2011
#
# 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
cd_to_toplevel || die "foo"

# Upstream ref
upstream=remotes/trunk

# Stop at this commit
last=
if [ ! -z $1 ]; then
	$(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 run()
{
	#echo "DEBUG: $@"
	$@
}	

IFS='
'
for c in $(git log --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 --pretty=oneline ${commit} --not "${upstream}"
echo

# Show the latest commit we are going to submit to SVN
#git show ${commit}

echo
echo "Commiting to SVN (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 || "Aborting - git svn dcommit failed!"

	if [ "${orig_head}" != "(detached head)" ]; then
		echo "DO THIS:"
		run git checkout "${orig_head}" && run git rebase "${upstream}"
	else
		echo "You have started this script being on a detached HEAD."
		echo "Please rebase manually!"
	fi
fi
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]