diff options
| -rw-r--r-- | git_config.py | 48 | ||||
| -rw-r--r-- | project.py | 82 |
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) |
| @@ -30,6 +30,21 @@ from remote import Remote | |||
| 30 | 30 | ||
| 31 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M | 31 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M |
| 32 | 32 | ||
| 33 | def _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 | |||
| 33 | def _error(fmt, *args): | 48 | def _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. |
