Backend Development | 一篇文章上手Git

1.起步

如果你已经对git有基本了解,可以直接跳到第二章,大佬请直接无视。

1.1 Git是什么?

简单来说四个字:版本控制

什么是版本控制? 版本控制是跟踪文件变化内容分布式版本控制系统 (Distributed Version Control System)

1.2 历史

Git是由 Linux 之父 Linus Torvalds 在 2005 编写 Linux 内核时创造出来的工具。当时 Linux 内核是使用 BitKeeper 做版本控制, 但是 2005 年的时候BitKeeper撤回了该产品的免费使用权,市面上又没有满足需求的免费软件, Torvalds 想要一款和BitKeeper差不多的版本控制软件,于是Git应运而生。

1.3 特点

  1. 分布式系统

    Git 允许多人在自己的机器上同时修改同一个项目,每个人之间又不会互相干扰。和分布式相对的是集中式管理,就是所有代码放在一台机器上,每个人修改都要跑到这台机器上。

  1. 非线性开发

    大家各自开发各自的,每个人都可以产生一个分支,整体来看是一个树状图。

扫描二维码关注公众号,回复: 10846224 查看本文章

  1. 直接记录快照,而非差异比较

    Git 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。 为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。

  2. 近乎所有操作都是本地执行

    在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。 如你在飞机或火车上想做些工作,就能愉快地提交(到本地仓库), 直到有网络连接时再上传。

  3. Git 保证完整性

    Git 中所有的数据在存储前都计算校验和,然后以校验和来引用。 这意味着不可能在 Git 不知情时更改任何文件内容或目录内容。 这个功能建构在 Git 底层,是构成 Git 哲学不可或缺的部分。 若你在传送过程中丢失信息或损坏文件,Git 就能发现。

    Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符(0-9 和 a-f)组成的字符串,基于 Git 中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样:

    24b9da6552252987aa493b52f8696cd6d3b00373

    Git 中使用这种哈希值的情况很多,你将经常看到这种哈希值。 实际上,Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。

  4. Git 一般只添加数据

    你执行的 Git 操作,几乎只往 Git 数据库中添加数据。 你很难让 Git 执行任何不可逆操作,或者让它以任何方式清除数据。 同别的 VCS 一样,未提交更新时有可能丢失或弄乱修改的内容。但是一旦你提交快照到 Git 中, 就难以再丢失数据,特别是如果你定期的推送数据库到其它仓库的话。

    这样的好处就是你可以随便修改文件而不用担心会把程序搞砸,即使你误删了文件,或者代码被改的面目全非,你也可以通过版本回溯恢复之前的文件。

1.4 安装

Linux

基于 Debian 的发行版,如 Deepin, Ubuntu等:


$ sudo apt install git
复制代码

其他各个发行版的安装:git-scm.com/download/li…

macOS

在 Mac 上安装 Git 有多种方式。 最简单的方法是安装 Xcode Command Line Tools

Mavericks (10.9) 或更高版本的系统中,在 Terminal 里尝试首次运行 git 命令即可。

$ git --version
复制代码

如果没有安装过命令行开发者工具,将会提示你安装。

如果你想安装更新的版本,可以使用二进制安装程序。 官方维护的 macOS Git 安装程序可以在 Git 官方网站下载,网址为 git-scm.com/download/ma…

你也可以将它作为 GitHub for macOS 的一部分来安装。 它们的图形化 Git 工具有一个安装命令行工具的选项。 你可以从 GitHub for macOS 网站下载该工具,网址为 mac.github.com

Windows

官方版本可以在 Git 官方网站下载。 打开 git-scm.com/download/wi…

安装成功

安装成功之后在命令行输入 git 会得到类似如下的输出:

1.5 第一次运行前的配置

安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。 这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改:

$ git config --global user.name "John Doe"
$ git config --global user.email "[email protected]"
复制代码

再次强调,如果使用了 --global 选项,那么该命令只需要运行一次,为之后无论你在该系统上修改任何项目, Git 都会使用这个用户名和邮箱。 当你想针对特定项目使用不同的用户名和邮箱时,可以在那个项目目录下运行去除 --global 选项的命令来配置。比如

$ git config user.name "John Doe"
$ git config user.email "[email protected]"
复制代码

2. 基础

2.1 文件的状态

文件无论多少种状态,请记住,你工作目录下的每一个文件都不外乎这两种状态:已跟踪 或 未跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后, 它们的状态可能是未修改,已修改或已放入暂存区。简而言之,已跟踪的文件就是 Git 已经知道的文件。

工作目录中除已跟踪文件外的其它所有文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有被放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态,因为 Git 刚刚检出了它们, 而你尚未编辑过它们。

  • 未跟踪的文件的改动不受到Git的版本控制。

  • 已跟踪的文件,即被纳入版本控制的文件,又分为未修改(unmodified)、已修改(modified)、已暂存(staged)三种状态。

所以在 git 中,文件有四种状态,:未跟踪 (Untracked)未修改 (Unmodified)已修改 (Modified)已暂存 (Staged)

2.2 基本操作

只看文件的状态是不是一脸懵逼?所以我们来看操作,我们把Git的文件存放区域分成三块:工作区暂存区仓库

工作区 (Word Directory): 项目的工作目录,就是我们写代码的目录,本地的所有追踪和未追踪的文件都存在这里。

暂存区 (Stage): 修改的文件或者新增的文件使用 git add 追踪之后就会进入到暂存区。

仓库 (Repository): 暂存区的文件提交之后就会进入到仓库中。即使修改甚至删除本地的文件也不会影响仓库中的文件。

Git 的各个区域和操作之间的关系如下图:

Git 的基本操作有以下几种:

  • git init 初始化仓库
  • git clone 克隆仓库
  • git status 查看当前的文件的状态。
  • git add 使用命令 git add 开始跟踪一个文件。
  • git commit 提交文件到暂存区
  • git checkout
  • git reset

初始化仓库

初始化仓库有两种方式,第一种是 git clone 直接将远程仓库克隆到本地,这种初始化一般用于已经存在的项目,第二种是使用 git init来初始化仓库,这种方式一般用于第一次创建项目。

(1) 使用 git clone 克隆仓库

如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想参与到开源项目中,或者要加入其他人的项目中,这时就要用到 git clone 命令。 克隆仓库的命令是 git clone <url>,比如,要克隆 Cmatrix 的仓库,可以用下面的命令:

git clone https://github.com/abishekvashok/cmatrix
复制代码

屏幕会出现如下输出

正克隆到 'cmatrix'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 244 (delta 0), reused 1 (delta 0), pack-reused 240
接收对象中: 100% (244/244), 414.36 KiB | 28.00 KiB/s, 完成.
处理 delta 中: 100% (128/128), 完成.
复制代码

克隆完成之后,当前目录下会出现一个 cmatrix 的目录,仓库就初始化在 cmatrix 这个目录下。克隆操作会将远程项目的每一个文件的每一个版本都拉取下来。

(2) 使用git init初始化仓库

首先创建一个目录作为我们的工作目录,即工作区 (Work Directory),名字随便起一个,这里我们使用 myproject

myproject 目录下执行

$ git init
复制代码

会看到类似这样的提示:

已初始化空的 Git 仓库于 /home/git_user/myproject/.git/
复制代码

这样就说明我们的仓库已经初始化成功。该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件。此时,我们仓库就已经初始化完成了。

查看当前文件状态

git status 命令可以查看哪些文件处于什么状态。

上面我们已经成功初始化仓库,还记得我们之前说的三个区域吗?工作区就是我们当前这个目录仓库暂存区此时此时都是空的。我们可以使用 git status 来查看一下当前的状态,输入如下命令

$ git status
复制代码

