| 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 |