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