输出结果如下:

位于分支 master

初始提交

无文件要提交(创建/拷贝文件并使用 "git add" 建立跟踪)
复制代码

现在我们创建一个文件名为 README.md 的文件,我们随便写点内容进去:

This is a readme doc.
复制代码

我们查看一下此时的状态:

$ git status

位于分支 master

初始提交

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)

	README.md

提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

复制代码

一般情况 git 会用红色将 新增的文件修改过的文件已删除的文件,标记出来,比如上面输出结果的 README.md。如下图:

此时我们的 工作区 已经有一个尚未追踪的README.md 的文件, 暂存区仓库 还都是空的。如图:

将文件快照加入到暂存区

快照简单理解就是文件的拷贝,git add 这个命令就像是把工作区的文件拷贝到暂存区一样。

上面我们已经成功的初始化仓库,并且已经在 工作区 新增了一个 README.md,该文件目前处于 未跟踪 状态,我们可以用 git add 把这个文件加入到 暂存区 (Stage)

git add README.md
复制代码

此时再运行 git status 命令,输出结果大概这样:

位于分支 master

初始提交

要提交的变更:
  (使用 "git rm --cached <文件>..." 以取消暂存)

	新文件:   README.md

复制代码

如果你的 git 有配色,这里的 README.md 会变成绿色。如果没有配色也没有关系,只要在 要提交的变更 这下面的文件,就说明存在于 暂存区 (Stage)

此时 README.md 的快照已经加入到 暂存区 (Stage) 中, 三个区域的状态如下:

这时候,如果我删除工作区的 README.md,暂存区的 README.md 是不受影响的。

紧接着,我们发现,README.md 文件好像不够详细,于是我们在 README.md 加了一些详细内容。现在 README.md 变成这样:

This is a readme doc.

# Detail

Detail.
Detail.
Detail.
Detail.
Detail.
Detail.

复制代码

再来查看一下文件状态,运行 git status:

位于分支 master

初始提交

要提交的变更:
  (使用 "git rm --cached <文件>..." 以取消暂存)

	新文件:   README.md

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

	修改:     README.md

复制代码

同样,我们运行

git add README.md
复制代码

这样就可以将 README.md 加入到 暂存区 (Stage) 中了。此时,暂存区的 README.md 就会被我们修改完之后的 README.md 替换掉。再次运行 git status

位于分支 master

初始提交

要提交的变更:
  (使用 "git rm --cached <文件>..." 以取消暂存)

	新文件:   README.md
复制代码

将暂存区的文件快照提交到版本库

git commit 会将暂存区的快照提交到仓库中,Git 会记录这些快照。

提交常用的格式是:git commit -m <提交的信息>, 每一条提交记录都对应一条提交信息,用来阐述提交的内容。

我们在命令行执行

git commit -m "First commit"
复制代码

得到如下输出

[master(根提交) 049d8df] First Commit
 1 file changed, 10 insertions(+)
 create mode 100644 README.md
复制代码

此时我们的文件已经提交到仓库中。暂存区的文件就会删除掉 (所以说叫暂存区) ,但是本地 (工作区) 的文件不会更改,也不会被删除,不受 Git 的影响。所以此时三个区域的状态如下图:

忽略文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如 日志文件 ,或者编译过程中创建的 临时文件 等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。

注意:.gitignore 文件和其他文件一样,也是需要提交到仓库中,并且 Git 会对该文件进行版本管理。

来看一个实际的 .gitignore 例子:

$ cat .gitignore
复制代码
*.[oa]
*~
复制代码

第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为你的新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。(# 开头为注释)

  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。

  • 匹配模式可以以(/)开头防止递归。

  • 匹配模式可以以(/)结尾指定目录。

  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c); 问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。 使用两个星号 (**)表示匹配任意中间目录,比如 a/**/z 可以匹配 a/z 、 a/b/z 或 a/b/c/z 等。

