##// END OF EJS Templates
subrepo: lazily update git's local tracking branches...
Eric Eisner -
r13087:cca0779b default
parent child Browse files
Show More
@@ -691,6 +691,19 b' class gitsubrepo(object):'
691 rev2branch.setdefault(revision, []).append(branch)
691 rev2branch.setdefault(revision, []).append(branch)
692 return current, branch2rev, rev2branch
692 return current, branch2rev, rev2branch
693
693
694 def _gittracking(self, branches):
695 'return map of remote branch to local tracking branch'
696 # assumes no more than one local tracking branch for each remote
697 tracking = {}
698 for b in branches:
699 if b.startswith('remotes/'):
700 continue
701 remote = self._gitcommand(['config', 'branch.%s.remote' % b])
702 if remote:
703 ref = self._gitcommand(['config', 'branch.%s.merge' % b])
704 tracking['remotes/%s/%s' % (remote, ref.split('/')[-1])] = b
705 return tracking
706
694 def _fetch(self, source, revision):
707 def _fetch(self, source, revision):
695 if not os.path.exists('%s/.git' % self._path):
708 if not os.path.exists('%s/.git' % self._path):
696 self._ui.status(_('cloning subrepo %s\n') % self._relpath)
709 self._ui.status(_('cloning subrepo %s\n') % self._relpath)
@@ -724,13 +737,17 b' class gitsubrepo(object):'
724 elif self._gitstate() == revision:
737 elif self._gitstate() == revision:
725 return
738 return
726 current, branch2rev, rev2branch = self._gitbranchmap()
739 current, branch2rev, rev2branch = self._gitbranchmap()
727 if revision not in rev2branch:
740
741 def rawcheckout():
728 # no branch to checkout, check it out with no branch
742 # no branch to checkout, check it out with no branch
729 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
743 self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
730 self._relpath)
744 self._relpath)
731 self._ui.warn(_('check out a git branch if you intend '
745 self._ui.warn(_('check out a git branch if you intend '
732 'to make changes\n'))
746 'to make changes\n'))
733 self._gitcommand(['checkout', '-q', revision])
747 self._gitcommand(['checkout', '-q', revision])
748
749 if revision not in rev2branch:
750 rawcheckout()
734 return
751 return
735 branches = rev2branch[revision]
752 branches = rev2branch[revision]
736 firstlocalbranch = None
753 firstlocalbranch = None
@@ -743,10 +760,34 b' class gitsubrepo(object):'
743 firstlocalbranch = b
760 firstlocalbranch = b
744 if firstlocalbranch:
761 if firstlocalbranch:
745 self._gitcommand(['checkout', firstlocalbranch])
762 self._gitcommand(['checkout', firstlocalbranch])
746 else:
763 return
747 remote = branches[0]
764
765 tracking = self._gittracking(branch2rev.keys())
766 # choose a remote branch already tracked if possible
767 remote = branches[0]
768 if remote not in tracking:
769 for b in branches:
770 if b in tracking:
771 remote = b
772 break
773
774 if remote not in tracking:
775 # create a new local tracking branch
748 local = remote.split('/')[-1]
776 local = remote.split('/')[-1]
749 self._gitcommand(['checkout', '-b', local, remote])
777 self._gitcommand(['checkout', '-b', local, remote])
778 elif self._gitisancestor(branch2rev[tracking[remote]], remote):
779 # When updating to a tracked remote branch,
780 # if the local tracking branch is downstream of it,
781 # a normal `git pull` would have performed a "fast-forward merge"
782 # which is equivalent to updating the local branch to the remote.
783 # Since we are only looking at branching at update, we need to
784 # detect this situation and perform this action lazily.
785 if tracking[remote] != current:
786 self._gitcommand(['checkout', tracking[remote]])
787 self._gitcommand(['merge', '--ff', remote])
788 else:
789 # a real merge would be required, just checkout the revision
790 rawcheckout()
750
791
751 def commit(self, text, user, date):
792 def commit(self, text, user, date):
752 cmd = ['commit', '-a', '-m', text]
793 cmd = ['commit', '-a', '-m', text]
@@ -209,6 +209,31 b' make and push changes to hg without upda'
209 adding file changes
209 adding file changes
210 added 1 changesets with 1 changes to 1 files
210 added 1 changesets with 1 changes to 1 files
211
211
212 sync to upstream git, distribute changes
213
214 $ cd ../ta
215 $ hg pull -u -q
216 $ cd s
217 $ git pull -q
218 $ cd ..
219 $ hg commit -m 'git upstream sync'
220 committing subrepository $TESTTMP/ta/s
221 $ hg debugsub
222 path s
223 source ../gitroot
224 revision 32a343883b74769118bb1d3b4b1fbf9156f4dddc
225 $ hg push -q
226
227 $ cd ../tb
228 $ hg pull -q
229 $ hg update
230 pulling subrepo s
231 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 $ hg debugsub
233 path s
234 source ../gitroot
235 revision 32a343883b74769118bb1d3b4b1fbf9156f4dddc
236
212 update to a revision without the subrepo, keeping the local git repository
237 update to a revision without the subrepo, keeping the local git repository
213
238
214 $ cd ../t
239 $ cd ../t
@@ -230,7 +255,7 b' update to a revision without the subrepo'
230 archive subrepos
255 archive subrepos
231
256
232 $ cd ../t
257 $ cd ../t
233 $ hg archive --subrepos -r tip ../archive
258 $ hg archive --subrepos -r 5 ../archive
234 pulling subrepo s
259 pulling subrepo s
235 $ cd ../archive
260 $ cd ../archive
236 $ cat s/f
261 $ cat s/f
@@ -239,4 +264,3 b' archive subrepos'
239 g
264 g
240 gg
265 gg
241 ggg
266 ggg
242
General Comments 0
You need to be logged in to leave comments. Login now