Back to github
github v1.1.0 8 min read 515 lines

github-repo-management

GitHub 저장소 관리 — 클론, 생성, 포크, 리모트, 시크릿, 릴리즈, 워크플로우

Hermes Agent
MIT

GitHub Repository Management

Create, clone, fork, configure, and manage GitHub repositories. Each section shows gh first, then the git + curl fallback.

Prerequisites

  • Authenticated with GitHub (see github-auth skill)

Setup

if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f $ENV_FILE ] && grep -q "^GITHUB_TOKEN=" $ENV_FILE; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" $ENV_FILE | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]:\([^@]\)@.*|\1|')
fi
fi
fi

Get your GitHub username (needed for several operations)


if [ "$AUTH" = "gh" ]; then
GH_USER=$(gh api user --jq '.login')
else
GH_USER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user | python3 -c "import sys,json; print(json.load(sys.stdin)['login'])")
fi

If you're inside a repo already:

REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)


1. Cloning Repositories

Cloning is pure git — works identically either way:

# Clone via HTTPS (works with credential helper or token-embedded URL)
git clone https://github.com/owner/repo-name.git

Clone into a specific directory


git clone https://github.com/owner/repo-name.git ./my-local-dir

Shallow clone (faster for large repos)


git clone --depth 1 https://github.com/owner/repo-name.git

Clone a specific branch


git clone --branch develop https://github.com/owner/repo-name.git

Clone via SSH (if SSH is configured)


git clone git@github.com:owner/repo-name.git

With gh (shorthand):

gh repo clone owner/repo-name
gh repo clone owner/repo-name -- --depth 1

2. Creating Repositories

With gh:

# Create a public repo and clone it
gh repo create my-new-project --public --clone

Private, with description and license


gh repo create my-new-project --private --description "A useful tool" --license MIT --clone

Under an organization


gh repo create my-org/my-new-project --public --clone

From existing local directory


cd /path/to/existing/project
gh repo create my-project --source . --public --push

With git + curl:

# Create the remote repo via API
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/user/repos \
-d '{
"name": "my-new-project",
"description": "A useful tool",
"private": false,
"auto_init": true,
"license_template": "mit"
}'

Clone it


git clone https://github.com/$GH_USER/my-new-project.git
cd my-new-project

-- OR -- push an existing local directory to the new repo


cd /path/to/existing/project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/$GH_USER/my-new-project.git
git push -u origin main

To create under an organization:

curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/orgs/my-org/repos \
-d '{"name": "my-new-project", "private": false}'

From a Template

With gh:

gh repo create my-new-app --template owner/template-repo --public --clone

With curl:

curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/owner/template-repo/generate \
-d '{"owner": "'"$GH_USER"'", "name": "my-new-app", "private": false}'

3. Forking Repositories

With gh:

gh repo fork owner/repo-name --clone

With git + curl:

# Create the fork via API
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/owner/repo-name/forks

Wait a moment for GitHub to create it, then clone


sleep 3
git clone https://github.com/$GH_USER/repo-name.git
cd repo-name

Add the original repo as "upstream" remote


git remote add upstream https://github.com/owner/repo-name.git

Keeping a Fork in Sync

# Pure git — works everywhere
git fetch upstream
git checkout main
git merge upstream/main
git push origin main

With gh (shortcut):

gh repo sync $GH_USER/repo-name

4. Repository Information

With gh:

gh repo view owner/repo-name
gh repo list --limit 20
gh search repos "machine learning" --language python --sort stars

With curl:

# View repo details
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO \
| python3 -c "
import sys, json
r = json.load(sys.stdin)
print(f\"Name: {r['full_name']}\")
print(f\"Description: {r['description']}\")
print(f\"Stars: {r['stargazers_count']} Forks: {r['forks_count']}\")
print(f\"Default branch: {r['default_branch']}\")
print(f\"Language: {r['language']}\")"

List your repos


curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/user/repos?per_page=20&sort=updated" \
| python3 -c "
import sys, json
for r in json.load(sys.stdin):
vis = 'private' if r['private'] else 'public'
print(f\" {r['full_name']:40} {vis:8} {r.get('language', ''):10} ★{r['stargazers_count']}\")"

Search repos


curl -s \
"https://api.github.com/search/repositories?q=machine+learning+language:python&sort=stars&per_page=10" \
| python3 -c "
import sys, json
for r in json.load(sys.stdin)['items']:
print(f\" {r['full_name']:40} ★{r['stargazers_count']:6} {r['description'][:60] if r['description'] else ''}\")"

5. Repository Settings

With gh:

gh repo edit --description "Updated description" --visibility public
gh repo edit --enable-wiki=false --enable-issues=true
gh repo edit --default-branch main
gh repo edit --add-topic "machine-learning,python"
gh repo edit --enable-auto-merge

With curl:

curl -s -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO \
-d '{
"description": "Updated description",
"has_wiki": false,
"has_issues": true,
"allow_auto_merge": true
}'

Update topics


curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.mercy-preview+json" \
https://api.github.com/repos/$OWNER/$REPO/topics \
-d '{"names": ["machine-learning", "python", "automation"]}'

6. Branch Protection

# View current protection
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection

Set up branch protection


curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/branches/main/protection \
-d '{
"required_status_checks": {
"strict": true,
"contexts": ["ci/test", "ci/lint"]
},
"enforce_admins": false,
"required_pull_request_reviews": {
"required_approving_review_count": 1
},
"restrictions": null
}'

7. Secrets Management (GitHub Actions)

With gh:

gh secret set API_KEY --body "your-secret-value"
gh secret set SSH_KEY < ~/.ssh/id_rsa
gh secret list
gh secret delete API_KEY

With curl:

Secrets require encryption with the repo's public key — more involved via API:

# Get the repo's public key for encrypting secrets
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/public-key

Encrypt and set (requires Python with PyNaCl)


python3 -c "
from base64 import b64encode
from nacl import encoding, public
import json, sys

Get the public key


key_id = ''
public_key = ''

Encrypt


sealed = public.SealedBox(
public.PublicKey(public_key.encode('utf-8'), encoding.Base64Encoder)
).encrypt('your-secret-value'.encode('utf-8'))
print(json.dumps({
'encrypted_value': b64encode(sealed).decode('utf-8'),
'key_id': key_id
}))"

Then PUT the encrypted secret


curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/secrets/API_KEY \
-d ''

List secrets (names only, values hidden)


curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/secrets \
| python3 -c "
import sys, json
for s in json.load(sys.stdin)['secrets']:
print(f\" {s['name']:30} updated: {s['updated_at']}\")"

Note: For secrets, gh secret set is dramatically simpler. If setting secrets is needed and gh isn't available, recommend installing it for just that operation.

8. Releases

With gh:

gh release create v1.0.0 --title "v1.0.0" --generate-notes
gh release create v2.0.0-rc1 --draft --prerelease --generate-notes
gh release create v1.0.0 ./dist/binary --title "v1.0.0" --notes "Release notes"
gh release list
gh release download v1.0.0 --dir ./downloads

With curl:

# Create a release
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/releases \
-d '{
"tag_name": "v1.0.0",
"name": "v1.0.0",
"body": "## Changelog\n- Feature A\n- Bug fix B",
"draft": false,
"prerelease": false,
"generate_release_notes": true
}'

List releases


curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/releases \
| python3 -c "
import sys, json
for r in json.load(sys.stdin):
tag = r.get('tag_name', 'no tag')
print(f\" {tag:15} {r['name']:30} {'draft' if r['draft'] else 'published'}\")"

Upload a release asset (binary file)


RELEASE_ID=
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/$OWNER/$REPO/releases/$RELEASE_ID/assets?name=binary-amd64" \
--data-binary @./dist/binary-amd64

9. GitHub Actions Workflows

With gh:

gh workflow list
gh run list --limit 10
gh run view
gh run view --log-failed
gh run rerun
gh run rerun --failed
gh workflow run ci.yml --ref main
gh workflow run deploy.yml -f environment=staging

With curl:

# List workflows
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/workflows \
| python3 -c "
import sys, json
for w in json.load(sys.stdin)['workflows']:
print(f\" {w['id']:10} {w['name']:30} {w['state']}\")"

List recent runs


curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10" \
| python3 -c "
import sys, json
for r in json.load(sys.stdin)['workflow_runs']:
print(f\" Run {r['id']} {r['name']:30} {r['conclusion'] or r['status']}\")"

Download failed run logs


RUN_ID=
curl -s -L \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \
-o /tmp/ci-logs.zip
cd /tmp && unzip -o ci-logs.zip -d ci-logs

Re-run a failed workflow


curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun

Re-run only failed jobs


curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/rerun-failed-jobs

Trigger a workflow manually (workflow_dispatch)


WORKFLOW_ID=
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/workflows/$WORKFLOW_ID/dispatches \
-d '{"ref": "main", "inputs": {"environment": "staging"}}'

10. Gists

With gh:

gh gist create script.py --public --desc "Useful script"
gh gist list

With curl:

# Create a gist
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/gists \
-d '{
"description": "Useful script",
"public": true,
"files": {
"script.py": {"content": "print(\"hello\")"}
}
}'

List your gists


curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/gists \
| python3 -c "
import sys, json
for g in json.load(sys.stdin):
files = ', '.join(g['files'].keys())
print(f\" {g['id']} {g['description'] or '(no desc)':40} {files}\")"

Quick Reference Table

| Action | gh | git + curl |
|--------|-----|-----------|
| Clone | gh repo clone o/r | git clone https://github.com/o/r.git |
| Create repo | gh repo create name --public | curl POST /user/repos |
| Fork | gh repo fork o/r --clone | curl POST /repos/o/r/forks + git clone |
| Repo info | gh repo view o/r | curl GET /repos/o/r |
| Edit settings | gh repo edit --... | curl PATCH /repos/o/r |
| Create release | gh release create v1.0 | curl POST /repos/o/r/releases |
| List workflows | gh workflow list | curl GET /repos/o/r/actions/workflows |
| Rerun CI | gh run rerun ID | curl POST /repos/o/r/actions/runs/ID/rerun |
| Set secret | gh secret set KEY | curl PUT /repos/o/r/actions/secrets/KEY (+ encryption) |

Related Skills / 관련 스킬

github v1.0.0

codebase-inspection

pygount으로 코드베이스 검사 — LOC 카운트, 언어별 분석, 코드/주석 비율

github v1.0.0

github-actions

GitHub Actions CI/CD 파이프라인 생성, 관리, 디버깅 — 워크플로우 작성부터 비밀관리, 자동 배포, 실패 트러블슈팅까지

github v1.1.0

github-auth

git 또는 gh CLI로 GitHub 인증 설정 — HTTPS 토큰, SSH 키, 크레덴셜 헬퍼

github v1.1.0

github-code-review

git diff 분석으로 코드 변경 리뷰 — PR 인라인 코멘트, 사전 푸시 리뷰