我们再看一个 .gitignore 文件的例子:

# 忽略所有的 .a 文件
*.a

# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
复制代码

TIPS: 一个针对各种语言的 .gitignore 模板集合:github.com/github/giti…

在最简单的情况下,一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整个仓库中。 然而,子目录下也可以有额外的 .gitignore 文件。子目录中的 .gitignore 文件中的规则只作用于它所在的目录中。 (Linux 内核的源码库拥有 206 个 .gitignore 文件。)

查看文件改动

(1) 查看工作区文件改动

查看 工作区 (Working Directory) 对比 暂存区 (Stage) 做了那些改动,只需要使用 git diff 就可以了。

我们新建一个文件 a.txt, 内容为 "abc", 保存之后,执行

git add a.txt
复制代码

此时 a.txt 已经提交到 暂存区 (Stage) 中,我们再次对 a.txt 修改,将内容改为

bbc
aaa
bbb
ccc
复制代码

此时我们执行 git diff 就会看到如下结果, (按q退出)


diff --git a/a.txt b/a.txt
index 8baef1b..695c27b 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,4 @@
-abc
+bbc
+aaa
+bbb
+ccc
(END)
复制代码

此命令比较的是工作目录中当前文件和暂存区快照之间的差异。

如果要查看 暂存区 (Stage)仓库 (Repository) 之间的差异, 可以使用 git diff --staged 命令。

跳过使用暂存区域,直接提交文件到仓库

有时候用暂存区非常麻烦,Git 提供了一个跳过暂存区,直接提交到仓库的办法。只要在提交的时候,给 git commit 加上 -a 选项,Git 就会自动把所有 已经跟踪过的文件 暂存起来一并提交,从而跳过 git add 步骤。

git commit -a -m 'new commit'
复制代码

移除文件

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。

如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 “Changes not staged for commit” 部分(也就是 未暂存清单)看到:

位于分支 master
尚未暂存以备提交的变更:
  (使用 "git add/rm <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

	删除:     a.txt

修改尚未加入提交(使用 "git add" 和/或 "git commit -a"复制代码

然后再运行 git rm 记录此次移除文件的操作,此时我们再查看一下,这次删除操作已经提交到暂存区。

位于分支 master
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

	删除:     a.txt
复制代码

下一次提交时,该文件就不再纳入版本管理了。 如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 -f(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删尚未添加到快照的数据,这样的数据不能被 Git 恢复。

另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加 .gitignore 文件,不小心把一个很大的日志文件或一堆 .a 这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用 --cached 选项:

git rm --cached <文件名 或者 glob字符串>
复制代码

git rm 命令后面可以列出文件或者目录的名字,也可以使用 glob 模式。比如:

git rm log/\*.log
复制代码

注意到星号 * 之前的反斜杠 \, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除 log/ 目录下扩展名为 .log 的所有文件。 类似的比如:

git rm \*~
复制代码

该命令会删除所有名字以 ~ 结尾的文件。

取消暂存的文件

使用 git reset 可以撤销掉暂存区的快照。如果执行

git reset
复制代码

所有暂存区的操作将会删除掉。如果只是想针对一个文件撤销暂存,可以这样

git reset HEAD README.md
复制代码

撤消对文件的修改

这里的撤销修改的意思是用 仓库 (Repository) 的文件覆盖本地的(工作区)文件 (注意下面命令中 -- 两边都有空格)。

git checkout -- README.md
复制代码

这样,Git 会从远程仓库拉取最新版本的 README.md 覆盖本地的 README.md

!!! 这个操作要谨慎使用,因为会用远程仓库的文件覆盖本地的文件,如果本地文件没有保存,那就凉凉。

查看远程仓库

如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
复制代码

添加远程仓库

git clone 会自动为你添加远程仓库,如果是我们手动初始化的仓库,就需要我们自己添加远程仓库,运行 git remote add <远程分支别名> <远程仓库地址> 添加一个新的远程 Git 仓库。其中 远程分支别名 是用来代替URL的简写,可以自己命名。

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)
复制代码

从远程仓库中抓取与拉取

从远程仓库中获得数据,可以执行:

$ git fetch <remote>
复制代码

git fetch 命令只会将数据下载到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。

如果你的当前分支设置了跟踪远程分支, 那么可以用 git pull 命令来自动抓取后合并该远程分支到当前分支。 这或许是个更加简单舒服的工作流程。默认情况下,git clone 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或其它名字的默认分支)。 运行 git pull 通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。

推送到远程仓库

当你想分享你的项目时,必须将其推送到远程仓库。 这个命令很简单:git push 。 当你想要将 master 分支推送到 origin 服务器时(再次说明,克隆时通常会自动帮你设置好那两个名字), 那么运行这个命令就可以将你所做的备份到服务器:

$ git push origin master
复制代码

只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先抓取他们的工作并将其合并进你的工作后才能推送。 简单来说,就是他也改了文件,你也改了,你得先把他改的东西加进来才能提交你的更改

查看某个远程仓库

如果想要查看某一个远程仓库的更多信息,可以使用 git remote show <remote> 命令。 如果想以一个特定的缩写名运行这个命令,例如 origin,会得到像下面类似的信息:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)
复制代码

