diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1280,19 +1280,32 @@ def walkchangerevs(repo, match, opts, pr yield change(rev) return iterate() -def add(ui, repo, match, dryrun): +def add(ui, repo, match, dryrun, listsubrepos, prefix): + join = lambda f: os.path.join(prefix, f) bad = [] oldbad = match.bad match.bad = lambda x, y: bad.append(x) or oldbad(x, y) names = [] + wctx = repo[None] for f in repo.walk(match): exact = match.exact(f) if exact or f not in repo.dirstate: names.append(f) if ui.verbose or not exact: - ui.status(_('adding %s\n') % match.rel(f)) + ui.status(_('adding %s\n') % match.rel(join(f))) + + if listsubrepos: + for subpath in wctx.substate: + sub = wctx.sub(subpath) + try: + submatch = matchmod.narrowmatcher(subpath, match) + bad.extend(sub.add(ui, submatch, dryrun, prefix)) + except error.LookupError: + ui.status(_("skipping missing subrepository: %s\n") + % join(subpath)) + if not dryrun: - rejected = repo[None].add(names) + rejected = wctx.add(names, prefix) bad.extend(f for f in rejected if f in match.files()) return bad diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -47,7 +47,8 @@ def add(ui, repo, *pats, **opts): """ m = cmdutil.match(repo, pats, opts) - rejected = cmdutil.add(ui, repo, m, opts.get('dry_run')) + rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'), + opts.get('subrepos'), prefix="") return rejected and 1 or 0 def addremove(ui, repo, *pats, **opts): @@ -4001,7 +4002,8 @@ subrepoopts = [ ] table = { - "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')), + "^add": (add, walkopts + subrepoopts + dryrunopts, + _('[OPTION]... [FILE]...')), "addremove": (addremove, similarityopts + walkopts + dryrunopts, _('[OPTION]... [FILE]...')), diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -769,7 +769,8 @@ class workingctx(changectx): self.modified() or self.added() or self.removed() or (missing and self.deleted())) - def add(self, list): + def add(self, list, prefix=""): + join = lambda f: os.path.join(prefix, f) wlock = self._repo.wlock() ui, ds = self._repo.ui, self._repo.dirstate try: @@ -779,7 +780,7 @@ class workingctx(changectx): try: st = os.lstat(p) except: - ui.warn(_("%s does not exist!\n") % f) + ui.warn(_("%s does not exist!\n") % join(f)) rejected.append(f) continue if st.st_size > 10000000: @@ -787,13 +788,13 @@ class workingctx(changectx): "to manage this file\n" "(use 'hg revert %s' to cancel the " "pending addition)\n") - % (f, 3 * st.st_size // 1000000, f)) + % (f, 3 * st.st_size // 1000000, join(f))) if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)): ui.warn(_("%s not added: only files and symlinks " - "supported currently\n") % f) + "supported currently\n") % join(f)) rejected.append(p) elif ds[f] in 'amn': - ui.warn(_("%s already tracked!\n") % f) + ui.warn(_("%s already tracked!\n") % join(f)) elif ds[f] == 'r': ds.normallookup(f) else: diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -255,6 +255,8 @@ class abstractsubrepo(object): """ raise NotImplementedError + def add(self, ui, match, dryrun, prefix): + return [] def status(self, rev2, **opts): return [], [], [], [], [], [], [] @@ -291,6 +293,10 @@ class hgsubrepo(abstractsubrepo): addpathconfig('default-push', defpushpath) fp.close() + def add(self, ui, match, dryrun, prefix): + return cmdutil.add(ui, self._repo, match, dryrun, True, + os.path.join(prefix, self._path)) + def status(self, rev2, **opts): try: rev1 = self._state[1] diff --git a/tests/test-debugcomplete.t b/tests/test-debugcomplete.t --- a/tests/test-debugcomplete.t +++ b/tests/test-debugcomplete.t @@ -176,7 +176,7 @@ Show an error if we use --options with a Show all commands + options $ hg debugcommands - add: include, exclude, dry-run + add: include, exclude, subrepos, dry-run annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd commit: addremove, close-branch, include, exclude, message, logfile, date, user diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -274,6 +274,7 @@ Test short command list with verbose opt -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns + -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output [+] marked option can be specified multiple times @@ -312,6 +313,7 @@ Verbose help for add -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns + -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output global options: @@ -364,6 +366,7 @@ Test help option with version option -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns + -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output [+] marked option can be specified multiple times @@ -391,6 +394,7 @@ Test help option with version option -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns + -S --subrepos recurse into subrepositories -n --dry-run do not perform actions, just print output [+] marked option can be specified multiple times diff --git a/tests/test-subrepo-recursion.t b/tests/test-subrepo-recursion.t --- a/tests/test-subrepo-recursion.t +++ b/tests/test-subrepo-recursion.t @@ -8,25 +8,30 @@ Create test repository: $ hg init $ echo x1 > x.txt - $ hg add x.txt $ hg init foo $ cd foo $ echo y1 > y.txt - $ hg add y.txt $ hg init bar $ cd bar $ echo z1 > z.txt - $ hg add z.txt $ cd .. $ echo 'bar = bar' > .hgsub - $ hg add .hgsub $ cd .. $ echo 'foo = foo' > .hgsub - $ hg add .hgsub + +Add files --- .hgsub files must go first to trigger subrepos: + + $ hg add -S .hgsub + $ hg add -S foo/.hgsub + $ hg add -S foo/bar + adding foo/bar/z.txt + $ hg add -S + adding x.txt + adding foo/y.txt Test recursive status without committing anything: