Re: `git fetch --refmap=<refspec>… <repository> <refspec>… ` providing NON-empty <refspec> to the --refmap ALSO causes Git to ignore the configured refspecs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> 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=<refspec>` to
really override configuration variables.
I guess the inner working is like this: first for-loop traverses
configuration variable `remote.<remote>.fetch` collecting <refspec>s
into a list, then second for-loop traverses `--refmap=<refspec>`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=<refspec>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 <remote> <branch>...` uses `remote.<remote>.fetch`;
`git fetch --refmap=<refspec> --refmap=<refspec> <remote> <branch>...`
uses `remote.<remote>.fetch` and all the `--refmap=<refspec>`s;
`git fetch --refmap='' --refmap=<refspec> --refmap=<refspec> <remote>
<branch>...` uses all the `--refmap=<refspec>`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=<refspec>` to use whatever mappings specified by
`remote.<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=<refspec>` to clear whatever mappings
specified by `remote.<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.<remote>.fetch`;

Currently [1.] is not working because --refmap=<not empty string!>
clears `remote.<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 <gitster@xxxxxxxxx> wrote:
>
> Johannes Sixt <j6t@xxxxxxxx> writes:
>
> > Am 04.09.24 um 13:12 schrieb Han Jiang:
> >> 1. If the doc says "providing an empty <refspec> 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 <refspec> will not do
> >> those".
> >
> > Fair enough. But then in section "Configured Remote-tracking Branches"
> > it is said that "The latter use of the remote.<repository>.fetch values
> > can be overridden by giving the --refmap=<refspec> 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 <refspec> in "--refmap=<refspec>", simply
> because you would not say
>
>     git fetch origin ""
>
> and expect the empty string is a <refspec> in "git fetch origin <refspec>".
>
> 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 <refspec> is used, though.
>
> Thanks.
>





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux