Linux-based practice of batch uploading local Git repositories to Github
1. Demand
Each folder in the app directory is a git repository. How to use a shell script to upload all git repositories to github?
server@dev-fj-srv:~/code/app$ tree -L 1
.
|-- FreemeBadgeProvider
|-- FreemeCalculator
|-- FreemeCamera
|-- FreemeCamera2
2. Upload the local Git repository
2.1 Initial version
To use a shell script to upload all Git repositories in the app directory to GitHub, you can follow the steps below:
-
First, make sure you create an empty remote repository on GitHub to store your application repository.
-
Create a new shell script file (for example
upload_to_github.sh
) and open it with a text editor. -
In the script file, add the following content:
#!/bin/bash
# 进入 app 目录
cd ~/code/app
# 遍历 app 目录下的每个文件夹
for repo in */; do
# 进入每个 Git 仓库目录
cd "$repo"
# 添加远程仓库地址
git remote add origin <GitHub 仓库的 URL>
# 推送代码到远程仓库
git push -u origin master
# 返回到 app 目录
cd ..
done
-
Replace
<GitHub 仓库的 URL>
with the URL address of the remote repository you created on GitHub. Make sure each warehouse has the correct remote warehouse address. -
Save and close the script file.
-
In the terminal, go to the directory containing the script file and add execute permissions to the script file. The following commands can be used:
chmod +x upload_to_github.sh
- To run the script file, use the following command:
./upload_to_github.sh
The script will automatically enter each warehouse directory and push it to the corresponding remote warehouse. You will need to provide your GitHub account username and password or access token during the first push to each repository to ensure permission verification.
2.2 Optimized version
If you want to use permalinks and folder names in the script to build the URL of the GitHub repository, you can make the following modifications to the script:
#!/bin/bash
# 进入 app 目录
cd ~/code/app
# 遍历 app 目录下的每个文件夹
for repo in */; do
# 进入每个 Git 仓库目录
cd "$repo"
# 获取文件夹名
folder_name=$(basename "$PWD")
# 构建远程仓库地址
repo_url="https://github.com/<你的用户名>/${folder_name}.git"
# 添加远程仓库地址
git remote add origin "$repo_url"
# 推送代码到远程仓库
git push -u origin master
# 返回到 app 目录
cd ..
done
In the above script, you need to <你的用户名>
replace with your username on GitHub.
In this way, the script will build the corresponding GitHub warehouse URL based on the name of each folder and add it to each warehouse as a remote warehouse address.
Note that this approach assumes that each folder's name exactly matches the corresponding GitHub repository name. If the folder name and repository name do not match, you may need to make further modifications to the script to suit your situation.
I hope this modification can meet your needs! If you need further assistance, please feel free to ask.
3. Create an empty warehouse on GitHub
3.1 Initial version
You can use a shell script to create an empty remote repository on GitHub through the GitHub API. The following is an example script using the cURL command:
#!/bin/bash
# 你的 GitHub 用户名和访问令牌
USERNAME="<你的用户名>"
ACCESS_TOKEN="<你的访问令牌>"
# 仓库名称
REPO_NAME="my-repo"
# 构建 API URL
API_URL="https://api.github.com/user/repos"
# 创建仓库的 JSON 数据
JSON_DATA="{
\"name\":\"$REPO_NAME\",\"private\":false}"
# 发送 POST 请求创建仓库
curl -u "$USERNAME:$ACCESS_TOKEN" -d "$JSON_DATA" "$API_URL"
In the above script, you need to <你的用户名>
replace with your GitHub username and <你的访问令牌>
replace with your GitHub access token.
The GitHub API used in the script is that /user/repos
it allows you to create a new repository belonging to the current user. name
The parameter specifies the warehouse name, and private
setting the parameter to false
means creating a public warehouse.
After running the script, it will create an empty remote repository by sending a POST request using the provided username and access token.
Please make sure you have the cURL tool installed before running the script, and replace the appropriate parameters in the script.
3.2 Optimized version
Based on response
server@dev-fj-srv:~/Desktop$ ./create_repo.sh
{
"id": 735911698,
"node_id": "R_kgDOK90fEg",
"name": "FreemeNotes",
"full_name": "fangjian98/FreemeNotes",
"private": false,
"owner": {
"login": "fangjian98",
"id": 59403187,
"node_id": "MDQ6VXNlcjU5NDAzMTg3",
"avatar_url": "https://avatars.githubusercontent.com/u/59403187?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/fangjian98",
"html_url": "https://github.com/fangjian98",
"followers_url": "https://api.github.com/users/fangjian98/followers",
"following_url": "https://api.github.com/users/fangjian98/following{/other_user}",
"gists_url": "https://api.github.com/users/fangjian98/gists{/gist_id}",
"starred_url": "https://api.github.com/users/fangjian98/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/fangjian98/subscriptions",
"organizations_url": "https://api.github.com/users/fangjian98/orgs",
"repos_url": "https://api.github.com/users/fangjian98/repos",
"events_url": "https://api.github.com/users/fangjian98/events{/privacy}",
"received_events_url": "https://api.github.com/users/fangjian98/received_events",
"type": "User",
"site_admin": false
},
"html_url": "https://github.com/fangjian98/FreemeNotes",
"description": null,
"fork": false,
"url": "https://api.github.com/repos/fangjian98/FreemeNotes",
"forks_url": "https://api.github.com/repos/fangjian98/FreemeNotes/forks",
"keys_url": "https://api.github.com/repos/fangjian98/FreemeNotes/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/fangjian98/FreemeNotes/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/fangjian98/FreemeNotes/teams",
"hooks_url": "https://api.github.com/repos/fangjian98/FreemeNotes/hooks",
"issue_events_url": "https://api.github.com/repos/fangjian98/FreemeNotes/issues/events{/number}",
"events_url": "https://api.github.com/repos/fangjian98/FreemeNotes/events",
"assignees_url": "https://api.github.com/repos/fangjian98/FreemeNotes/assignees{/user}",
"branches_url": "https://api.github.com/repos/fangjian98/FreemeNotes/branches{/branch}",
"tags_url": "https://api.github.com/repos/fangjian98/FreemeNotes/tags",
"blobs_url": "https://api.github.com/repos/fangjian98/FreemeNotes/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/fangjian98/FreemeNotes/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/fangjian98/FreemeNotes/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/fangjian98/FreemeNotes/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/fangjian98/FreemeNotes/statuses/{sha}",
"languages_url": "https://api.github.com/repos/fangjian98/FreemeNotes/languages",
"stargazers_url": "https://api.github.com/repos/fangjian98/FreemeNotes/stargazers",
"contributors_url": "https://api.github.com/repos/fangjian98/FreemeNotes/contributors",
"subscribers_url": "https://api.github.com/repos/fangjian98/FreemeNotes/subscribers",
"subscription_url": "https://api.github.com/repos/fangjian98/FreemeNotes/subscription",
"commits_url": "https://api.github.com/repos/fangjian98/FreemeNotes/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/fangjian98/FreemeNotes/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/fangjian98/FreemeNotes/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/fangjian98/FreemeNotes/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/fangjian98/FreemeNotes/contents/{+path}",
"compare_url": "https://api.github.com/repos/fangjian98/FreemeNotes/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/fangjian98/FreemeNotes/merges",
"archive_url": "https://api.github.com/repos/fangjian98/FreemeNotes/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/fangjian98/FreemeNotes/downloads",
"issues_url": "https://api.github.com/repos/fangjian98/FreemeNotes/issues{/number}",
"pulls_url": "https://api.github.com/repos/fangjian98/FreemeNotes/pulls{/number}",
"milestones_url": "https://api.github.com/repos/fangjian98/FreemeNotes/milestones{/number}",
"notifications_url": "https://api.github.com/repos/fangjian98/FreemeNotes/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/fangjian98/FreemeNotes/labels{/name}",
"releases_url": "https://api.github.com/repos/fangjian98/FreemeNotes/releases{/id}",
"deployments_url": "https://api.github.com/repos/fangjian98/FreemeNotes/deployments",
"created_at": "2023-12-26T12:41:16Z",
"updated_at": "2023-12-26T12:41:16Z",
"pushed_at": "2023-12-26T12:41:16Z",
"git_url": "git://github.com/fangjian98/FreemeNotes.git",
"ssh_url": "[email protected]:fangjian98/FreemeNotes.git",
"clone_url": "https://github.com/fangjian98/FreemeNotes.git",
"svn_url": "https://github.com/fangjian98/FreemeNotes",
"homepage": null,
"size": 0,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 0,
"license": null,
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [
],
"visibility": "public",
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "main",
"permissions": {
"admin": true,
"maintain": true,
"push": true,
"triage": true,
"pull": true
},
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE",
"network_count": 0,
"subscribers_count": 0
}
In order to optimize the code to output the repository URL and a success or failure message, you can use command substitution to capture the output of the curl command and process it accordingly based on the return status. Here is a modified example script:
#!/bin/bash
# 你的 GitHub 用户名和访问令牌
USERNAME="<你的用户名>"
ACCESS_TOKEN="<你的访问令牌>"
# 仓库名称
REPO_NAME="my-repo"
# 构建 API URL
API_URL="https://api.github.com/user/repos"
# 创建仓库的 JSON 数据
JSON_DATA="{
\"name\":\"$REPO_NAME\",\"private\":false}"
# 发送 POST 请求创建仓库并捕获输出
response=$(curl -s -u "$USERNAME:$ACCESS_TOKEN" -d "$JSON_DATA" "$API_URL")
# 检查返回状态并输出相应信息
if [[ $? -eq 0 ]]; then
repo_url=$(echo "$response" | grep -o '"html_url": "[^"]*' | grep -o '[^"]*$')
echo "仓库创建成功!"
echo "仓库 URL:$repo_url"
else
echo "仓库创建失败!"
fi
In the above script, -s
parameters are used with the curl command to send the request in silent mode and hide the progress information. $?
Is the return status of the previous command, we use it to check whether the curl command was executed successfully. grep
Command is used to extract the repository URL from curl output.
If the curl command is executed successfully, the script will extract the warehouse URL and output a success message, otherwise it will output a failure message.
Please make sure you have the cURL tool installed before running the script, and replace the appropriate parameters in the script.
4. Gitee creates an empty warehouse
You can use a shell script to create an empty remote repository on Gitee through the Gitee API. The following is an example script using the cURL command:
#!/bin/bash
# 你的 Gitee 用户名和访问令牌
USERNAME="<你的用户名>"
ACCESS_TOKEN="<你的访问令牌>"
# 仓库名称
REPO_NAME="my-repo"
# 构建 API URL
API_URL="https://gitee.com/api/v5/user/repos"
# 创建仓库的 JSON 数据
JSON_DATA="{
\"name\":\"$REPO_NAME\",\"private\":false}"
# 发送 POST 请求创建仓库
curl -X POST -H "Content-Type: application/json" -H "Authorization: token $ACCESS_TOKEN" -d "$JSON_DATA" "$API_URL"
In the above script, you need to <你的用户名>
replace with your Gitee username and <你的访问令牌>
with your Gitee access token.
The Gitee API used in the script is that /api/v5/user/repos
it allows you to create a new repository as the current user. name
The parameter specifies the warehouse name, and private
setting the parameter to false
means creating a public warehouse.
After running the script, it will create an empty remote repository by sending a POST request using the provided username and access token.
Please make sure you have the cURL tool installed before running the script, and replace the appropriate parameters in the script.