gitlab bash_如何编写Bash一线式以克隆和管理GitHub和GitLab存储库

gitlab bash

Few things are more satisfying to me than one elegant line of Bash that automates hours of tedious work.

没有什么比让Bash自动完成数小时繁琐工作的Bash优雅系列令我满意的了。

As part of some recent explorations into automatically re-creating my laptop with Bash scripts (post to come!), I wanted to find a way to easily clone my GitHub-hosted repositories to a new machine. After a bit of digging around, I wrote a one-liner that did just that.

作为最近使用Bash脚本自动重新创建笔记本电脑的探索的一部分,我想找到一种轻松地将GitHub托管的存储库克隆到新计算机上的方法。 经过一番摸索之后,我写了一篇这样的单线纸。

Then, in the spirit of not putting all our eggs in the same basket, I wrote another one-liner to automatically create and push to GitLab-hosted backups as well. Here they are.

然后,本着不把所有鸡蛋都放在同一篮子的精神,我写了另一种单行代码来自动创建并推送到GitLab托管的备份。 他们来了。

一个Bash一线式克隆您所有的GitHub存储库 (A Bash one-liner to clone all your GitHub repositories)

Caveat: you’ll need a list of the GitHub repositories you want to clone. The good thing about that is it gives you full agency to choose just the repositories you want on your machine, instead of going in whole-hog.

注意:您将需要要克隆的GitHub存储库的列表。 这样做的好处是,它使您可以完全选择仅要在计算机上存储的存储库,而不必花很多精力。

You can easily clone GitHub repositories without entering your password each time by using HTTPS with your 15-minute cached credentials or, my preferred method, by connecting to GitHub with SSH. For brevity I’ll assume we’re going with the latter, and our SSH keys are set up.

您可以轻松地克隆GitHub存储库,而无需每次都输入HTTPS并使用15分钟的缓存凭据,或者,我首选的方法是使用SSH连接到GitHub,而无需每次输入密码。 为简便起见,我假设我们要使用后者,并且我们已经设置了SSH密钥。

Given a list of GitHub URLs in the file gh-repos.txt, like this:

在文件gh-repos.txt中给出GitHub URL的列表,如下所示:

git@github.com:username/first-repository.git
git@github.com:username/second-repository.git
git@github.com:username/third-repository.git

We run:

我们跑:

xargs -n1 git clone < gh-repos.txt

This clones all the repositories on the list into the current folder. This same one-liner works for GitLab as well, if you substitute the appropriate URLs.

这会将列表上的所有存储库克隆到当前文件夹中。 如果替换适当的URL,则同一行也适用于GitLab。

这里发生了什么? (What’s going on here?)

There are two halves to this one-liner: the input, counterintuitively on the right side, and the part that makes stuff happen, on the left. We could make the order of these parts more intuitive (maybe?) by writing the same command like this:

单行代码有两半:输入(在直觉上相反)在右侧,而使事情发生的部分在左侧。 通过编写如下相同的命令,我们可以使这些部分的顺序更直观(也许?):

<gh-repos.txt xargs -n1 git clone

To run a command for each line of our input, gh-repos.txt, we use xargs -n1. The tool xargs reads items from input and executes any commands it finds (it will echo if it doesn’t find any). By default, it assumes that items are separated by spaces; new lines also works and makes our list easier to read. The flag -n1tells xargs to use 1 argument, or in our case, one line, per command. We build our command with git clone, which xargs then executes for each line. Ta-da.

要对输入的每一行gh-repos.txt运行命令,我们使用xargs -n1xargs工具从输入中读取项目并执行找到的所有命令(如果找不到则echo )。 默认情况下,它假定项目之间用空格隔开; 新行也可以使我们的列表更易于阅读。 标志-n1告诉xargs每个命令使用1参数,在本例中为1行。 我们使用git clone构建命令,然后xargs将针对每一行执行。 -

Bash一线式工具,可在GitLab上创建并推送许多存储库 (A Bash one-liner to create and push many repositories on GitLab)

GitLab, unlike GitHub, lets us do this nifty thing where we don’t have to use the website to make a new repository first. We can create a new GitLab repository from our terminal. The newly created repository defaults to being set as Private, so if we want to make it Public on GitLab, we’ll have to do that manually later.

与GitHub不同,GitLab让我们可以做这件漂亮的事情,而不必先使用网站创建新的存储库。 我们可以从终端创建一个新的GitLab存储库 。 新创建的存储库默认设置为“私有”,因此,如果要在GitLab上将其设置为“公共”,则稍后必须手动进行。

The GitLab docs tell us to push to create a new project using git push --set-upstream, but I don’t find this to be very convenient for using GitLab as a backup. As I work with my repositories in the future, I’d like to run one command that pushes to both GitHub and GitLab without additional effort on my part.

GitLab文档告诉我们使用git push --set-upstream来推动创建一个新项目,但是我发现使用GitLab作为备份不是很方便。 将来在使用存储库时,我想运行一个命令同时推送到GitHub GitLab,而无需我付出额外的努力。

To make this Bash one-liner work, we’ll also need a list of repository URLs for GitLab (ones that don’t exist yet). We can easily do this by copying our GitHub repository list, opening it up with Vim, and doing a search-and-replace:

为了使此Bash单线工作,我们还需要GitLab的存储库URL列表(尚不存在的URL)。 我们可以轻松地做到这一点,方法是复制我们的GitHub存储库列表,使用Vim打开它,然后进行搜索和替换 :

cp gh-repos.txt gl-repos.txt
vim gl-repos.txt
:%s/\<github\>/gitlab/g
:wq

This produces gl-repos.txt, which looks like:

这将产生gl-repos.txt ,看起来像:

git@gitlab.com:username/first-repository.git
git@gitlab.com:username/second-repository.git
git@gitlab.com:username/third-repository.git

We can create these repositories on GitLab, add the URLs as remotes, and push our code to the new repositories by running:

我们可以在GitLab上创建这些存储库,将URL添加为远程存储,并通过运行以下命令将代码推送到新的存储库:

awk -F'\/|(\.git)' '{system("cd ~/FULL/PATH/" $2 " && git remote set-url origin --add " $0 " && git push")}' gl-repos.txt

Hang tight and I’ll explain it; for now, take note that ~/FULL/PATH/ should be the full path to the directory containing our GitHub repositories.

请稍等,我会解释。 现在,请注意~/FULL/PATH/应该是包含我们的GitHub存储库的目录的完整路径。

We do have to make note of a couple assumptions:

我们必须注意以下两个假设:

  1. The name of the directory on your local machine that contains the repository is the same as the name of the repository in the URL (this will be the case if it was cloned with the one-liner above);

    包含资源库的本地计算机上目录的名称与URL中资源库的名称相同(如果是使用上述单行代码克隆的,则为这种情况);
  2. Each repository is currently checked out to the branch you want pushed, ie. master.

    当前每个存储库都签出到要推送的分支,即。 master

The one-liner could be expanded to handle these assumptions, but it is the humble opinion of the author that at that point, we really ought to be writing a Bash script.

单行代码可以扩展以处理这些假设,但是作者的拙见认为,在那时,我们确实应该编写Bash脚本。

这里发生了什么? (What’s going on here?)

Our Bash one-liner uses each line (or URL) in the gl-repos.txt file as input. With awk, it splits off the name of the directory containing the repository on our local machine, and uses these pieces of information to build our larger command. If we were to print the output of awk, we’d see:

我们的Bash单行使用gl-repos.txt文件中的每一行(或URL)作为输入。 使用awk ,它拆分出包含本地计算机上存储库的目录名称,并使用这些信息来构建更大的命令。 如果要print awk的输出, awk看到:

cd ~/FULL/PATH/first-repository && git remote set-url origin --add git@gitlab.com:username/first-repository.git && git push
cd ~/FULL/PATH/second-repository && git remote set-url origin --add git@gitlab.com:username/second-repository.git && git push
cd ~/FULL/PATH/third-repository && git remote set-url origin --add git@gitlab.com:username/third-repository.git && git push

Let’s look at how we build this command.

让我们看看我们如何构建此命令。

awk分割字符串 (Splitting strings with awk)

The tool awk can split input based on field separators. The default separator is a whitespace character, but we can change this by passing the -F flag. Besides single characters, we can also use a regular expression field separator. Since our repository URLs have a set format, we can grab the repository names by asking for the substring between the slash character / and the end of the URL, .git.

工具awk可以基于字段分隔符拆分输入。 默认的分隔符是空格字符,但是我们可以通过传递-F标志来更改它。 除了单个字符,我们还可以使用正则表达式字段分隔符 。 由于我们的存储库URL具有固定的格式,因此我们可以通过请求斜杠/和URL末尾.git之间的子字符串来获取存储库名称。

