From: Han Jiang Date: Wed, 04 Sep 2024 23:52:31 GMT Subject: Re: `git fetch --refmap=… … ` providing NON-empty to the --refmap ALSO causes Git to ignore the configured refspecs Message-ID: In-Reply-To: > But then in section "Configured Remote-tracking Branches" it is said that The problem with the doc is "how to override". From https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt---refmapltrefspecgt it seems we need to `git fetch --refmap='' --refmap=` to really override configuration variables. I guess the inner working is like this: first for-loop traverses configuration variable `remote..fetch` collecting s into a list, then second for-loop traverses `--refmap=`s, clears the list when an empty string is encountered, appends to the list when a non-empty string is encountered. Maybe I'm just daydreaming... > git fetch --refmap="" foo bar baz I think the correct use case of empty string, is to specify more --refmap=s after it (like in https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushpushOption ), otherwise the mapping (to operate upon foo,bar and baz) would be empty. Sorry that I didn't use examples to express my intended use scenarios clearly! After I searched "empty value" or "empty string" in https://git-scm.com/docs/git-config yesterday, the most intuitive behavior of `git fetch --refmap` (for me) was: `git fetch ...` uses `remote..fetch`; `git fetch --refmap= --refmap= ...` uses `remote..fetch` and all the `--refmap=`s; `git fetch --refmap='' --refmap= --refmap= ...` uses all the `--refmap=`s; Here is an example of all of these being used at the same time. 1. Normally, user uses `fetch-safe` which uses `git fetch --refmap=` to use whatever mappings specified by `remote..fetch` and also let our backup logic sneak in. 2. Occasionally, upstream is rebased and our backup logic (refspec without `+`) blocks the process because of `--atomic`. 2.1. When that happens, user uses `fetch-bak-current-time` which uses `git fetch --refmap='' --refmap=` to clear whatever mappings specified by `remote..fetch` and use our another backup logic (refspec with `+`). 2.2. After old tips are saved, user uses `git fetch --force` to use whatever mappings specified by `remote..fetch`; Currently [1.] is not working because --refmap= clears `remote..fetch` instead of merging with it. Hence this bug report. cd '/'; cd '/'; rm --force --recursive -- './test_git2'; mkdir "$_"; cd "$_"; mkdir --parents -- './server' './client'; git -C './server' init --bare './repo.git' git --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty -m "$((++number))" git --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty -m "$((++number))" git -C './server/repo.git' branch branch1; git -C './server/repo.git' branch branch2 git -C './client' init './repo' git -C './client/repo' config set --local 'alias.fetch-safe' '!git_fetch_safe(){ server="$1"; shift; git fetch --atomic --refmap='\''refs/*:refs/namespaces/'\''"$server"'\''_backup/refs/*'\'' "$server" "$@"; };git_fetch_safe' git -C './client/repo' config set --local 'alias.fetch-bak-current-time' '!git_fetch_bak_current_time(){ server="$1"; shift; git -c '\''remote.'\''"$server"'\''_backup.url=.'\'' --namespace="$server"'\''_backup'\'' fetch --refmap='\''refs/*:refs/namespaces/'\''"$server"'\''_backup_'\''"$(date +'%Y%m%d%H%M%S')"'\''/refs/*'\'' "$server"'_backup' "$@"; git fetch --atomic --refmap='\'\'' --refmap='\''+refs/*:refs/namespaces/'\''"$server"'\''_backup/refs/*'\'' "$server" "$@"; };git_fetch_bak_current_time' git -C './client/repo' remote add server 'file://'"$(realpath './server/repo.git')" git -C './client/repo' remote --verbose git -C './client/repo' config list --local --show-scope --show-origin git -C './client/repo' fetch-safe server branch1 branch2 git -C './client/repo' show-ref git -C './client/repo' lg --all --decorate-refs='*' git --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty -m "$((++number))" git -C './server/repo.git' branch --force branch1; git -C './server/repo.git' branch --force branch2 git -C './client/repo' fetch-safe server branch1 branch2 git -C './client/repo' show-ref git -C './client/repo' lg --all --decorate-refs='*' git --git-dir='./server/repo.git' --work-tree='.' commit --allow-empty -m "$((++number))" --amend git -C './server/repo.git' branch --force branch1; git -C './server/repo.git' branch --force branch2 git -C './client/repo' fetch-safe server branch1 branch2 git -C './client/repo' show-ref git -C './client/repo' lg --all --decorate-refs='*' git -C './client/repo' fetch-bak-current-time server branch1 branch2 git -C './client/repo' show-ref git -C './client/repo' lg --all --decorate-refs='*' git -C './client/repo' fetch --force server branch1 branch2 git -C './client/repo' show-ref git -C './client/repo' lg --all --decorate-refs='*' On Thu, Sep 5, 2024 at 4:47 AM Junio C Hamano wrote: > > Johannes Sixt writes: > > > Am 04.09.24 um 13:12 schrieb Han Jiang: > >> 1. If the doc says "providing an empty to the --refmap > >> option causes Git to ignore the configured refspecs and rely entirely > >> on the refspecs supplied as command-line arguments" then it's > >> reasonable to guess that "providing a non-empty will not do > >> those". > > > > Fair enough. But then in section "Configured Remote-tracking Branches" > > it is said that "The latter use of the remote..fetch values > > can be overridden by giving the --refmap= parameter(s) on the > > command line." So... I dunno. Just my 2c. > > This cuts both ways, I suspect. It is so unusual to say > > git fetch --refmap="" foo bar baz > > to use an empty string as in "--refmap=", simply > because you would not say > > git fetch origin "" > > and expect the empty string is a in "git fetch origin ". > > Any string other than an empty string, e.g. > > git fetch --refmap="refs/heads/*:refs/prefetch/x/*" foo bar baz > > would have an extra side effect of storing what gets fetched, when > your primary focus is "I want the command to ignore the configured > refspec". > > For these reasons, I would actually say it is quite fair for the > documentation to single out the empty string case as an idiom that > may be hard for readers to figure out for themselves without being > told. > > I would not be opposed to add a sentence or two to clarify what > happens when a non-empty is used, though. > > Thanks. >