[Erp5-report] r45847 jm - /erp5/trunk/utils/git-helpers/

nobody at svn.erp5.org nobody at svn.erp5.org
Thu May 12 15:11:32 CEST 2011


Author: jm
Date: Thu May 12 15:11:32 2011
New Revision: 45847

URL: http://svn.erp5.org?rev=45847&view=rev
Log:
Add a few Git commands

- git-auto-push: automatically rebase current branch if needed and push it
                 (based on Products.ERP5VCS.Git.Git.commit implementation)
- git-new-workdir: to have several working copies sharing the same Git DB
                   (fork of git.git:contrib/workdir/git-new-workdir)
- git-squash-dups: useful to clean up a converted repository from Subversion

Added:
    erp5/trunk/utils/git-helpers/
    erp5/trunk/utils/git-helpers/git-auto-push   (with props)
    erp5/trunk/utils/git-helpers/git-new-workdir   (with props)
    erp5/trunk/utils/git-helpers/git-squash-dups   (with props)

Added: erp5/trunk/utils/git-helpers/git-auto-push
URL: http://svn.erp5.org/erp5/trunk/utils/git-helpers/git-auto-push?rev=45847&view=auto
==============================================================================
--- erp5/trunk/utils/git-helpers/git-auto-push (added)
+++ erp5/trunk/utils/git-helpers/git-auto-push [utf8] Thu May 12 15:11:32 2011
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+import subprocess, sys
+
+class GitError(EnvironmentError):
+    def __init__(self, err, out, returncode):
+        EnvironmentError.__init__(self, err)
+        self.stdout = out
+        self.returncode = returncode
+
+def _git(*args, **kw):
+    p = subprocess.Popen(('git',) + args, **kw)
+    out, err = p.communicate()
+    if p.returncode:
+        raise GitError(err, out, p.returncode)
+    return out
+
+def git(*args, **kw):
+    out = _git(stdout=subprocess.PIPE, stderr=subprocess.PIPE, *args, **kw)
+    return out.strip()
+
+def main():
+    try:
+        src, dst = git('rev-parse', '--symbolic-full-name',
+                       'HEAD', '@{u}').splitlines()
+        assert src[:11] == 'refs/heads/' and dst[:13] == 'refs/remotes/'
+        src = src[11:]
+        dst = dst[13:]
+        remote, dst = dst.split('/', 1)
+        push_args = 'push', '--porcelain', remote, '%s:%s' % (src, dst)
+        try:
+            print git(*push_args)
+        except GitError, e:
+            # first check why we could not push
+            status = [x for x in e.stdout.splitlines() if x[:1] == '!']
+            if (len(status) !=  1 or
+                status[0].split()[2:] != ['[rejected]', '(non-fast-forward)']):
+                raise
+            _git('fetch')
+            if not int(git('rev-list', '--count', '..@{u}')):
+                raise
+            # try to update our working copy
+            try:
+                _git('rebase', '@{u}')
+            except GitError, e:
+                # XXX: how to know how it failed ?
+                try:
+                    _git('rebase', '--abort')
+                except GitError:
+                    pass
+                raise
+            # retry to push everything
+            _git(*push_args)
+    except GitError, e:
+        err = str(e)
+        if err:
+            sys.stderr.write(err)
+        return e.returncode
+
+if __name__ == "__main__":
+    sys.exit(main())

Propchange: erp5/trunk/utils/git-helpers/git-auto-push
------------------------------------------------------------------------------
    svn:executable = *

Added: erp5/trunk/utils/git-helpers/git-new-workdir
URL: http://svn.erp5.org/erp5/trunk/utils/git-helpers/git-new-workdir?rev=45847&view=auto
==============================================================================
--- erp5/trunk/utils/git-helpers/git-new-workdir (added)
+++ erp5/trunk/utils/git-helpers/git-new-workdir [utf8] Thu May 12 15:11:32 2011
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+usage () {
+	echo "usage:" $@
+	exit 127
+}
+
+die () {
+	echo $@
+	exit 128
+}
+
+if test $# -lt 2 || test $# -gt 3
+then
+	usage "$0 <repository> <new_workdir> [<branch>]"
+fi
+
+orig_git=$1
+new_workdir=$2
+branch=$3
+
+# want to make sure that what is pointed to has a .git directory ...
+git_dir=$(cd "$orig_git" 2>/dev/null &&
+  git rev-parse --git-dir 2>/dev/null) ||
+  die "Not a git repository: \"$orig_git\""
+
+case "$git_dir" in
+.git)
+	git_dir="$orig_git/.git"
+	;;
+.)
+	git_dir=$orig_git
+	;;
+esac
+
+# don't link to a configured bare repository
+isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
+if test ztrue = z$isbare
+then
+	die "\"$git_dir\" has core.bare set to true," \
+		" remove from \"$git_dir/config\" to use $0"
+fi
+
+# don't link to a workdir
+if test -h "$git_dir/config"
+then
+	die "\"$orig_git\" is a working directory only, please specify" \
+		"a complete repository."
+fi
+
+# don't recreate a workdir over an existing repository
+if test -e "$new_workdir"
+then
+	die "destination directory '$new_workdir' already exists."
+fi
+
+# create the workdir
+mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"
+
+cd "$git_dir"
+git_dir=$(pwd) # make sure the links use full paths
+orig_list=$(echo * info/*)
+cd - >/dev/null
+cd "$new_workdir/.git"
+ln -s "$git_dir" orig_git
+
+# create the links to the original repo.  explicitly exclude index, HEAD and
+# logs/HEAD from the list since they are purely related to the current working
+# directory, and should not be shared.
+for x in $orig_list packed-refs logs/refs
+do
+	case "$x" in
+	*\**)
+		continue ;;
+	logs|info)
+		mkdir "$x" ;;
+	HEAD)
+		# copy the HEAD from the original repository as a default branch
+		cp "orig_git/$x" . ;;
+	*/*|config|packed-refs)
+		;;
+	*)
+		[ -d "orig_git/$x" ] || continue ;;
+	esac
+	[ -e "$x" -o -L "$x" ] || {
+		set $(echo "$x" |sed 's,[^/]\+,..,g')
+		ln -s "${1%..}orig_git/$x" "$x"
+	}
+done
+
+[ "$branch" ] || exit 0
+
+# now setup the workdir
+cd ..
+# checkout the branch (either the same as HEAD from the original repository, or
+# the one that was asked for)
+git checkout -f $branch

Propchange: erp5/trunk/utils/git-helpers/git-new-workdir
------------------------------------------------------------------------------
    svn:executable = *

Added: erp5/trunk/utils/git-helpers/git-squash-dups
URL: http://svn.erp5.org/erp5/trunk/utils/git-helpers/git-squash-dups?rev=45847&view=auto
==============================================================================
--- erp5/trunk/utils/git-helpers/git-squash-dups (added)
+++ erp5/trunk/utils/git-helpers/git-squash-dups [utf8] Thu May 12 15:11:32 2011
@@ -0,0 +1,66 @@
+#!/usr/bin/python2.6
+import os, re, subprocess, sys
+
+class GitError(EnvironmentError):
+    def __init__(self, err, out, returncode):
+        EnvironmentError.__init__(self, err)
+        self.stdout = out
+        self.returncode = returncode
+
+def git(*args, **kw):
+    p = subprocess.Popen(('git',) + args, **kw)
+    out, err = p.communicate()
+    if p.returncode:
+        raise GitError(err, out, p.returncode)
+    return out
+
+def main():
+    svn_id_re = re.compile('\n+git-svn-id: .*\n*$')
+    grafts = []
+    key = None
+    skip = False
+    try:
+        for log in git('log', '-z', '--pretty=format:%H %P %an %B',
+                       stdout=subprocess.PIPE, *sys.argv[1:]).split('\0'):
+            # If there is more than 1 parent, 'k' will start
+            # with their hash and will always differ from 'key'.
+            # Thus, we never squash merge commits.
+            h, p, k = log.split(' ', 2)
+            k = svn_id_re.sub('', k)
+            if k == key:
+                skip = True
+            else:
+                if skip:
+                    grafts.append((parent, h))
+                key = k
+                parent = h
+                skip = False
+        if skip:
+            grafts.append((parent,))
+        if grafts:
+            git_dir = git('rev-parse', '--git-dir',
+                          stdout=subprocess.PIPE).strip()
+            with open(os.path.join(git_dir, 'info', 'grafts'), 'a') as f:
+                for graft in grafts:
+                    f.write(' '.join(graft) + '\n')
+    except GitError, e:
+        err = str(e)
+        if err:
+            sys.stderr.write(err)
+        return e.returncode
+
+if __name__ == '__main__':
+    sys.exit(main())
+
+
+# #!/bin/sh -e
+# tmp=`mktemp -d`
+# trap "rm -r $tmp" 0
+# if git log --pretty=format:'%H %an %s' |uniq -cds 41 |while read n h line
+#    do git rev-parse -q --verify $h^2 >/dev/null || git rev-list $h~$n..$h~
+#    done | (cd "$tmp"; xargs touch 2>/dev/null)
+# then git filter-branch --commit-filter "if rm $tmp/\$GIT_COMMIT 2>/dev/null
+#        then skip_commit "\$@"
+#        else git commit-tree "\$@"
+#      fi" --tag-name-filter cat "$@"
+# fi

Propchange: erp5/trunk/utils/git-helpers/git-squash-dups
------------------------------------------------------------------------------
    svn:executable = *



More information about the Erp5-report mailing list