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

基于 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 工具,并且替换脚本中的相应参数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux文件系统结构及相关命令1(man pwd ls ctrl +Shift +T ls /etc)

Linux的文件系统结构 某所大学的学生可能在一两万人左右&#xff0c;通常将学生分配在以学院-系班为单位的分层组织机构中。 如何查找一名学生&#xff1f; 最笨的办法&#xff1a;依次问询大学中的每一个学生&#xff0c;直到找到为止。 查询效率高的方法&#xff1a;按照从…

Eureka服务注册与发现

1. Eureka简介 Eureka采用了CS的设计架构&#xff0c;Eureka Server 作为服务注册功能的服务器&#xff0c;它是服务注册中心。而系统中的其他微服务&#xff0c;使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系…

微服务(1)

目录 1.什么是微服务&#xff1f;谈谈你对微服务的理解&#xff1f; 2.什么是Spring Cloud&#xff1f; 3.Springcloud中的组件有哪些&#xff1f; 3.具体说说SpringCloud主要项目&#xff1f; 5.SpringCloud项目部署架构&#xff1f; 1.什么是微服务&#xff1f;谈谈你对微…

idea配置docker推送本地镜像到远程私有仓库

目录 1&#xff0c;搭建远程Docker 私有仓库 Docker registry 2&#xff0c;Windows10/11系统上安装Docker Desktop 3&#xff0c;idea 配置远程私有仓库地址 4&#xff0c;idea 配置Docker 5&#xff0c;idea在本地构建镜像 6&#xff0c;推送本地Docker镜像到远程 Dock…

DotNet 命令行开发

DotNet 命令行开发 下载安装下载 SDK安装 SDK绿色版下载绿化脚本 常用命令创建 dotnet new运行 dotnet run发布应用 dotnet publish更多命令 VSCode 调试所需插件调试 CS 配置项目.csproj排除依赖关系 launch.jsontasks.json 参考资料 下载安装 下载 SDK 我们就下最新的好&am…

事实验证文章分类 Papers Category For Fact Checking

事实验证文章分类 Papers Category For Fact Checking By 2023.11 个人根据自己的观点&#xff0c;花了很多时间整理的一些关于事实验证领域证据召回&#xff0c;验证推理过程的文献综合整理分类&#xff08;不是很严谨&#xff09;。 引用请注明出处 欢迎从事事实验证Fact…

【开源】基于Vue+SpringBoot的就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

基于ElementUI二次封装弹窗组件

效果&#xff1a; 一、自定义内容类型弹窗 <!-- title&#xff1a;对话框的标题confirmLoading&#xff1a;当前是否处于提交中titleCenter&#xff1a;对话框标题居中方式footerCenter&#xff1a;底部按钮的对其方式visible&#xff1a;是否显示弹窗width&#xff1a;设置…

重定向和转发的区别

重定向 1、定义 用户通过浏览器发送一个请求&#xff0c;Tomcat服务器接收这个请求&#xff0c;会给浏览器发送一个状态码302&#xff0c;并设置一个重定向的路径&#xff0c;浏览器如果接收到了这个302的状态码以后&#xff0c;就会去自动加载服务器设置的路径 一个页面跳转…

【测试开发与AIchat】它的思维跟大多数人还是一样的,都解决不了实际问题,可能是它也没有积累类似的经验[chatGPT]

分享一个人工智能{AI}解决问题的工具GPT(点我赶紧注册)&#xff0c;它是有GPT-4模型的。 它可以做很多事情&#xff0c;譬如问&#xff1a;开发平台功能 但是它仍然没有解决题主的问题。 源码如下&#xff1a; #....with smtplib.SMTP() as smtp:smtp.connect(smtp_server…

【两两交换链表中的节点】

Problem: 24. 两两交换链表中的节点 文章目录 思路解题方法Code 思路 把第一步的模拟过程的步骤记录下来 一共分为三个步骤 解题方法 创建虚拟头节点 循环什么时候结束&#xff0c;需要考虑问题 Q&#xff1a; 奇数链表结束条件&#xff1f;偶数链表结束条件&#xff1f;为什么…

一语道破爬虫,来揭开爬虫面纱

目录 一、爬虫&#xff08;网络蜘蛛(Spider)&#xff09; 1.1、是什么&#xff1a; 1.2、学习的原因 1.3、用在地方&#xff1a; 1.4、是否合法&#xff1a; 1.5、后果 案例&#xff1a; 二、应用领域 三、Robots协议 四、抓包 4.1、浏览器抓包 4.2、抓包工具 常见…

【数据结构复习之路】查找(严蔚敏版)万字详解

专栏&#xff1a;数据结构复习之路 复习完上面四章【线性表】【栈和队列】【串】【数组和广义表】【树和二叉树】【图】&#xff0c;我们接着复习 查找&#xff0c;这篇文章我写的非常详细且通俗易懂&#xff0c;看完保证会带给你不一样的收获。如果对你有帮助&#xff0c;看在…

深入学习Python与Vscode环境的安装与配置

上进小菜猪&#xff0c;沈工大软件工程专业&#xff0c;爱好敲代码&#xff0c;持续输出干货。 随着Python的广泛应用&#xff0c;使用一款高效的集成开发环境&#xff08;IDE&#xff09;变得尤为重要。而在众多IDE中&#xff0c;Visual Studio Code&#xff08;简称Vscode&a…

几种取时间的方法(附代码)

1.上古版 最原始的取时间的方法大概就是timelocaltime了&#xff0c;见代码&#xff1a; #include <stdio.h>#include <time.h>// gcc -o time_1 time_1.cint main(){time_t tm_now;time(&tm_now);// 或者写成 tm_now time(NULL);//1.直接打印&#xff1a;197…

【C++】开源:libev事件循环库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍libev事件循环库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c…

代码回滚(git reset)后push失败的解决方法

问题描述 代码本地回滚之后&#xff08;即 git reset 到之前的某个历史节点&#xff09;&#xff0c;push上去失败&#xff0c;并报出以下错误信息 ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to gitgithub.com:PisecesPeng/useg…

Strateg策略模式(组件协作)

策略模式&#xff08;组件协作&#xff09; 链接&#xff1a;策略模式实例代码 注解 目的 正常情况下&#xff0c;一个类/对象中会包含其所有可能会使用的内外方法&#xff0c;但是一般情况下&#xff0c;这些常使用的类都是由不同的父类继承、组合得来的&#xff0c;来实现…

精品Nodejs实现的校园疫情防控管理系统的设计与实现健康打卡

《[含文档PPT源码等]精品Nodejs实现的校园疫情防控管理系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Win…

【nodejs】Express概念与使用介绍

Express Express是基于Node.js平台&#xff0c;从内置模块http封装出来的第三方模块&#xff0c;可以更方便的开发Web服务器。 中文官网&#xff1a; http://www.expressjs.com.cn/ 一、基本使用 // 导入express const express require(express) // 创建web服务器 const a…