From e70fde62410ad2639e5266346914773fcc564cf5 Mon Sep 17 00:00:00 2001 From: Michael Hanke Date: Wed, 25 Oct 2023 20:29:45 +0200 Subject: [PATCH] Patch update for more robust behavior with adjusted branches Companion of https://github.com/datalad/datalad/pull/7522 --- ...31025_202631_michael.hanke_bf_core_7522.md | 6 ++ datalad_next/patches/enabled.py | 1 + datalad_next/patches/update.py | 58 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 changelog.d/20231025_202631_michael.hanke_bf_core_7522.md create mode 100644 datalad_next/patches/update.py diff --git a/changelog.d/20231025_202631_michael.hanke_bf_core_7522.md b/changelog.d/20231025_202631_michael.hanke_bf_core_7522.md new file mode 100644 index 00000000..f225fce8 --- /dev/null +++ b/changelog.d/20231025_202631_michael.hanke_bf_core_7522.md @@ -0,0 +1,6 @@ +### 🐛 Bug Fixes + +- Add patch to fix `update`'s target detection for adjusted mode datasets + that can crash under some circumstances. + See https://github.com/datalad/datalad/issues/7507, fixed via + https://github.com/datalad/datalad-next/pull/509 (by @mih) diff --git a/datalad_next/patches/enabled.py b/datalad_next/patches/enabled.py index 763961c4..c705c0f6 100644 --- a/datalad_next/patches/enabled.py +++ b/datalad_next/patches/enabled.py @@ -13,4 +13,5 @@ customremotes_main, create_sibling_gitlab, run, + update, ) diff --git a/datalad_next/patches/update.py b/datalad_next/patches/update.py new file mode 100644 index 00000000..d0f7be85 --- /dev/null +++ b/datalad_next/patches/update.py @@ -0,0 +1,58 @@ +"""Robustify ``update()`` target detection for adjusted mode datasets + +The true cause of the problem is not well understood. +https://github.com/datalad/datalad/issues/7507 documents that it is not +easy to capture the breakage in a test. +""" + +from . import apply_patch + + +# This function is taken from datalad-core@cdc0ceb30ae04265c5369186acf2ab2683a8ec96 +# datalad/distribution/update.py +# The change has been proposed in https://github.com/datalad/datalad/pull/7522 +def _choose_update_target(repo, branch, remote, cfg_remote): + """Select a target to update `repo` from. + + Note: This function is not concerned with _how_ the update is done (e.g., + merge, reset, ...). + + Parameters + ---------- + repo : Repo instance + branch : str + The current branch. + remote : str + The remote which updates are coming from. + cfg_remote : str + The configured upstream remote. + + Returns + ------- + str (the target) or None if a choice wasn't made. + """ + target = None + if cfg_remote and remote == cfg_remote: + # Use the configured cfg_remote branch as the target. + # + # In this scenario, it's tempting to use FETCH_HEAD as the target. For + # a merge, that would be the equivalent of 'git pull REMOTE'. But doing + # so would be problematic when the GitRepo.fetch() call was passed + # all_=True. Given we can't use FETCH_HEAD, it's tempting to use the + # branch.*.merge value, but that assumes a value for remote.*.fetch. + target = repo.call_git_oneline( + ["rev-parse", "--symbolic-full-name", "--abbrev-ref=strict", + # THIS IS THE PATCH: prefix @{upstream} with the branch name + # of the corresponding branch + f"{repo.get_corresponding_branch(branch) or ''}" "@{upstream}"], + read_only=True) + elif branch: + remote_branch = "{}/{}".format(remote, branch) + if repo.commit_exists(remote_branch): + target = remote_branch + return target + + +apply_patch( + 'datalad.distribution.update', None, '_choose_update_target', + _choose_update_target)