On Sun, 28 Oct 2007, Helge Kreutzmann wrote: > > We have no way to filter anything on the server side. But maybe we can > > provide you some scripts that hide the git commands behind two scripts > > like "dpkg-git update" and "dpkg-git commit" (which would have the > > same logic as SVN). > I like the idea quite a bit and thus would be enlightend if something > like this could be implemented and distributed. This would also allow > you to update the actual git commands without anyone noticing :-))
I had a try to create such a command. It's attached to this mail. It requires git 1.5.3 as "git-stash" is used. It tries to mimic the behaviour of svn. Put the script in your dpkg repository and call it from the root of the repository. There are two important commands only: ./dpkg-vcs update ./dpkg-vcs commit The output of the script itself is prefixed with "**" so that you can easily skip git's own output (in case you don't understand it). The script does a fair number of verifications and checks the exit code of several important git command and gives you proper indication on how to continue. Please try it and feel free to give some feedback. Cheers, -- Raphaël Hertzog Premier livre français sur Debian GNU/Linux : http://www.ouaza.com/livre/admin-debian/
#!/bin/sh #Â Copyright 2007 Raphael Hertzog <[EMAIL PROTECTED]> # # This program is free software; you may redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This is distributed in the hope that it will be useful, but without # any warranty; without even the implied warranty of merchantability or # fitness for a particular purpose. See the GNU General Public License # for more details. # # A copy of the GNU General Public License is available as # /usr/share/common-licenses/GPL in the Debian GNU/Linux distribution # or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. # You can also obtain it by writing to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # This script is only meant to be used in the master branch of dpkg # This branch is created by default by a git clone # ssh://git.debian.org/git/dpkg/dpkg.git # Git 1.5.3 is required (for git-stash) has_changes_in_index() { # git-diff --quiet returns 1 when there are changes if git diff --quiet --cached; then return 1 else return 0 fi } has_changes_in_working_tree() { # git-diff --quiet returns 1 when there are changes if git diff --quiet; then return 1 else return 0 fi } is_uptodate() { unmerged=`git rev-list origin/master ^HEAD` if test -z "$unmerged"; then return 0 else return 1 fi } has_unpushed_commits() { unpushed=`git rev-list HEAD ^origin/master` if test -n "$unpushed"; then return 0 else return 1 fi } test -d .git || { echo "This script must be called from the root of dpkg's git repository." >&2 exit } branch=`git-name-rev --name-only HEAD` [ "$branch" = "master" ] || { echo "This script must be called from dpkg's master branch." >&2 echo "Call 'git checkout master'." exit } case $1 in update) git fetch --quiet origin if has_unpushed_commits; then echo "** You have local commits that were not pushed to the remote repository." if is_uptodate; then echo "** They are still OK to be pushed." else echo "** The remote repository has evolved. Rebasing your work." $0 rebase fi else if ! is_uptodate; then echo "** The remote repository has changed. Trying to update." if has_changes_in_index || has_changes_in_working_tree; then git merge origin/master result=$? if [ $result -eq 0 ]; then echo "** The repository has been updated." elif [ $result -eq 1 ]; then echo "** The repository has been updated but there have been conflicts:" git ls-files --unmerged | awk '{print $4}' | uniq -c else echo "** The automatic merge failed. Try another stratrgy." echo "** Pushing local changes aside with git stash" git stash save "WIP saved by dpkg-vcs" echo "** Merging remote changes, should result in fast-forward" git merge origin/master echo "** Reapplying local changes with git stash apply" git stash apply result=$? if [ $result -eq 0 ]; then echo "** Local changes have been merged" elif [ $result -eq 1 ]; then echo "** Local changes have been merged but there have been conflicts:" git ls-files --unmerged | awk '{print $4}' | uniq -c else echo "** git stash apply failed badly and returned $result." echo "** You're on your own..." exit 2 fi fi fi else echo "** Nothing updated, the remote respository hasn't changed." fi fi ;; commit) git fetch --quiet origin if ! is_uptodate; then echo "** You're not up-to-date, please do '$0 update' first." exit 1 fi if has_changes_in_index || has_changes_in_working_tree; then echo "** Committing changes locally" git commit -a || { echo "** git commit failed, stopping here." exit 1 } fi if has_unpushed_commits; then echo "** Pushing your changes to the remote repository" echo "Here's a resume of what you're going to push:" git rev-list --pretty=oneline --abbrev-commit master ^origin/master echo "** Do you confirm that you want to push? [Yn] " read answer if [ "$answer" = "" ] || [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then echo "** Calling 'git push'" git push fi fi ;; rebase) git fetch --quiet origin if [ -z "$2" ]; then echo "** Starting a rebase process..." git rebase origin/master result=$? else if [ "$2" = "--continue" ] || [ "$2" = "--skip" ]; then if [ "$2" = "--continue" ]; then for file in `git ls-files --unmerged | awk '{print $4}' | uniq`; do git add $file done fi git rebase $2 result=$? else echo "Invalid option for '$0 rebase': $2" >&2 exit 1 fi fi if [ $result -eq 0 ]; then echo "** The rebase process is finished. Your repository is up-to-date." exit 0 elif [ $result -eq 1 ]; then echo "** Rebase process interrupted by conflicts." echo "** Edit the files below and fix all the conflicts," echo "** then call '$0 rebase --continue':" git ls-files --unmerged | awk '{print $4}' | uniq -c exit 1 else echo "** The rebase process miserably failed for an unknown reason." echo "** Aborting it." git rebase --abort exit 2 fi ;; *) echo "$0: invalid syntax" >&2 echo "$0 update: update the master branch of the repository" >&2 echo "$0 commit: commit and push the changes to the master repository" >&2 ;; esac

