summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--git_config.py48
-rw-r--r--project.py82
2 files changed, 104 insertions, 26 deletions
diff --git a/git_config.py b/git_config.py
index 78069c5d..7aad80d2 100644
--- a/git_config.py
+++ b/git_config.py
@@ -57,6 +57,7 @@ class GitConfig(object):
57 self.file = file 57 self.file = file
58 self.defaults = defaults 58 self.defaults = defaults
59 self._cache_dict = None 59 self._cache_dict = None
60 self._section_dict = None
60 self._remotes = {} 61 self._remotes = {}
61 self._branches = {} 62 self._branches = {}
62 self._pickle = os.path.join( 63 self._pickle = os.path.join(
@@ -168,6 +169,33 @@ class GitConfig(object):
168 self._branches[b.name] = b 169 self._branches[b.name] = b
169 return b 170 return b
170 171
172 def HasSection(self, section, subsection = ''):
173 """Does at least one key in section.subsection exist?
174 """
175 try:
176 return subsection in self._sections[section]
177 except KeyError:
178 return False
179
180 @property
181 def _sections(self):
182 d = self._section_dict
183 if d is None:
184 d = {}
185 for name in self._cache.keys():
186 p = name.split('.')
187 if 2 == len(p):
188 section = p[0]
189 subsect = ''
190 else:
191 section = p[0]
192 subsect = '.'.join(p[1:-1])
193 if section not in d:
194 d[section] = set()
195 d[section].add(subsect)
196 self._section_dict = d
197 return d
198
171 @property 199 @property
172 def _cache(self): 200 def _cache(self):
173 if self._cache_dict is None: 201 if self._cache_dict is None:
@@ -443,11 +471,23 @@ class Branch(object):
443 def Save(self): 471 def Save(self):
444 """Save this branch back into the configuration. 472 """Save this branch back into the configuration.
445 """ 473 """
446 self._Set('merge', self.merge) 474 if self._config.HasSection('branch', self.name):
447 if self.remote: 475 if self.remote:
448 self._Set('remote', self.remote.name) 476 self._Set('remote', self.remote.name)
477 else:
478 self._Set('remote', None)
479 self._Set('merge', self.merge)
480
449 else: 481 else:
450 self._Set('remote', None) 482 fd = open(self._config.file, 'ab')
483 try:
484 fd.write('[branch "%s"]\n' % self.name)
485 if self.remote:
486 fd.write('\tremote = %s\n' % self.remote.name)
487 if self.merge:
488 fd.write('\tmerge = %s\n' % self.merge)
489 finally:
490 fd.close()
451 491
452 def _Set(self, key, value): 492 def _Set(self, key, value):
453 key = 'branch.%s.%s' % (self.name, key) 493 key = 'branch.%s.%s' % (self.name, key)
diff --git a/project.py b/project.py
index 79ade3b6..8d6e4b6c 100644
--- a/project.py
+++ b/project.py
@@ -30,6 +30,21 @@ from remote import Remote
30 30
31from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M 31from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M
32 32
33def _lwrite(path, content):
34 lock = '%s.lock' % path
35
36 fd = open(lock, 'wb')
37 try:
38 fd.write(content)
39 finally:
40 fd.close()
41
42 try:
43 os.rename(lock, path)
44 except OSError:
45 os.remove(lock)
46 raise
47
33def _error(fmt, *args): 48def _error(fmt, *args):
34 msg = fmt % args 49 msg = fmt % args
35 print >>sys.stderr, 'error: %s' % msg 50 print >>sys.stderr, 'error: %s' % msg
@@ -758,31 +773,54 @@ class Project(object):
758 def StartBranch(self, name): 773 def StartBranch(self, name):
759 """Create a new branch off the manifest's revision. 774 """Create a new branch off the manifest's revision.
760 """ 775 """
761 try: 776 head = self.work_git.GetHead()
762 self.bare_git.rev_parse(R_HEADS + name) 777 if head == (R_HEADS + name):
763 exists = True 778 return True
764 except GitError:
765 exists = False;
766 779
767 if exists: 780 all = self.bare_ref.all
768 if name == self.CurrentBranch: 781 if (R_HEADS + name) in all:
769 return True 782 cmd = ['checkout', name, '--']
770 else: 783 return GitCommand(self,
771 cmd = ['checkout', name, '--'] 784 cmd,
772 return GitCommand(self, cmd).Wait() == 0 785 capture_stdout = True).Wait() == 0
786
787 branch = self.GetBranch(name)
788 branch.remote = self.GetRemote(self.remote.name)
789 branch.merge = self.revision
773 790
791 rev = branch.LocalMerge
792 if rev in all:
793 revid = all[rev]
794 elif IsId(rev):
795 revid = rev
774 else: 796 else:
775 branch = self.GetBranch(name) 797 revid = None
776 branch.remote = self.GetRemote(self.remote.name) 798
777 branch.merge = self.revision 799 if head.startswith(R_HEADS):
778 800 try:
779 rev = branch.LocalMerge 801 head = all[head]
780 cmd = ['checkout', '-b', branch.name, rev] 802 except KeyError:
781 if GitCommand(self, cmd).Wait() == 0: 803 head = None
782 branch.Save() 804
783 return True 805 if revid and head and revid == head:
784 else: 806 ref = os.path.join(self.gitdir, R_HEADS + name)
785 return False 807 try:
808 os.makedirs(os.path.dirname(ref))
809 except OSError:
810 pass
811 _lwrite(ref, '%s\n' % revid)
812 _lwrite(os.path.join(self.worktree, '.git', HEAD),
813 'ref: %s%s\n' % (R_HEADS, name))
814 branch.Save()
815 return True
816
817 cmd = ['checkout', '-b', branch.name, rev]
818 if GitCommand(self,
819 cmd,
820 capture_stdout = True).Wait() == 0:
821 branch.Save()
822 return True
823 return False
786 824
787 def CheckoutBranch(self, name): 825 def CheckoutBranch(self, name):
788 """Checkout a local topic branch. 826 """Checkout a local topic branch.