One way to accomplish this is with our regex \/|(\.git):

实现此目的的一种方法是使用我们的正则表达式\/|(\.git)

  • \/ is an escaped / character;

    \/是转义的/字符;

  • | means “or”, telling awk to match either expression;

    | 表示“或”,告诉awk匹配任一表达式;

  • (\.git) is the capture group at the end of our URL that matches “.git”, with an escaped . character. This is a bit of a cheat, as “.git” isn’t strictly splitting anything (there’s nothing on the other side) but it’s an easy way for us to take this bit off.

    (\.git)是URL末尾的捕获组,与“ .git”匹配,并带有一个转义的. 字符。 这有点作弊,因为“ .git”并没有严格分割任何内容(另一面没有任何内容),但这是我们轻松实现这一点的简便方法。

Once we’ve told awk where to split, we can grab the right substring with the field operator. We refer to our fields with a $ character, then by the field’s column number. In our example, we want the second field, $2. Here’s what all the substrings look like:

告诉awk拆分位置后,我们可以使用field运算符来获取正确的子字符串。 我们用$字符引用字段,然后用字段的列号引用。 在我们的示例中,我们需要第二个字段$2 。 这是所有子字符串的样子:

1: git@gitlab.com:username
2: first-repository

To use the whole string, or in our case, the whole URL, we use the field operator $0. To write the command, we just substitute the field operators for the repository name and URL. Running this with print as we’re building it can help to make sure we’ve got all the spaces right.

要使用整个字符串,或者在我们的示例中,使用整个URL,我们使用字段运算符$0 。 要编写命令,我们只需将字段运算符替换为存储库名称和URL。 在构建它时使用print运行它可以帮助确保所有空间都正确。

awk -F'\/|(\.git)' '{print "cd ~/FULL/PATH/" $2 " && git remote set-url origin --add " $0 " && git push"}' gl-repos.txt

运行命令 (Running the command)

We build our command inside the parenthesis of system(). By using this as the output of awk, each command will run as soon as it is built and output. The system() function creates a child process that executes our command, then returns once the command is completed. In plain English, this lets us perform the Git commands on each repository, one-by-one, without breaking from our main process in which awk is doing things with our input file. Here’s our final command again, all put together.

我们在system()括号内构建命令。 通过将其用作awk的输出,每条命令在生成并输出后将立即运行。 system()函数创建一个执行我们的命令的子进程 ,然后在命令完成后返回。 用简单的英语来说,这使我们可以在每个存储库上一对一地执行Git命令,而不会破坏awk使用输入文件执行操作的主要过程。 这是我们的最终命令,所有命令都放在一起了。

awk -F'\/|(\.git)' '{system("cd ~/FULL/PATH/" $2 " && git remote set-url origin --add " $0 " && git push")}' gl-repos.txt

使用我们的备份 (Using our backups)

By adding the GitLab URLs as remotes, we’ve simplified the process of pushing to both externally hosted repositories. If we run git remote -v in one of our repository directories, we’ll see:

通过将GitLab URL添加为远程站点,我们简化了推送到两个外部托管存储库的过程。 如果在其中一个存储库目录中运行git remote -v ,我们将看到:

origin  git@github.com:username/first-repository.git (fetch)
origin  git@github.com:username/first-repository.git (push)
origin  git@gitlab.com:username/first-repository.git (push)

Now, simply running git push without arguments will push the current branch to both remote repositories.

现在,简单地运行不带参数的git push会将当前分支推送到两个远程存储库。

We should also note that git pull will generally only try to pull from the remote repository you originally cloned from (the URL marked (fetch) in our example above). Pulling from multiple Git repositories at the same time is possible, but complicated, and beyond the scope of this post. Here’s an explanation of pushing and pulling to multiple remotes to help get you started, if you’re curious. The Git documentation on remotes may also be helpful.

我们还应该注意, git pull通常只会尝试从最初克隆的远程存储库中(fetch)在上面的示例中标记为(fetch)的URL)。 可以同时从多个Git存储库中拉出,但很复杂,超出了本文的范围。 如果您有好奇心,这是推和拉到多个遥控器以帮助您入门的说明。 遥控器上的Git文档也可能会有所帮助。

详细阐述Bash单线的简洁性 (To elaborate on the succinctness of Bash one-liners)

Bash one-liners, when understood, can be fun and handy shortcuts. At the very least, being aware of tools like xargs and awk can help to automate and alleviate a lot of tediousness in our work. However, there are some downsides.

如果了解Bash一线,可以说是有趣而便捷的捷径。 至少,了解xargsawk类的工具可以帮助自动化和减轻我们工作中的繁琐工作。 但是,还有一些缺点。

In terms of an easy-to-understand, maintainable, and approachable tool, Bash one-liners suck. They’re usually more complicated to write than a Bash script using if or while loops, and certainly more complicated to read. It’s likely that when we write them, we’ll miss a single quote or closing parenthesis somewhere; and as I hope this post demonstrates, they can take quite a bit of explaining, too. So why use them?

就易于理解,易于维护和易于使用的工具而言,Bash一线难熬。 与使用ifwhile循环的Bash脚本相比,编写它们通常更复杂,并且读取起来当然更复杂。 当我们编写它们时,可能会在某处遗漏单引号或右括号。 正如我希望这篇文章所演示的那样,他们也可以做很多解释。 那为什么要使用它们呢?

Imagine reading a recipe for baking a cake, step by step. You understand the methods and ingredients, and gather your supplies. Then, as you think about it, you begin to realize that if you just throw all the ingredients at the oven in precisely the right order, a cake will instantly materialize. You try it, and it works!

想象一下,逐步阅读烘焙蛋糕的食谱。 您了解方法和成分,并收集物品。 然后,当您考虑它时,您开始意识到,如果只是以正确的顺序将所有配料扔进烤箱,蛋糕就会立即变质。 您尝试一下,就可以了!

That would be pretty satisfying, wouldn’t it?

那会很令人满意,不是吗?

翻译自: https://www.freecodecamp.org/news/bash-one-liners-for-github-and-gitlab/

gitlab bash

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

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

相关文章

寒假学习笔记(4)

2018.2.11 类中的常成员 关键字const&#xff0c;在类定义中声明数据成员使用关键字限定&#xff0c;声明时不能初始化。初始化列表&#xff0c;类中的任何函数都不能对常数据成员赋值&#xff0c;包括构造函数。为构造函数添加初始化列表是对常数据成员进行初始化的唯一途径。…

svm和k-最近邻_使用K最近邻的电影推荐和评级预测

svm和k-最近邻Recommendation systems are becoming increasingly important in today’s hectic world. People are always in the lookout for products/services that are best suited for them. Therefore, the recommendation systems are important as they help them ma…

Oracle:时间字段模糊查询

需要查询某一天的数据&#xff0c;但是库里面存的是下图date类型 将Oracle中时间字段转化成字符串&#xff0c;然后进行字符串模糊查询 select * from CAINIAO_MONITOR_MSG t WHERE to_char(t.CREATE_TIME,yyyy-MM-dd) like 2019-09-12 转载于:https://www.cnblogs.com/gcgc/p/…

cogs2109 [NOIP2015] 运输计划

cogs2109 [NOIP2015] 运输计划 二分答案树上差分。 STO链剖巨佬们我不会&#xff08;太虚伪了吧 首先二分一个答案&#xff0c;下界为0,上界为max{路径长度}。 然后判断一个答案是否可行&#xff0c;这里用到树上差分。 &#xff08;阔以理解为前缀和&#xff1f;&#xff1f;&…

leetcode 690. 员工的重要性(dfs)

给定一个保存员工信息的数据结构&#xff0c;它包含了员工 唯一的 id &#xff0c;重要度 和 直系下属的 id 。 比如&#xff0c;员工 1 是员工 2 的领导&#xff0c;员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] &#x…

组件分页_如何创建分页组件

组件分页The theme for week #17 of the Weekly Coding Challenge is:每周编码挑战第17周的主题是&#xff1a; 分页 (Pagination) A Pagination Component is used on websites where you have more content available than you want to display at one time to the user so …

web-项目管理

总结 目的是 1.可查询 2.方便团队管理 每个成员都可以看到任何东西 项目 需求 计划 bug 按模板来 1.问题描述 2.原因分析 3.解决方法 开发 提交代码 按模板来 1.问题描述 2.原因分析 3.解决方法 打包 更新说明文件.txt 按模板来 一、更新说明 1.问题描述 1&#xff09;计划号 2…

cnn对网络数据预处理_CNN中的数据预处理和网络构建

cnn对网络数据预处理In this article, we will go through the end-to-end pipeline of training convolution neural networks, i.e. organizing the data into directories, preprocessing, data augmentation, model building, etc.在本文中&#xff0c;我们将遍历训练卷积神…

leetcode 554. 砖墙

你的面前有一堵矩形的、由 n 行砖块组成的砖墙。这些砖块高度相同&#xff08;也就是一个单位高&#xff09;但是宽度不同。每一行砖块的宽度之和应该相等。 你现在要画一条 自顶向下 的、穿过 最少 砖块的垂线。如果你画的线只是从砖块的边缘经过&#xff0c;就不算穿过这块砖…

django-rest-framework解析请求参数过程详解

https://www.jb51.net/article/165699.htm 转载于:https://www.cnblogs.com/gcgc/p/11544187.html

递归 和 迭代 斐波那契数列

#include "stdio.h"int Fbi(int i) /* 斐波那契的递归函数 */ { if( i < 2 ) return i 0 ? 0 : 1; return Fbi(i - 1) Fbi(i - 2); /* 这里Fbi就是函数自己&#xff0c;等于在调用自己 */ }int main() { int i; int a[40]; printf("迭代显示斐波那契数列…

单元测试 python_Python单元测试简介

单元测试 pythonYou just finished writing a piece of code and you are wondering what to do. Will you submit a pull request and have your teammates review the code? Or will you manually test the code? 您刚刚编写了一段代码&#xff0c;并且想知道该怎么做。 您…

飞行模式的开启和关闭

2019独角兽企业重金招聘Python工程师标准>>> if(Settings.System.getString(getActivity().getContentResolver(),Settings.Global.AIRPLANE_MODE_ON).equals("0")) { Settings.System.putInt(getActivity().getContentResolver(),Settings.Global.AIRPLA…

消解原理推理_什么是推理统计中的Z检验及其工作原理?

消解原理推理I Feel:我觉得&#xff1a; The more you analyze the data the more enlightened, data engineer you will become.您对数据的分析越多&#xff0c;您将变得越发开明。 In data engineering, you will always find an instance where you need to establish whet…

pytest+allure测试框架搭建

https://blog.csdn.net/wust_lh/article/details/86685912 https://www.jianshu.com/p/9673b2aeb0d3 定制化展示数据 https://blog.csdn.net/qw943571775/article/details/99634577 环境说明&#xff1a; jdk 1.8 python 3.5.3 allure-commandline 2.13.0 文档及下载地址&…

lintcode433 岛屿的个数

岛屿的个数 给一个01矩阵&#xff0c;求不同的岛屿的个数。 0代表海&#xff0c;1代表岛&#xff0c;如果两个1相邻&#xff0c;那么这两个1属于同一个岛。我们只考虑上下左右为相邻。 您在真实的面试中是否遇到过这个题&#xff1f; Yes样例 在矩阵&#xff1a; [[1, 1, 0, …

大数据分析要学习什么_为什么要学习数据分析

大数据分析要学习什么The opportunity to leverage insights from data has never been greater.利用来自数据的洞察力的机会从未如此大。 Humans tend to generate a lot of data each day - from heart rates to favorite songs, fitness goals and movie preferences. You …

POJ - 3257 Cow Roller Coaster (背包)

题目大意&#xff1a;要用N种材料建一条长为L的路&#xff0c;如今给出每种材料的长度w。起始地点x。发费c和耐久度f 问&#xff1a;在预算为B的情况下&#xff0c;建好这条路的最大耐久度是多少 解题思路&#xff1a;背包问题 dp[i][j]表示起始地点为i。发费为j的最大耐久度…

leetcode 1473. 粉刷房子 III(dp)

在一个小城市里&#xff0c;有 m 个房子排成一排&#xff0c;你需要给每个房子涂上 n 种颜色之一&#xff08;颜色编号为 1 到 n &#xff09;。有的房子去年夏天已经涂过颜色了&#xff0c;所以这些房子不需要被重新涂色。 我们将连续相同颜色尽可能多的房子称为一个街区。&a…

大学生信息安全_给大学生的信息

大学生信息安全You’re an undergraduate. Either you’re graduating soon (like me) or you’re in the process of getting your first college degree. The process is not easy and I can only assume how difficult the pressures on Masters and Ph.D. students are. Ho…