Modify 'repo abandon' to be more like 'repo checkout' and 'repo start'
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/project.py b/project.py
index 029a80f..3b9535e 100644
--- a/project.py
+++ b/project.py
@@ -862,18 +862,38 @@
def AbandonBranch(self, name):
"""Destroy a local topic branch.
"""
- try:
- tip_rev = self.bare_git.rev_parse(R_HEADS + name)
- except GitError:
- return
+ rev = R_HEADS + name
+ all = self.bare_ref.all
+ if rev not in all:
+ # Doesn't exist; assume already abandoned.
+ #
+ return True
- if self.CurrentBranch == name:
- self._Checkout(
- self.GetRemote(self.remote.name).ToLocal(self.revision),
- quiet=True)
+ head = self.work_git.GetHead()
+ if head == rev:
+ # We can't destroy the branch while we are sitting
+ # on it. Switch to a detached HEAD.
+ #
+ head = all[head]
- cmd = ['branch', '-D', name]
- GitCommand(self, cmd, capture_stdout=True).Wait()
+ rev = self.GetRemote(self.remote.name).ToLocal(self.revision)
+ if rev in all:
+ revid = all[rev]
+ elif IsId(rev):
+ revid = rev
+ else:
+ revid = None
+
+ if revid and head == revid:
+ _lwrite(os.path.join(self.worktree, '.git', HEAD),
+ '%s\n' % revid)
+ else:
+ self._Checkout(rev, quiet=True)
+
+ return GitCommand(self,
+ ['branch', '-D', name],
+ capture_stdout = True,
+ capture_stderr = True).Wait() == 0
def PruneHeads(self):
"""Prune any topic branches already merged into upstream.
diff --git a/subcmds/abandon.py b/subcmds/abandon.py
index 4f976d7..8af6132 100644
--- a/subcmds/abandon.py
+++ b/subcmds/abandon.py
@@ -16,6 +16,7 @@
import sys
from command import Command
from git_command import git
+from progress import Progress
class Abandon(Command):
common = True
@@ -38,5 +39,23 @@
print >>sys.stderr, "error: '%s' is not a valid name" % nb
sys.exit(1)
- for project in self.GetProjects(args[1:]):
- project.AbandonBranch(nb)
+ nb = args[0]
+ err = []
+ all = self.GetProjects(args[1:])
+
+ pm = Progress('Abandon %s' % nb, len(all))
+ for project in all:
+ pm.update()
+ if not project.AbandonBranch(nb):
+ err.append(project)
+ pm.end()
+
+ if err:
+ if len(err) == len(all):
+ print >>sys.stderr, 'error: no project has branch %s' % nb
+ else:
+ for p in err:
+ print >>sys.stderr,\
+ "error: %s/: cannot abandon %s" \
+ % (p.relpath, nb)
+ sys.exit(1)