这是一个经常遇到的简单例子。 如果你是 Git 的重度使用者,那么还可以通过 git remote show 看到更多的信息。

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)
复制代码

这个命令列出了当你在特定的分支上执行 git push 会自动地推送到哪一个远程分支。 它也同样地列出了哪些远程分支不在你的本地,哪些远程分支已经从服务器上移除了, 还有当你执行 git pull 时哪些本地分支可以与它跟踪的远程分支自动合并。

查看提交历史

使用 git log 可以查看提交历史,加入参数 --pretty=oneline 可以将每个提交记录用一行的空间展示出来。

git log --pretty=oneline
复制代码

打标签

Git 可以给仓库历史中的某一个提交打上标签,以示重要。比如我们在某一次 commit 之后,构建了一个可运行的稳定版本,这时候我们可能想标记一下这个版本( v1.0 、 v2.0 等等),这时候就用到了标签功能。

这里我们使用 cmatrix 项目来举例子。克隆项目到本地,然后进入目录。

$ git clone https://github.com/abishekvashok/cmatrix
$ cd cmatrix
复制代码

查看该项目的标签:

$ git tag
1.2
v2.0
复制代码

!!! danger df

3. Github

Pull Request

  1. Fork 项目到自己的 Github
  2. 在 Fork 之后的项目中新建分支,修改之后上传到自己的 Github.
  3. 在 Github 上发起 Pull Request 原则:Fork 过来的 master 分支不更改,所有改动都新建分支。

更新 Fork 之后变更较多的项目

有些项目更新速度非常快,或者你 Fork 一个项目已经很久了,这时 Fork 过来的项目和原项目有很大差异,我们就需要将 Fork 过来的项目与原项目进行同步。

1. 添加远程仓库上游地址

$ git remote add upstream <原项目地址>
复制代码

可以使用如下命令查看:

$ git remote -v
origin	[email protected]:xxx/fastapi.git (fetch)
origin	[email protected]:xxx/fastapi.git (push)
upstream	https://github.com/tiangolo/fastapi.git (fetch)
upstream	https://github.com/tiangolo/fastapi.git (push)
复制代码

其中下面两行就是我们刚刚增加的上游仓库

2. 合并仓库

切换到主分支

$ git checkout master
复制代码

下载上游仓库

git fetch upstream
复制代码

合并仓库

git merge upstream/master
复制代码

3. 推送到远程仓库(自己)

git push origin master
复制代码

文章内容可能有纰漏,欢迎斧正

猜你喜欢

转载自juejin.im/post/5e7b7ef2f265da42dc02f46d