summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjiajia tang <tangjiajia@xiaomi.com>2021-04-25 20:02:02 +0800
committerMike Frysinger <vapier@google.com>2021-05-01 13:26:08 +0000
commita590e640a69b1a6ba448600cbc7f3be31178bc92 (patch)
tree3fb624ed517f1306cc03e076e95f5ece1734ebbf
parentf69c7ee3187eded54e83d2524fea423706380766 (diff)
downloadgit-repo-a590e640a69b1a6ba448600cbc7f3be31178bc92.tar.gz
Update copyfile and linkfile if manifest updated
Currently, copyfiles and linkfiles which marked by "<copyfile/>" and "<linkfile/>" in manifest will be created by first exec 'repo sync'. But if some "<copyfile/>" or "<linkfile/>" are removed in manifest, then 'repo sync', these removed item dest can not be removed in the sourcecode workspace. This patch is intent to fix this issue, by save a 'copy-link-files.json' in .repo and then compared with new dest path when next sync. If any "<copyfile/>" or "<linkfile/>" were removed, the dest path will be removed in sourcecode at the same time. Bug: https://crbug.com/gerrit/11008 Change-Id: I6b7b41e94df0f9e6e52801ec755951a4c572d05d Signed-off-by: jiajia tang <tangjiajia@xiaomi.com> Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/304202 Reviewed-by: Mike Frysinger <vapier@google.com>
-rw-r--r--docs/internal-fs-layout.md2
-rw-r--r--subcmds/sync.py64
2 files changed, 66 insertions, 0 deletions
diff --git a/docs/internal-fs-layout.md b/docs/internal-fs-layout.md
index 0c59f988..8cc3cabd 100644
--- a/docs/internal-fs-layout.md
+++ b/docs/internal-fs-layout.md
@@ -110,6 +110,8 @@ Instead, you should use standard Git workflows like [git worktree] or
110[gitsubmodules] with [superprojects]. 110[gitsubmodules] with [superprojects].
111*** 111***
112 112
113* `copy-link-files.json`: Tracking file used by `repo sync` to determine when
114 copyfile or linkfile are added or removed and need corresponding updates.
113* `project.list`: Tracking file used by `repo sync` to determine when projects 115* `project.list`: Tracking file used by `repo sync` to determine when projects
114 are added or removed and need corresponding updates in the checkout. 116 are added or removed and need corresponding updates in the checkout.
115* `projects/`: Bare checkouts of every project synced by the manifest. The 117* `projects/`: Bare checkouts of every project synced by the manifest. The
diff --git a/subcmds/sync.py b/subcmds/sync.py
index aafec1d2..0c386add 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -12,6 +12,7 @@
12# See the License for the specific language governing permissions and 12# See the License for the specific language governing permissions and
13# limitations under the License. 13# limitations under the License.
14 14
15import errno
15import functools 16import functools
16import http.cookiejar as cookielib 17import http.cookiejar as cookielib
17import io 18import io
@@ -614,6 +615,60 @@ later is required to fix a server side protocol bug.
614 fd.write('\n') 615 fd.write('\n')
615 return 0 616 return 0
616 617
618 def UpdateCopyLinkfileList(self):
619 """Save all dests of copyfile and linkfile, and update them if needed.
620
621 Returns:
622 Whether update was successful.
623 """
624 new_paths = {}
625 new_linkfile_paths = []
626 new_copyfile_paths = []
627 for project in self.GetProjects(None, missing_ok=True):
628 new_linkfile_paths.extend(x.dest for x in project.linkfiles)
629 new_copyfile_paths.extend(x.dest for x in project.copyfiles)
630
631 new_paths = {
632 'linkfile': new_linkfile_paths,
633 'copyfile': new_copyfile_paths,
634 }
635
636 copylinkfile_name = 'copy-link-files.json'
637 copylinkfile_path = os.path.join(self.manifest.repodir, copylinkfile_name)
638 old_copylinkfile_paths = {}
639
640 if os.path.exists(copylinkfile_path):
641 with open(copylinkfile_path, 'rb') as fp:
642 try:
643 old_copylinkfile_paths = json.load(fp)
644 except:
645 print('error: %s is not a json formatted file.' %
646 copylinkfile_path, file=sys.stderr)
647 platform_utils.remove(copylinkfile_path)
648 return False
649
650 need_remove_files = []
651 need_remove_files.extend(
652 set(old_copylinkfile_paths.get('linkfile', [])) -
653 set(new_linkfile_paths))
654 need_remove_files.extend(
655 set(old_copylinkfile_paths.get('copyfile', [])) -
656 set(new_copyfile_paths))
657
658 for need_remove_file in need_remove_files:
659 try:
660 platform_utils.remove(need_remove_file)
661 except OSError as e:
662 if e.errno == errno.ENOENT:
663 # Try to remove the updated copyfile or linkfile.
664 # So, if the file is not exist, nothing need to do.
665 pass
666
667 # Create copy-link-files.json, save dest path of "copyfile" and "linkfile".
668 with open(copylinkfile_path, 'w', encoding='utf-8') as fp:
669 json.dump(new_paths, fp)
670 return True
671
617 def _SmartSyncSetup(self, opt, smart_sync_manifest_path): 672 def _SmartSyncSetup(self, opt, smart_sync_manifest_path):
618 if not self.manifest.manifest_server: 673 if not self.manifest.manifest_server:
619 print('error: cannot smart sync: no manifest server defined in ' 674 print('error: cannot smart sync: no manifest server defined in '
@@ -914,6 +969,13 @@ later is required to fix a server side protocol bug.
914 print('\nerror: Local checkouts *not* updated.', file=sys.stderr) 969 print('\nerror: Local checkouts *not* updated.', file=sys.stderr)
915 sys.exit(1) 970 sys.exit(1)
916 971
972 if not self.UpdateCopyLinkfileList():
973 err_event.set()
974 err_update_linkfiles = True
975 if opt.fail_fast:
976 print('\nerror: Local update copyfile or linkfile failed.', file=sys.stderr)
977 sys.exit(1)
978
917 err_results = [] 979 err_results = []
918 # NB: We don't exit here because this is the last step. 980 # NB: We don't exit here because this is the last step.
919 err_checkout = not self._Checkout(all_projects, opt, err_results) 981 err_checkout = not self._Checkout(all_projects, opt, err_results)
@@ -932,6 +994,8 @@ later is required to fix a server side protocol bug.
932 print('error: Downloading network changes failed.', file=sys.stderr) 994 print('error: Downloading network changes failed.', file=sys.stderr)
933 if err_update_projects: 995 if err_update_projects:
934 print('error: Updating local project lists failed.', file=sys.stderr) 996 print('error: Updating local project lists failed.', file=sys.stderr)
997 if err_update_linkfiles:
998 print('error: Updating copyfiles or linkfiles failed.', file=sys.stderr)
935 if err_checkout: 999 if err_checkout:
936 print('error: Checking out local projects failed.', file=sys.stderr) 1000 print('error: Checking out local projects failed.', file=sys.stderr)
937 if err_results: 1001 if err_results: