From 3ade5bbd92b506f215f86a7d41048b22b287c673 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Thu, 8 Oct 2020 10:09:15 -0400 Subject: [PATCH] msubprojects: Handle change of URL in wrap-git --- docs/markdown/Subprojects.md | 5 +++- docs/markdown/snippets/subprojects_update.md | 5 +++- mesonbuild/msubprojects.py | 28 +++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/docs/markdown/Subprojects.md b/docs/markdown/Subprojects.md index 379c7755c..446137355 100644 --- a/docs/markdown/Subprojects.md +++ b/docs/markdown/Subprojects.md @@ -300,7 +300,7 @@ To pull latest version of all your subprojects at once, just run the command: prevent from any loss of local changes. - If subproject is currently in detached mode, a checkout of the revision from wrap file is performed. *Since 0.56.0* a rebase is also performed in case the - revision already existed locally by was outdated. If `--reset` is specified, + revision already existed locally but was outdated. If `--reset` is specified, a hard reset is performed instead of rebase. - If subproject is currently at the same branch as specified by the wrap file, a rebase on `origin` commit is performed. *Since 0.56.0* If `--reset` is @@ -312,6 +312,9 @@ To pull latest version of all your subprojects at once, just run the command: file is performed and a rebase is also performed in case the revision already existed locally by was outdated. If `--reset` is specified, a hard reset is performed instead of rebase. +- *Since 0.56.0* if the `url` specified in wrap file is different to the URL set + on `origin` for a git repository it will not be updated, unless `--reset` is + specified in which case the URL of `origin` will be reset first. ### Start a topic branch across all git subprojects diff --git a/docs/markdown/snippets/subprojects_update.md b/docs/markdown/snippets/subprojects_update.md index 022545eb2..f85a9ebcc 100644 --- a/docs/markdown/snippets/subprojects_update.md +++ b/docs/markdown/snippets/subprojects_update.md @@ -17,12 +17,15 @@ If the command fails on any subproject the execution continues with other subprojects, but at the end an error code is now returned. The `update` subcommand has been reworked: +- In the case the URL of `origin` is different as the `url` set in wrap file, + the subproject will not be updated unless `--reset` is specified (see below). - The `--rebase` behaviour is now the default for consistency: it was already rebasing when current branch and revision are the same, it is less confusing to rebase when they are different too. - Add `--reset` mode that checkout the new branch and hard reset that branch to remote commit. This new mode guarantees that every - subproject are exactly at the wrap's revision. + subproject are exactly at the wrap's revision. In addition the URL of `origin` + is updated in case it changed in the wrap file. - Local changes are always stashed first to avoid any data loss. In the worst case scenario the user can always check reflog and stash list to rollback. diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py index 422dad2d9..195410f4a 100755 --- a/mesonbuild/msubprojects.py +++ b/mesonbuild/msubprojects.py @@ -120,11 +120,33 @@ def update_git(wrap, repo_dir, options): if not os.path.isdir(repo_dir): mlog.log(' -> Not used.') return True - revision = wrap.get('revision') - if not revision: + revision = wrap.values.get('revision') + url = wrap.values.get('url') + push_url = wrap.values.get('push-url') + if not revision or not url: # It could be a detached git submodule for example. - mlog.log(' -> No revision specified.') + mlog.log(' -> No revision or URL specified.') return True + try: + origin_url = git_output(['remote', 'get-url', 'origin'], repo_dir).strip() + except GitException as e: + mlog.log(' -> Failed to determine current origin URL in', mlog.bold(repo_dir)) + mlog.log(mlog.red(e.output)) + mlog.log(mlog.red(str(e))) + return False + if options.reset: + try: + git_output(['remote', 'set-url', 'origin', url], repo_dir) + if push_url: + git_output(['remote', 'set-url', '--push', 'origin', push_url], repo_dir) + except GitException as e: + mlog.log(' -> Failed to reset origin URL in', mlog.bold(repo_dir)) + mlog.log(mlog.red(e.output)) + mlog.log(mlog.red(str(e))) + return False + elif url != origin_url: + mlog.log(' -> URL changed from {!r} to {!r}'.format(origin_url, url)) + return False try: # Same as `git branch --show-current` but compatible with older git version branch = git_output(['rev-parse', '--abbrev-ref', 'HEAD'], repo_dir).strip()