Change repo sync to be more friendly when updating the tree

We now try to sync all projects that can be done safely first, before
we start rebasing user commits over the upstream.  This has the nice
effect of making the local tree as close to the upstream as possible
before the user has to start resolving merge conflicts, as that extra
information in other projects may aid in the conflict resolution.

Informational output is buffered and delayed until calculation for
all projects has been done, so that the user gets one concise list
of notice messages, rather than it interrupting the progress meter.

Fast-forward output is now prefixed with the project header, so the
user can see which project that update is taking place in, and make
some relation of the diffstat back to the project name.

Rebase output is now prefixed with the project header, so that if
the rebase fails, the user can see which project we were operating
on and can try to address the failure themselves.

Since rebase sits on a detached HEAD, we now look for an in-progress
rebase during sync, so we can alert the user that the given project
is in a state we cannot handle.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-04-16 11:21:18 -07:00
parent 48244781c2
commit 350cde4c4b
4 changed files with 175 additions and 62 deletions

View File

@@ -20,6 +20,7 @@ from color import Coloring
from command import InteractiveCommand, MirrorSafeCommand
from error import ManifestParseError
from remote import Remote
from project import SyncBuffer
from git_command import git, MIN_GIT_VERSION
class Init(InteractiveCommand, MirrorSafeCommand):
@@ -129,7 +130,10 @@ default.xml will be used.
print >>sys.stderr, 'fatal: cannot obtain manifest %s' % r.url
sys.exit(1)
m.Sync_LocalHalf()
syncbuf = SyncBuffer(m.config)
m.Sync_LocalHalf(syncbuf)
syncbuf.Finish()
if is_new or m.CurrentBranch is None:
if not m.StartBranch('default'):
print >>sys.stderr, 'fatal: cannot create default in manifest'

View File

@@ -24,6 +24,7 @@ from project import HEAD
from command import Command, MirrorSafeCommand
from error import RepoChangedException, GitError
from project import R_HEADS
from project import SyncBuffer
from progress import Progress
class Sync(Command, MirrorSafeCommand):
@@ -112,7 +113,9 @@ revision is temporarily needed.
return
if mp.HasChanges:
if not mp.Sync_LocalHalf():
syncbuf = SyncBuffer(mp.config)
mp.Sync_LocalHalf(syncbuf)
if not syncbuf.Finish():
sys.exit(1)
self.manifest._Unload()
@@ -123,14 +126,17 @@ revision is temporarily needed.
missing.append(project)
self._Fetch(*missing)
syncbuf = SyncBuffer(mp.config,
detach_head = opt.detach_head)
pm = Progress('Syncing work tree', len(all))
for project in all:
pm.update()
if project.worktree:
if not project.Sync_LocalHalf(
detach_head=opt.detach_head):
sys.exit(1)
project.Sync_LocalHalf(syncbuf)
pm.end()
print >>sys.stderr
if not syncbuf.Finish():
sys.exit(1)
def _PostRepoUpgrade(manifest):
@@ -143,7 +149,9 @@ def _PostRepoFetch(rp, no_repo_verify=False, verbose=False):
print >>sys.stderr, 'info: A new version of repo is available'
print >>sys.stderr, ''
if no_repo_verify or _VerifyTag(rp):
if not rp.Sync_LocalHalf():
syncbuf = SyncBuffer(rp.config)
rp.Sync_LocalHalf(syncbuf)
if not syncbuf.Finish():
sys.exit(1)
print >>sys.stderr, 'info: Restarting repo with latest version'
raise RepoChangedException(['--repo-upgraded'])