a new one. Not tested at all yet.
from gitadmin.adm.models import Repository
class RepositoryForm(ModelForm):
+ initialclone = forms.RegexField(r'^(git://.+/.+|[^:]+)$',max_length=256,required=False,
+ label="Initial clone",
+# help_text='<a href="javascript:popupRepoList()">Select repository</a>')
+ help_text='Input a valid local repository name or git:// URL')
+
class Meta:
model = Repository
exclude = ('repoid','name', )
anonymous = models.BooleanField(blank=False,verbose_name='Enable anonymous access')
web = models.BooleanField(blank=False,verbose_name='Enable gitweb access')
approved = models.BooleanField(blank=False)
+ initialclone = models.TextField(max_length=256, blank=False, null=True)
def ValidateOwnerPermissions(self, user):
if user.is_superuser:
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8" />
<link rel="shortcut icon" href="/favicon.ico" />
<style type="text/css" media="screen" title="Normal Text">@import url("/static/pggit.css");</style>
+ <script language="javascript" src="/static/pggit.js"></script>
</head>
<body>
<div id="pggitWrap">
{% if not repo.approved %}
<p><strong>This repository has not yet been approved.</strong> This means you cannot access it through git or web yet.
You can still update the description and set permissions - they will all start working automatically
-when the repository is approved.</p>
+when the repository is approved. Until approval you can also set it up to clone another repository
+automatically upon creation.</p>
{%endif%}
{% if form_saved_at %}
<p>Your changes were successfully saved at {{form_saved_at|date:"Y-m-d H:i:s"}}.</p>
{%endif%}
+{% if form.errors %}
+<p><b>Error:</b> The submitted form contains errors and could not be saved.</p>
+{%endif%}
<form method="POST" action=".">
<table class="leftalign">
{{form}}
+# vim: ai ts=4 sts=4 sw=4
import re
from django.http import HttpResponse, HttpResponseRedirect
from gitadmin.adm.models import *
from gitadmin.adm.forms import *
+# Utility classes
+class FormIsNotValid(Exception):
+ pass
+
# Utility functions
def _MissingSshkey(user):
repo = get_object_or_404(Repository, repoid=repoid)
repo.ValidateOwnerPermissions(request.user)
savedat = None
+ form = None
formfactory = inlineformset_factory(Repository, RepositoryPermission, extra=1)
formset = formfactory(data=request.POST, instance=repo)
if not request.user.is_superuser:
del form.fields['approved']
+ if repo.approved:
+ del form.fields['initialclone']
if form.is_valid() and formset.is_valid():
- form.save()
- formset.save()
- savedat = datetime.datetime.now()
- # Get a new copy of the repository to make sure it refreshes!
- repo = get_object_or_404(Repository, repoid=repoid)
-
- form = RepositoryForm(instance=repo)
- if not request.user.is_superuser:
- del form.fields['approved']
+ try:
+ # Manually validate the repository entered if there is one to clone
+ if form.cleaned_data['initialclone']:
+ if form.cleaned_data['initialclone'].startswith('git://'):
+ # Validate hostnames and stuff?
+ pass
+ else:
+ # Assume local
+ try:
+ r = Repository.objects.get(name=form.cleaned_data['initialclone'])
+ except Repository.DoesNotExist:
+ form._errors['initialclone'] = form._errors.get('initialclone', [])
+ form._errors['initialclone'].append('Specified repository does not exist')
+ raise FormIsNotValid()
+
+ form.save()
+ formset.save()
+ savedat = datetime.datetime.now()
+ # Get a new copy of the repository to make sure it refreshes!
+ repo = get_object_or_404(Repository, repoid=repoid)
+ except FormIsNotValid:
+ # Just continue as if the form wasn't valid, expect the caller
+ # to have set the required error fields
+ pass
+
+ if not form or not form.errors:
+ form = RepositoryForm(instance=repo)
+ if not request.user.is_superuser:
+ del form.fields['approved']
+ if repo.approved:
+ del form.fields['initialclone']
formset = formfactory(instance=repo)
perm = repo.repositorypermission_set.all()
def dumprepos(self):
# FIXME: use a trigger to indicate if *anything at all* has changed
curs = self.db.cursor()
- curs.execute("SELECT name,anonymous,web,description,(SELECT min(first_name) FROM repository_permissions AS rp LEFT JOIN auth_user AS au ON au.username=rp.userid WHERE rp.level=2 AND rp.repository=r.repoid) FROM repositories AS r WHERE approved ORDER BY name")
+ curs.execute("SELECT name,anonymous,web,description,initialclone,(SELECT min(first_name) FROM repository_permissions AS rp LEFT JOIN auth_user AS au ON au.username=rp.userid WHERE rp.level=2 AND rp.repository=r.repoid) FROM repositories AS r WHERE approved ORDER BY name")
f = open("%s.tmp" % self.conf.get("paths", "gitweblist"), "w")
- for name, anon, web, description, owner in curs:
+ for name, anon, web, description, initialclone, owner in curs:
# Check if this repository exists at all
if not os.path.isdir("%s/repos/%s" % (self.conf.get("paths", "githome"), name)):
# Does not exist, let's initialize a new one
- print "Initializing new git repository %s" % name
os.environ['GIT_DIR'] = "%s/repos/%s"% (self.conf.get("paths", "githome"), name)
- os.system("git init --bare --shared")
+ if initialclone:
+ print "Initializing git into %s (cloned repo %s)" % (name, initialclone)
+ if initialclone.startswith('git://'):
+ # Just use the raw URL, expect approver to have validated it
+ oldrepo = initialclone
+ else:
+ # This is a local reference, so rewrite it based on our root
+ oldrepo = "%s/repos/%s" % (self.conf.get("paths", "githome"), initialclone)
+ os.system("git clone --bare %s %s/repos/%s" % (
+ # Old repo
+ oldrepo,
+ # New repo
+ self.conf.get("paths", "githome"), name,
+ ))
+ else:
+ print "Initializing new git repository %s" % name
+ os.system("git init --bare --shared")
del os.environ['GIT_DIR']
# Check for publishing options here