-
-
Save Angelk90/d3b2623b5bb1f4bf5aff7f19e7e1db43 to your computer and use it in GitHub Desktop.
what are GitHub 'refs/pull/*' refspecs and how to get full copy of GitHub repo [git] [github]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# we are going to fetch all refs (including 'refs/pull/*') from Git remote | |
# 'repo-to-fetch', which points to public GitHub repo defined by URL | |
# '${repoURL}' where the GitHub user account '${userName}' has write access | |
# for more details on GitHub 'refs/pull/*' refspecs see [1] | |
userName=mxxxxxx | |
[email protected] | |
repoURL=https://github.com/txxxx-xx/gxx-xxxx.git | |
# create, init, and configure git repo | |
mkdir bare-repo | |
cd bare-repo | |
git init --bare | |
git config user.email ${userEmail} | |
git config user.name ${userName} | |
git config credential.username ${userName} | |
# set up 'repo-to-fetch' remote, you NEED TO CREATE new GitHub repo | |
# preliminarily | |
git remote add --mirror=fetch repo-to-fetch ${repoURL} | |
# see default set of 'refspec' for the created remote (for 'git fetch' | |
# command) | |
git config --get-all remote.repo-to-fetch.fetch # output: '+refs/*:refs/*' | |
# see existing branches and tags before fetch | |
git branch -avv | wc -l # output: 0 | |
git tag -l | wc -l # output: 0 | |
find refs -type f | wc -l # output: 0 | |
tree refs # output: | |
#> refs | |
#> ├── heads | |
#> └── tags | |
#> | |
#> 2 directories, 0 files | |
# fetch updates from 'repo-to-fetch' remote | |
git remote update 2>&1 | grep "^ \*" > log | |
# examine log | |
cat log | wc -l # output: ' 20' | |
cat log | grep "new branch" | wc -l # output: ' 3' | |
cat log | grep "new ref" | wc -l # output: ' 11' | |
cat log | grep "new tag" | wc -l # output: ' 6' | |
# see existing branches and tags after fetch (with help of git command) | |
git branch -avv | wc -l # output: ' 3' | |
git tag -l | wc -l # output: ' 6' | |
# see stored refs | |
find refs -type f | wc -l # output: ' 20' | |
find refs/heads -type f | wc -l # output: ' 3' | |
find refs/pull -type f | wc -l # output: ' 11' | |
find refs/tags -type f | wc -l # output: ' 6' | |
# see all remote refs | |
git ls-remote repo-to-fetch | wc -l # output: ' 24' | |
git ls-remote repo-to-fetch | grep HEAD | wc -l # output: ' 1' | |
git ls-remote repo-to-fetch | grep "refs/heads" | wc -l # output: ' 3' | |
git ls-remote repo-to-fetch | grep "refs/pull" | wc -l # output: ' 11' | |
git ls-remote repo-to-fetch | grep "refs/pull/[0-9]\+/head" | wc -l # output: ' 10' | |
git ls-remote repo-to-fetch | grep "refs/pull/[0-9]\+/merge" | wc -l # output: ' 1' | |
git ls-remote repo-to-fetch | grep "refs/tags" | wc -l # output: ' 9' | |
git ls-remote repo-to-fetch | grep "refs/tags" | grep -v "\^{}$" | wc -l # output: ' 6' | |
# let's see how 'refs/pull/*' refspecs look like; let's assume we have | |
# open pull request which have number ${prOpen} | |
# change N to the number of existing open pull request | |
prOpen=N | |
# the GitHub 'refs/pull/*/head' refspecs correspond to all created (open | |
# and closed) pull requests; new 'refs/pull/<N>/head' is created every | |
# time new pull request <N> is created (e.g. via GitHub webUI, 'gh', 'hub') | |
find refs/pull -type f | grep "refs/pull/[0-9]\+/head" | wc -l # output: ' 10' | |
# see how 'refs/pull/<N>/head' refspecs look like | |
cat refs/pull/${prOpen}/head # output: 'ce46a4519061e27250e1284523d8b3275f07248b' | |
git show $(cat refs/pull/${prOpen}/head) # output: | |
#> commit ce46a4519061e27250e1284523d8b3275f07248b (refs/pull/N/head, user/featureN) | |
#> Author: user <[email protected]> | |
#> Date: Mon Apr 6 16:04:48 2020 +0300 | |
#> | |
#> featureN | |
#> | |
#> diff --git a/featureN b/featureN | |
#> new file mode 100644 | |
#> index 0000000..e69de29 | |
# the GitHub 'refs/pull/*/merge' refspecs correspond to open pull requests | |
# only; new 'refs/pull/<N>/merge' is created every time new pull request | |
# <N> is created (e.g. via GitHub webUI, 'gh', 'hub'); the | |
# 'refs/pull/<N>/merge' is deleted every time pull request <N> is | |
# merged (e.g. via GitHub webUI, 'gh', 'hub') | |
find refs/pull -type f | grep "refs/pull/[0-9]\+/merge" | wc -l # output: ' 1' | |
# see how 'refs/pull/<N>/merge' refspecs look like | |
cat refs/pull/${prOpen}/merge # output: '4ab972401e31c379d012e0c76bef97df8ec8e886' | |
git show $(cat refs/pull/${prOpen}/merge) # output: | |
#> commit 4ab972401e31c379d012e0c76bef97df8ec8e886 (refs/pull/N/merge) | |
#> Merge: 6937f49 ce46a45 | |
#> Author: user <[email protected]> | |
#> Date: Mon Apr 6 13:05:50 2020 +0000 | |
#> | |
#> Merge ce46a4519061e27250e1284523d8b3275f07248b into 6937f49a3f85b94c1caaa46245a0b9e02ffc23ff | |
#> | |
# let's see how 'refs/pull/*' are created/deleted as pull requests are | |
# created/merged (e.g. via GitHub webUI, 'gh', 'hub'); let's assume the | |
# next created pull request will have the number ${prNext} | |
# change M to the number of the next pull request (the number of | |
# the last one plus one) | |
prNext=M | |
# look at the pull request locally and remotely | |
find refs/pull -type f -path "refs/pull/${prNext}/*" # no output | |
git ls-remote repo-to-fetch | grep "refs/pull/${prNext}" # no output | |
# create and checkout to new branch 'user/featureM' | |
git branch user/feature${prNext} | |
mkdir ../work-tree | |
git --work-tree=../work-tree checkout user/feature${prNext} | |
# make, stage, and commit changes | |
touch ../work-tree/feature${prNext} | |
git --work-tree=../work-tree add feature${prNext} | |
git --work-tree=../work-tree commit -m "feature${prNext}" | |
# push the created branch to remote | |
git --work-tree=../work-tree push repo-to-fetch user/feature${prNext} | |
echo "here you NEED TO CREATE new branch pull request (e.g. via GitHub webUI)" | |
echo "the script will continue in 60 seconds" | |
sleep 60 | |
# the GitHub Action refspecs (github.ref) for the created pull request | |
# is 'refs/pull/M/merge' | |
# look at the pull request locally and remotely | |
find refs/pull -type f -path "refs/pull/${prNext}/*" # no output | |
git ls-remote repo-to-fetch | grep "refs/pull/${prNext}" # output: | |
#> 71940958cc9ebf3904119ae16c549cc23cbe6652 refs/pull/M/head | |
#> 3c68ecbc55105bd7f9ecf67fb1692880fd7ae4a5 refs/pull/M/merge | |
# fetch and look at changes locally | |
git fetch repo-to-fetch | |
find refs/pull -type f -path "refs/pull/${prNext}/*" # output: | |
#> refs/pull/M/merge | |
#> refs/pull/M/head | |
find refs/pull -type f -path "refs/pull/${prNext}/*" | xargs cat # output: | |
#> 3c68ecbc55105bd7f9ecf67fb1692880fd7ae4a5 | |
#> 71940958cc9ebf3904119ae16c549cc23cbe6652 | |
echo "here you NEED TO MERGE the pull request (e.g. via GitHub webUI)" | |
echo "the script will continue in 60 seconds" | |
sleep 60 | |
# the GitHub Action refspecs (github.ref) for the merge is 'refs/heads/master' | |
# look at the pull request locally and remotely | |
find refs/pull -type f -path "refs/pull/${prNext}/*" # output: | |
#> refs/pull/M/merge | |
#> refs/pull/M/head | |
git ls-remote repo-to-fetch | grep "refs/pull/${prNext}" # output: | |
#> 71940958cc9ebf3904119ae16c549cc23cbe6652 refs/pull/M/head | |
# fetch and look at changes locally | |
git fetch repo-to-fetch | |
find refs/pull -type f -path "refs/pull/${prNext}/*" # output: | |
#> refs/pull/M/merge | |
#> refs/pull/M/head | |
# remove any remote-tracking references (that no longer exist on the remote), | |
# fetch and look at changes locally | |
git fetch repo-to-fetch -p | |
find refs/pull -type f -path "refs/pull/${prNext}/*" # output: | |
#> refs/pull/M/head | |
# PS: clean up local and remote repos | |
# remote feature branch is deleted after pull request merge | |
# see remote feature branch before it is deleted | |
git ls-remote repo-to-fetch | grep "feature${prNext}" # output: | |
#> 71940958cc9ebf3904119ae16c549cc23cbe6652 refs/heads/user/featureM | |
echo "here you NEED TO DELETE feature branch remotely (e.g. via GitHub webUI)" | |
echo "the script will continue in 60 seconds" | |
sleep 60 | |
# no more remote feature branch after it is deleted | |
git ls-remote repo-to-fetch | grep "feature${prNext}" # no output | |
# local feature branch is also can be deleted after pull request merge | |
# see local feature branch before it is deleted | |
git br -a | grep "feature${prNext}" # output: '* user/featureM' | |
# delete feature branch locally | |
git br -d user/feature${prNext} | |
# no local feature branch after it is deleted | |
git br -a | grep "feature${prNext}" # no output | |
# [1] https://gist.github.com/piscisaureus/3342247 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment