基于 Linux 的批量上传本地 Git 仓库到 Github 的实践

news2025/1/22 12:50:42

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践

  • 一、需求
  • 二、上传本地 Git 仓库
    • 2.1 初始版本
    • 2.2 优化版本
  • 三、 GitHub 创建空仓库
    • 3.1 初始版本
    • 3.2 优化版本
  • 四、Gitee 创建空仓库

一、需求

app目录下的每个文件夹都是一个git仓库,如何使用shell脚本将所有git仓库都上传到github上

server@dev-fj-srv:~/code/app$ tree -L 1
.
|-- FreemeBadgeProvider
|-- FreemeCalculator
|-- FreemeCamera
|-- FreemeCamera2 

在这里插入图片描述

二、上传本地 Git 仓库

2.1 初始版本

要使用 shell 脚本将 app 目录下的所有 Git 仓库上传到 GitHub 上,可以按照以下步骤进行操作:

  1. 首先,确保你在 GitHub 上创建了一个空的远程仓库,用于存储你的应用程序仓库。

  2. 创建一个新的 shell 脚本文件(例如 upload_to_github.sh),并使用文本编辑器打开它。

  3. 在脚本文件中,添加以下内容:

#!/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
  1. 替换 <GitHub 仓库的 URL> 为你在 GitHub 上创建的远程仓库的 URL 地址。确保每个仓库都有正确的远程仓库地址。

  2. 保存并关闭脚本文件。

  3. 在终端中,进入包含脚本文件的目录,并为脚本文件添加执行权限。可以使用以下命令:

chmod +x upload_to_github.sh
  1. 运行脚本文件,使用以下命令:
./upload_to_github.sh

脚本将自动进入每个仓库目录,并将其推送到对应的远程仓库。你需要在每个仓库的首次推送时提供 GitHub 账户的用户名和密码或访问令牌,以确保权限验证。

2.2 优化版本

如果你希望在脚本中使用固定链接和文件夹名来构建 GitHub 仓库的 URL,你可以对脚本进行以下修改:

#!/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

在上述脚本中,你需要将 <你的用户名> 替换为你在 GitHub 上的用户名。

这样,脚本将会根据每个文件夹的名称构建对应的 GitHub 仓库 URL,并将其作为远程仓库地址添加到各个仓库中。

请注意,这种方法假设每个文件夹的名称与对应的 GitHub 仓库名称完全匹配。如果文件夹名称和仓库名称不一致,你可能需要对脚本进行进一步修改以适应你的情况。

希望这次修改能满足你的需求!如果你需要进一步帮助,请随时提问。

三、 GitHub 创建空仓库

3.1 初始版本

你可以使用 shell 脚本通过 GitHub API 在 GitHub 上创建一个空的远程仓库。以下是一个使用 cURL 命令的示例脚本:

#!/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"

在上述脚本中,你需要将 <你的用户名> 替换为你的 GitHub 用户名,并将 <你的访问令牌> 替换为你的 GitHub 访问令牌。

脚本中使用的 GitHub API 是 /user/repos,它允许你创建一个属于当前用户的新仓库。name 参数指定了仓库名称,private 参数设置为 false 表示创建一个公开仓库。

运行脚本后,它将使用提供的用户名和访问令牌发送一个 POST 请求来创建一个空的远程仓库。

请确保在运行脚本之前安装了 cURL 工具,并且替换脚本中的相应参数。

3.2 优化版本

基于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": "git@github.com: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
}

为了优化代码以输出仓库 URL 和成功或失败的提示信息,你可以使用命令替换(command substitution)来捕获 curl 命令的输出,并根据返回状态进行相应的处理。下面是经过修改的示例脚本:

#!/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

在上述脚本中,-s 参数用于 curl 命令,以静默模式发送请求并隐藏进度信息。$? 是上一个命令的返回状态,我们使用它来检查 curl 命令是否成功执行。grep 命令用于从 curl 输出中提取仓库 URL。

如果 curl 命令成功执行,脚本将提取仓库 URL 并输出成功的提示信息,否则将输出失败的提示信息。

请确保在运行脚本之前安装了 cURL 工具,并且替换脚本中的相应参数。

四、Gitee 创建空仓库

你可以使用 shell 脚本通过 Gitee API 在 Gitee 上创建一个空的远程仓库。以下是一个使用 cURL 命令的示例脚本:

#!/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"

在上述脚本中,你需要将 <你的用户名> 替换为你的 Gitee 用户名,并将 <你的访问令牌> 替换为你的 Gitee 访问令牌。

脚本中使用的 Gitee API 是 /api/v5/user/repos,它允许你以当前用户的身份创建一个新的仓库。name 参数指定了仓库名称,private 参数设置为 false 表示创建一个公开仓库。

运行脚本后,它将使用提供的用户名和访问令牌发送一个 POST 请求来创建一个空的远程仓库。

请确保在运行脚本之前安装了 cURL 工具,并且替换脚本中的相应参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1344307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python/R/GUI/BI类型常用数据可视化工具

什么是数据可视化工具&#xff1f; 数据可视化工具是指旨在可视化数据的所有形式的软件。它们处理数据输入&#xff0c;将其转换为用户可以根据自己的需求进行定制的视觉效果。 不同的工具可以包含不同的功能&#xff0c;但最基本的是&#xff0c;数据可视化工具提供输入数据集…

交叉编译含义

交叉编译是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统&#xff1b;同样&#xff0c;同一个操作系统也可以在不同的体系结构上运行。 编译工具链下载&#xff1a; (1) ARM提供&#xff1a;Arm GNU Toolchain Downloads – Arm Develope…

GroundingDINO-根据文本提示检测任意目标

1. 背景介绍 GroundingDINO是一种新的SOTA零样本物体检测模型。在这篇文章中&#xff0c;我们将讨论Grounding DINO模型的优势&#xff0c;分析其具体的模型架构&#xff0c;并提供真实的测试样例。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2.零样本目标检测 大多…

Python实现员工管理系统(Django页面版 ) 七

各位小伙伴们好久不见&#xff0c;2024年即将到来&#xff0c;小编在这里提前祝大家新的一年快快乐乐&#xff0c;能够事业有成&#xff0c;学习顺心&#xff0c;家庭和睦&#xff0c;事事顺利。 今天我们本篇要实现的是一个登录界面的实现&#xff0c;其实登录界面的实现看着挺…

php学习06-魔术常量

有九个魔术常量它们的值随着它们在代码中的位置改变而改变。例如 LINE 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写&#xff0c;如下&#xff1a; 参考

SpringBoot知识

1、Spring和SpringBoot对比 2、版本调整 &#xff08;1&#xff09;先排除是否是JDK与SpringBoot的版本不一致导致的&#xff1a;如JDK1.8和SpringBoot3.1.5冲突&#xff1b; &#xff08;2&#xff09;调整编译版本 &#xff08;3&#xff09;调整maven的jdk &#xff08;4&…

AI又进化了,AI 写代码工具

今年 AI 的发展可谓一日千里&#xff0c;相信不少同学应该都用过 AI 来帮助自己提高开发效率吧&#xff1f; 比如让 AI 根据注释生成代码、解释整段代码、提供技术问题的答疑、修改 Bug、生成单元测试等等。 在 12 月 28 日刚刚结束的 WAVE SUMMIT 深度学习开发者大会上&…

引领手游技术潮流:武汉灰京文化的卓越技术创新与市场推广支持

在数字娱乐领域&#xff0c;手游行业正蓬勃发展&#xff0c;为数以亿计的玩家提供了丰富的娱乐选择。武汉灰京文化&#xff0c;作为该领域的佼佼者&#xff0c;以其强大的技术创新和全面的市场推广支持&#xff0c;为合作伙伴的成功铺平了道路&#xff0c;不仅提升了游戏质量&a…

Amlogic HDMI驱动分析

目录 一、简介 二、代码结构介绍 三、HDMI资料 四、宏观认识一下HDMI 1、硬件连接 2、Amlogic方案中HDMI的位置 3、Amlogic HDMI驱动模块的划分 五、HDMI-RX驱动分析 1、芯片手册解读 2、RX -makefile 3、驱动模型分析 4、RX的运行 5、HDMI RX调试 六、HDMI-TX驱…

单列集合Collection常用api

集合体系结构 Collection Collection是单列集合的祖宗接口&#xff0c;它的功能是全部单列集合都可以继承使用的。 public static void main(String[] args) {//TODO Collection类 所有集合的接口 /*public boolean add(E e) 添加public void clear() …

Ubuntu20.04 上启用 VCAN 用作本地调试

目录 一、启用本机的 VCAN​ 编辑 1.1 加载本机的 vcan 1.2 添加本机的 vcan0 1.3 查看添加的 vcan0 1.4 开启本机的 vcan0 1.5 关闭本机的 vcan0 1.6 删除本机的 vcan0 二、测试本机的 VCAN 2.1 CAN 发送数据 代码 2.2 CAN 接收数据 代码 2.3 CMakeLists.…

图像质量评估:使用 SSIM 计算图像相似性

在图像处理领域&#xff0c;衡量两幅图像之间相似性的一种常见方法是使用结构相似性指数&#xff08;SSIM&#xff09;。SSIM 是一种全参考的图像质量评估指标&#xff0c;它不仅考虑了图像的亮度、对比度&#xff0c;还考虑了结构信息。在本文中&#xff0c;我们将介绍一个使用…

Qt QAction添加图片

QAction用的时候&#xff0c;时常需要添加图片&#xff0c;如上图所示&#xff0c;代码如下所示&#xff1a; 测试的图片格式包含png,jpg,bmp,svg&#xff0c;其他未测试

OpenCV-Python(9):图像基础操作

目录 学习目标 获取图像像素并修改像素值 获取图像属性 图像ROI 拆分及合并图像通道 图像边缘扩充 学习目标 获取像素值并修改获取图像的属性(信息)图像的ROI获取图像通道拆分及合并图像扩边 获取图像像素并修改像素值 几乎所有这些操作与Numpy 的关系要比与OpenCV 的…

大语言模型(LLM)框架及微调 (Fine Tuning)

大语言模型&#xff08;LLM&#xff09; 技术作为人工智能领域的一项重要创 新在今年引起了广泛的关注。 LLM 是利用深度学习和大数据训练的人工智能系统&#xff0c;专门 设计来理解、生成和回应自然语言。这些模型通过分析大量 的文本数据来学习语言的结构和用法&#xff0c;…

跟着LearnOpenGL学习11--材质

文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里&#xff0c;每个物体会对光产生不同的反应。 比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反…

器件的静态特性

器件的静态特性 静态特性&#xff08;伏安特性&#xff09; 1.器件在导通或关断的状态下&#xff0c;其电压与电流对应关系。 2.静态过程体现器件最基本的电压与电流稳态特性。 动态特性&#xff08;开关特性&#xff09; 1.器件在开或关过程中&#xff0c;其电压、电流随时…

关于java循环结构for

关于java循环结构for 在上一篇文章中&#xff0c;我们了解到了while和do…while的结构以及用法&#xff0c;这篇文章我们主要学习一下最常用的循环结构&#xff0c;for结构&#x1f600;&#xff0c;这个结构理解起来相对while结构会难一些&#xff0c;本篇文章内容会很多&…

深入Mybatis数据源

数据源是持久层框架中最核心的组件之一&#xff0c;在实际工作中比较常见的数据源有 C3P0、Apache Common DBCP、Proxool 等。作为一款成熟的持久化框架&#xff0c;MyBatis 不仅自己提供了一套数据源实现&#xff0c;而且还能够方便地集成第三方数据源。 javax.sql.DataSourc…

Linux之缓冲区的理解

目录 一、问题引入 二、缓冲区 1、什么是缓冲区 2、刷新策略 3、缓冲区由谁提供 4、重看问题 三、缓冲区的简单实现 一、问题引入 我们先来看看下面的代码&#xff1a;我们使用了C语言接口和系统调用接口来进行文件操作。在代码的最后&#xff0c;我们还使用fork函数创建…