OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Meta checkout manager supporting both Subversion and GIT.""" | 6 """Meta checkout manager supporting both Subversion and GIT.""" |
7 # Files | 7 # Files |
8 # .gclient : Current client configuration, written by 'config' command. | 8 # .gclient : Current client configuration, written by 'config' command. |
9 # Format is a Python script defining 'solutions', a list whose | 9 # Format is a Python script defining 'solutions', a list whose |
10 # entries each are maps binding the strings "name" and "url" | 10 # entries each are maps binding the strings "name" and "url" |
(...skipping 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 full_entries = [os.path.join(self.root_dir, e.replace('/', os.path.sep)) | 1535 full_entries = [os.path.join(self.root_dir, e.replace('/', os.path.sep)) |
1536 for e in entries] | 1536 for e in entries] |
1537 | 1537 |
1538 for entry, prev_url in self._ReadEntries().iteritems(): | 1538 for entry, prev_url in self._ReadEntries().iteritems(): |
1539 if not prev_url: | 1539 if not prev_url: |
1540 # entry must have been overridden via .gclient custom_deps | 1540 # entry must have been overridden via .gclient custom_deps |
1541 continue | 1541 continue |
1542 # Fix path separator on Windows. | 1542 # Fix path separator on Windows. |
1543 entry_fixed = entry.replace('/', os.path.sep) | 1543 entry_fixed = entry.replace('/', os.path.sep) |
1544 e_dir = os.path.join(self.root_dir, entry_fixed) | 1544 e_dir = os.path.join(self.root_dir, entry_fixed) |
| 1545 |
| 1546 def _IsParentOfAny(parent, path_list): |
| 1547 parent_plus_slash = parent + '/' |
| 1548 return any( |
| 1549 path[:len(parent_plus_slash)] == parent_plus_slash |
| 1550 for path in path_list) |
| 1551 |
1545 # Use entry and not entry_fixed there. | 1552 # Use entry and not entry_fixed there. |
1546 if (entry not in entries and | 1553 if (entry not in entries and |
1547 (not any(path.startswith(entry + '/') for path in entries)) and | 1554 (not any(path.startswith(entry + '/') for path in entries)) and |
1548 os.path.exists(e_dir)): | 1555 os.path.exists(e_dir)): |
1549 # The entry has been removed from DEPS. | |
1550 scm = gclient_scm.CreateSCM( | 1556 scm = gclient_scm.CreateSCM( |
1551 prev_url, self.root_dir, entry_fixed, self.outbuf) | 1557 prev_url, self.root_dir, entry_fixed, self.outbuf) |
1552 | 1558 |
1553 # Check to see if this directory is now part of a higher-up checkout. | 1559 # Check to see if this directory is now part of a higher-up checkout. |
1554 # The directory might be part of a git OR svn checkout. | 1560 # The directory might be part of a git OR svn checkout. |
1555 scm_root = None | 1561 scm_root = None |
1556 scm_class = None | |
1557 for scm_class in (gclient_scm.scm.GIT, gclient_scm.scm.SVN): | 1562 for scm_class in (gclient_scm.scm.GIT, gclient_scm.scm.SVN): |
1558 try: | 1563 try: |
1559 scm_root = scm_class.GetCheckoutRoot(scm.checkout_path) | 1564 scm_root = scm_class.GetCheckoutRoot(scm.checkout_path) |
1560 except subprocess2.CalledProcessError: | 1565 except subprocess2.CalledProcessError: |
1561 pass | 1566 pass |
1562 if scm_root: | 1567 if scm_root: |
1563 break | 1568 break |
1564 else: | 1569 else: |
1565 logging.warning('Could not find checkout root for %s. Unable to ' | 1570 logging.warning('Could not find checkout root for %s. Unable to ' |
1566 'determine whether it is part of a higher-level ' | 1571 'determine whether it is part of a higher-level ' |
1567 'checkout, so not removing.' % entry) | 1572 'checkout, so not removing.' % entry) |
1568 continue | 1573 continue |
1569 | |
1570 # This is to handle the case of third_party/WebKit migrating from | |
1571 # being a DEPS entry to being part of the main project. | |
1572 # If the subproject is a Git project, we need to remove its .git | |
1573 # folder. Otherwise git operations on that folder will have different | |
1574 # effects depending on the current working directory. | |
1575 if scm_class == gclient_scm.scm.GIT and ( | |
1576 os.path.abspath(scm_root) == os.path.abspath(e_dir)): | |
1577 e_par_dir = os.path.join(e_dir, os.pardir) | |
1578 if scm_class.IsInsideWorkTree(e_par_dir): | |
1579 par_scm_root = scm_class.GetCheckoutRoot(e_par_dir) | |
1580 # rel_e_dir : relative path of entry w.r.t. its parent repo. | |
1581 rel_e_dir = os.path.relpath(e_dir, par_scm_root) | |
1582 if scm_class.IsDirectoryVersioned(par_scm_root, rel_e_dir): | |
1583 save_dir = scm.GetGitBackupDirPath() | |
1584 # Remove any eventual stale backup dir for the same project. | |
1585 if os.path.exists(save_dir): | |
1586 gclient_utils.rmtree(save_dir) | |
1587 os.rename(os.path.join(e_dir, '.git'), save_dir) | |
1588 # When switching between the two states (entry/ is a subproject | |
1589 # -> entry/ is part of the outer project), it is very likely | |
1590 # that some files are changed in the checkout, unless we are | |
1591 # jumping *exactly* across the commit which changed just DEPS. | |
1592 # In such case we want to cleanup any eventual stale files | |
1593 # (coming from the old subproject) in order to end up with a | |
1594 # clean checkout. | |
1595 scm_class.CleanupDir(par_scm_root, rel_e_dir) | |
1596 assert not os.path.exists(os.path.join(e_dir, '.git')) | |
1597 print(('\nWARNING: \'%s\' has been moved from DEPS to a higher ' | |
1598 'level checkout. The git folder containing all the local' | |
1599 ' branches has been saved to %s.\n' | |
1600 'If you don\'t care about its state you can safely ' | |
1601 'remove that folder to free up space.') % | |
1602 (entry, save_dir)) | |
1603 continue | |
1604 | |
1605 if scm_root in full_entries: | 1574 if scm_root in full_entries: |
1606 logging.info('%s is part of a higher level checkout, not removing', | 1575 logging.info('%s is part of a higher level checkout, not ' |
1607 scm.GetCheckoutRoot()) | 1576 'removing.', scm.GetCheckoutRoot()) |
1608 continue | 1577 continue |
1609 | 1578 |
1610 file_list = [] | 1579 file_list = [] |
1611 scm.status(self._options, [], file_list) | 1580 scm.status(self._options, [], file_list) |
1612 modified_files = file_list != [] | 1581 modified_files = file_list != [] |
1613 if (not self._options.delete_unversioned_trees or | 1582 if (not self._options.delete_unversioned_trees or |
1614 (modified_files and not self._options.force)): | 1583 (modified_files and not self._options.force)): |
1615 # There are modified files in this entry. Keep warning until | 1584 # There are modified files in this entry. Keep warning until |
1616 # removed. | 1585 # removed. |
1617 print(('\nWARNING: \'%s\' is no longer part of this client. ' | 1586 print(('\nWARNING: \'%s\' is no longer part of this client. ' |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2288 print >> sys.stderr, 'Error: %s' % str(e) | 2257 print >> sys.stderr, 'Error: %s' % str(e) |
2289 return 1 | 2258 return 1 |
2290 finally: | 2259 finally: |
2291 gclient_utils.PrintWarnings() | 2260 gclient_utils.PrintWarnings() |
2292 | 2261 |
2293 | 2262 |
2294 if '__main__' == __name__: | 2263 if '__main__' == __name__: |
2295 sys.exit(Main(sys.argv[1:])) | 2264 sys.exit(Main(sys.argv[1:])) |
2296 | 2265 |
2297 # vim: ts=2:sw=2:tw=80:et: | 2266 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |