admin管理员组文章数量:1312658
Scenario 1
Suppose I have the following stanza in .git/config
:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
With this configuration:
- Running
git fetch origin
will fetch all branches. - Running
git fetch origin my_branch
will fetch origin's copy ofmy_branch
and update the tracking branch atrefs/remotes/origin/my_branch
.
Scenario 2
Now suppose I have the following stanza instead, which names two explicit branches that are not my_branch
.
[remote "origin"]
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/all-green:refs/remotes/origin/all-green
With this configuration:
- Running
git fetch origin
will only fetchmaster
andall-green
. - Running
git fetch origin my_branch
will fetch the branch, but not update any tracking branch. If I want to update the tracking branch, I must explicitly saygit fetch origin my_branch:refs/remotes/origin/my_branch
.
Question
Is it possible to configure git
in such a way that the following two statements are true?
git fetch origin my_branch
will update local tracking branches according to the refspec in Scenario 1 for all possible values of my_branch.git fetch origin
fetches only those branches that have previously been explicitly fetched (e.g. they already have a remote-tracking branch) rather than all branches that match the refspec.
In other words, I would like to use the refspec
to determine the branch mapping automatically when I give a remote branch name to fetch, but not to determine the set of branches that is fetched when I merely say git fetch origin
without a branch name.
My current approach is to just edit the git config (manually or using a script) for every remote branch I want to track, but I ask this question to see if there's a more direct way to get the behavior I want.
Scenario 1
Suppose I have the following stanza in .git/config
:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
With this configuration:
- Running
git fetch origin
will fetch all branches. - Running
git fetch origin my_branch
will fetch origin's copy ofmy_branch
and update the tracking branch atrefs/remotes/origin/my_branch
.
Scenario 2
Now suppose I have the following stanza instead, which names two explicit branches that are not my_branch
.
[remote "origin"]
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/all-green:refs/remotes/origin/all-green
With this configuration:
- Running
git fetch origin
will only fetchmaster
andall-green
. - Running
git fetch origin my_branch
will fetch the branch, but not update any tracking branch. If I want to update the tracking branch, I must explicitly saygit fetch origin my_branch:refs/remotes/origin/my_branch
.
Question
Is it possible to configure git
in such a way that the following two statements are true?
git fetch origin my_branch
will update local tracking branches according to the refspec in Scenario 1 for all possible values of my_branch.git fetch origin
fetches only those branches that have previously been explicitly fetched (e.g. they already have a remote-tracking branch) rather than all branches that match the refspec.
In other words, I would like to use the refspec
to determine the branch mapping automatically when I give a remote branch name to fetch, but not to determine the set of branches that is fetched when I merely say git fetch origin
without a branch name.
My current approach is to just edit the git config (manually or using a script) for every remote branch I want to track, but I ask this question to see if there's a more direct way to get the behavior I want.
Share Improve this question asked Feb 1 at 5:01 merlin2011merlin2011 75.6k47 gold badges212 silver badges356 bronze badges 5 |2 Answers
Reset to default 1edit: this works fine but OP found the --refmap
option I'd never noticed, that makes a much better answer, this is still useful as context/samplecode so:
It's very easy to write a ~update the factory-default tracking branches even for branches I'm not usually tracking~ convenience, the payload is just
awk '$2=="branch" { print "git update-ref refs/remotes/origin/"$3,$1 }' \
$(git rev-parse --git-dir)/FETCH_HEAD | sh -x
and you can invoke that however you want. It might be your best option, because I think this in the fetch refspec docs
Unlike when pushing with git-push[1], there is no configuration which’ll amend these rules, and nothing like a
pre-fetch
hook analogous to thepre-receive
hook.
means "no." Which does make sense, fetching is often scripted for custom workflows already, some of them so common support has been provided in a factory-supplied convenience: git pull does any of several really common fetch-plus-custom-followup sequences.
For another option, you could also customize an alternate remote,
git config remote.onebranch.url $(git config remote.origin.url)
git config remote.onebranch.fetch +refs/heads/*:refs/remotes/origin/*
after which git fetch onebranch my_branch
will update the origin tracking branch if needed.
Given that the answer is "No", I am posting additional workarounds:
Workaround 1: Add an alias for the specific remote.
git config --global alias.fetchbranch "fetch --refmap=+refs/heads/*:refs/remotes/origin/*"
Workaround 1a: Add an alias for any remote
Add the following manually to the ~/.gitconfig
:
[alias]
ffetch = "!f() { git fetch --refmap=\"+refs/heads/*:refs/remotes/${1}/*\" \"$@\"; }; f"
Note that both of the above workarounds, as well as the accepted answer, do not cause git fetch origin
to correctly fetch the tracked branch.
Workaround 2: Script for adding to git config
The only method that actually causes git fetch
without specifying a branch to automatically pick up updates appears to be adding the refspec into the git config:
git-track
remote_branch_name="$1"
remote="origin"
if [[ $# -gt 1 ]]; then
remote="$2"
fi
refspec="refs/heads/${remote_branch_name}:refs/remotes/origin/${remote_branch_name}"
# Check if this config already exists.
if git config --get "remote.${remote}.fetch" "$refspec"; then
>&2 echo "Branch ${remote_branch_name} from ${remote} is already tracked."
exit 0
fi
# Check if the remote has the branch.
if ! git fetch "$remote" "refs/heads/${remote_branch_name}" 2>/dev/null; then
>&2 echo "Branch ${remote_branch_name} does not exist on ${remote}."
exit 1
fi
# Actually add the refspec
git config --add "remote.${remote}.fetch" "+${refspec}"
# Do the initial fetch as a convenience.
git fetch "${remote}" "${remote_branch_name}"
I paired this with a second script to untrack:
git-untrack
remote_branch_name="$1"
remote="origin"
if [[ $# -gt 1 ]]; then
remote="$2"
fi
refspec="refs/heads/${remote_branch_name}:refs/remotes/origin/${remote_branch_name}"
# For no-op case.
if ! git config --get "remote.${remote}.fetch" "$refspec"; then
>&2 echo "Branch ${remote_branch_name} from ${remote} is already untracked."
exit 0
fi
git config --unset-all remote.origin.fetch "\+${refspec}"
本文标签:
版权声明:本文标题:Is it possible to `git fetch` only specific branches without specifying a full refspec on each invocation? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741886858a2403072.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
my_branch
with the stringTimRoberts/branch1
or the stringmerlin2011/branch2
, it should still work. – merlin2011 Commented Feb 1 at 5:10git myfetch origin branchfoo
to: a. just updateorigin/branchfoo
ref ? b. updateorigin/branchfoo
and also create a local tracking branch ? or c. addbranchfoo
in the list of default branches in the.git/config
file for that remote ? – LeGEC Commented Feb 1 at 9:03! ...
,...
can be any shell command, 2. if you create an executable script namedgit-foo
, make it executable and somehow accessible from the PATH, then you can typegit foo ...
as if it were an alias or a new subcommand – LeGEC Commented Feb 1 at 9:05git branch
, but ifc
just means the branch gets updated by default when I dogit fetch origin
, then I also meanc
. – merlin2011 Commented Feb 1 at 9:12