Skip to content

How to Use Git & GitHub

jamesnulliu edited this page Apr 23, 2024 · 11 revisions

How to Use Git & GitHub

1. 下载 & 安装 Git

Linux 用户可以直接通过 sudo apt install git 安装 git.

Windows 用户可以在 Git 官网 下载安装最新版本 Git.

  • 注意: 本文只解释如何使用 Git Bash (终端) 进行版本控制.

无论是 Windows 还是 Linux,
只要系统带图形界面,
都可以在工作区文件夹的空白处右键;
在弹出菜单中:
❗Linux 用户请选择打开终端 (terminal),
Windows 用户请选择打开 git bash.

此时终端 (或 git bash) 的打开路径将是工作区文件夹的路径.

如果不带图形界面, 请打开终端 (或 git bash), cd 到工作区文件夹的路径去.

为了方便书写, 后文统一使用 "终端" 一词, Windows 用户需要明白这是指 git bash 而不是 cmd 或者 powershell.

在终端输入以下命令检查 git 版本:

git -v

2. 必要设置

请先完成本节的设置再看后面的内容.

当利用 Git 进行版本管理并希望 commit 一些改动时, 需要提供 user 的信息;
具体来说, 你需要设置 (当前工作区或全局的) :

  • user.name
  • user.email

你的所有 commit 记录中都会包含你设定的 user 信息.

为了简化教学, 我们直接设置全局的 user 信息.

在电脑的任意位置打开终端, 输入以下指令设置 user.name (请将 <YourName> 替换为合适内容):

git config --global user.name "<YourName>"

接着输入以下指令设置 user.email (请将 <YourEmail> 替换为合适内容):

git config --global user.email "<YourEmail>"

😼按照以上步骤设置完成后, 除非你重装了 Git 或者想改名字, 否则都不用再设置了.

3. 本地 Git 储存库

3.1. 在工作区内创建本地 Git 储存库

注意: 工作区就是一个项目的根目录, 或者说项目文件夹.

你可以为任意一个工作区创建一个本地 Git 储存库, 进而进行版本控制.

将终端路径设置为工作区路径 (或者在工作区文件夹内的空白处右键, 打开终端), 输入以下指令可以将当前工作区创建为一个本地 Git 储存库:

git init


Figure 1. git init 做了什么

在 Fig.1 中, 由于我们刚刚创建了一个 Git 储存库, 但还没告诉储存库: "你应该去跟踪工作区里的 main.cpp 的改动."
因此 Git 储存库会告诉你: "我没有跟踪 (Untrack) 你的工作区里叫 'main.cpp' 的文件."

3.2. 将改动 commit 至本地 Git 储存库

先创建一个空文件夹作为工作区;
在文件夹中添加一个文件 (比如 "main.cpp"); 根据 3.1. 在工作区内创建本地 Git 储存库, 为工作区初始化一个本地 Git 储存库.

当工作区内的某些文件出现改动, 在终端输入以下命令可以查看详细信息:

git status

对于 Fig. 1 的情况, 终端会输出类似于 "Untraked files: main.cpp" 的提示.

可以利用以下命令将工作区内的改动 add 到缓存区(add 后, 改动还没被正式记录下来, 只是被缓存了):

git add <FilePath>


Figure 2. git add 做了什么

接着利用以下命令可以正式将改动 commit 到本地 Git 储存库:

git commit -m "<Message>"


Figure 3. git commit 做了什么

参考 Fig.3, commit 完成后, 当前的工作区内的所有内容将成为一个版本, 记录在本地 Git 储存库中.

参考 Fig.4,
我们修改 "main.cpp" 中的内容 (比如写两行代码),
同时在工作区内又新建一个 "tool.cpp";
在终端输入 git status 命令,
会提示 main.cpp 处于 Modified 的状态, 而 tool.cpp 处于 Untracked 的状态.

此时输入以下命令将所有的更改 (包括 Modified 和 Untracked) 都 add 进缓存区:

git add .

然后输入以下命令 commit 缓存区的更改:

git commit -m "<Message>"


Figure 4. commit 第二个版本

Fig.4 中, 我们 commit 了工作区中所有的更改,
于是在本地 Git 储存库中创建了第二个版本;
这个版本是当前项目的最新版本.

之后的开发过程中如果出现问题, 可以进行版本回退, 这里不多赘述.

4. 远程储存库

3. 本地 Git 储存库 中, 我们已经学习了如何在本地进行项目的版本管理.

但是很多时候, 我们需要在不同的电脑上部署自己的项目 (多人协同开发).

因此会出现 "将本地 Git 储存库同步到一个远程储存库 (例如 GitHub)" 的想法.

本节我们就说说怎么使用远程 GitHub 储存库.

4.1. 创建一个远程 GitHub 储存库


Figure 5. 如何创建一个远程 GitHub 储存库

  1. 输入 GitHub 的网址进入首页并登录.
  2. 点击左侧的 New 按钮创建一个新储存库.
  3. 给储存库取个名字.
  4. 写一个对于当前储存库的简短介绍.
  5. 选择是否公开储存库, 如果不公开, 除了你以外别人都无法看到你的储存库.
  6. 选择是否添加一个 README 文件, 相当于对自己储存库的详细介绍文件. README 文件会展示在储存库的首页.
  7. 选择是否添加 .gitignore 文件; 目的是强制地不跟踪项目中的某些文件; 这个有机会细说吧.
  8. 选择一个 licence, 也就是告诉别人可以怎么使用你的代码: 能不能进行商业行为, 能不能直接复制你的代码不注明你是作者之类的.
  9. GitHub 上目前把默认分支名从 master 改成 main 了, 这是为了回应 Black Lives Matter 运动; 由于本文不会详细谈关于分支的内容, 这个设置的影响不是特别大, 可以直接忽略.
  10. 上面 9 步设置完后, 点右下角 Create repository, 你就能成功创建一个远程 GitHub 储存库, 并且跳到储存库的首页了😁.

注意: GitHub 上创建的 repo 默认分支名为 main (而非 master).

4.2. 生成 SSH 密钥 & 公钥

SSH 是一种网络协议, 用于计算机之间的加密登录;
具体是什么这里就不细说了.

目前有两种主流的算法生成密钥, 一种是 rsa, 另一种是 ed25519.

ed25519 是一种 ECC 算法, 比起传统的 rsa 更加现代化和高效.

本文使用 ed25519 算法生成密钥.

Key Points

  • 在你的系统下, 你可以生成多对 SSH 密钥, 然后将其中的一对绑定到 GitHub 账号.
  • 你可以把其他的密钥绑定到其他地方, 比如 Gitee.
  • ssh 一般来说直连就能 clone Github 上的储存库, 不需要走代理; 因此对有些场景比较友好.
  • ssh 比 http 更安全.

Step 1

注意: 在 Linux 下, 如果你的用户名是 "james", 那么在终端输入路径时, 开头的 "~" 会被系统自动替换为 "/home/james"; 而如果是 Windows, "~" 会被自动替换为 "C:/Users/james".

在你的个人文件夹下创建一个叫 ".ssh" 的文件夹. 可以通过在终端中输入以下命令创建文件夹 (如果已经创建, 会报错文件夹已存在; 忽视即可):

mkdir ~/.ssh

根据不同的平台, 在终端输入以下两个命令之一, 进而创建 SSH Keys (请把 <comments>, <key_name>, <your_user_name> 替换为合理的内容):

# Windows:
ssh-keygen -t ed25519 -C "<comments>" -f C:/Users/<your_user_name>/.ssh/<key_name>

# Linux:
ssh-keygen -t ed25519 -C "<comments>" -f /home/<your_user_name>/.ssh/<key_name>

命令解释:

  • ssh-keygen 表示生成 ssh 密钥
  • -t ed25519 表示使用 ed25519 算法; 如果使用 rsa 算法, 建议输入 -t rsa -b 4096, 即生成 4096 bits 的密钥
  • -C "<comments>" 是对该密钥的说明, 引号内的 <comments> 可以替换成任何文字;
  • -f xxx/.ssh/<keyname> 指出了密钥的生成路径以及密钥的文件名 (可以按需更改), 文件名可以依据自己的需求更改, 生成的密钥可在 "xxx/.ssh" 路径下找到;

Step 2

输入命令后终端提示为生产的密钥设置一个密码, 我们建议设置一个密码;

注意: 在你输入密码时, 终端的界面上不会显示出白色的输入内容字符 (看起来和没输入一样), 这是对周围环境的防范.

再次输入与刚刚相同的密码, 匹配成功后显示密钥成功生成, 并输出了密钥的指纹和随机图像. 可以忽略这些内容.

Step 3

进入 "~/.ssh" (里面应该有你之前创建的密钥文件),
新建一个文件, 取名为 config (不要保留任何后缀名),
在文件内输入以下内容 (根据之前的命令修改 Identity File 的路径, 也就是你的密钥路径) 以设置你的 ssh 密钥:

Host github.com
  Hostname ssh.github.com
  Port 443
  User git
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/<keyname>
  TCPKeepAlive yes
  IdentitiesOnly yes

Step 4

接着我们要在自己的 GitHub 账号中添加公钥,
目的是给远程储存库加密.

在你的电脑上, 复制 "~/.ssh" 路径下 <KeyName>.pub 文件中的所有内容 (复制的内容就是公钥).


Figure 6. 如何给 GitHub 添加 SSH 公钥

根据 Fig.6:

  1. 打开 Github, 登录账号, 点击右上角头像
  2. 点击 Settings 按钮进入设置页
  3. 在页面左侧栏中找到 SSH and GPG keys , 点击进入
  4. 点击右侧按钮 New SSH key 添加一个 ssh 公钥
  5. 为公钥随便取个名字
  6. 在 Key 窗口粘贴前面复制的 <KeyName>.pub 中的所有内容
  7. 点击按钮 Add SSH key

Step 5

回到电脑, 任意位置打开终端,

在 linux, 我们需要额外设置密钥的权限为仅有你可读, 因此需要补一条指令 (将其中的 <your_user_name><key_name> 替换为相应内容):

# Linux only:
chmod -R 600 /home/<your_user_name>/.ssh/<key_name>

输入以下命令测试和 github 的 ssh 连接:

ssh -T git@github.com

终端提示输入密码, 输入刚才设置的密码.

之后会提示该密钥还没被授权 (Authenticate), 提问是否授权;
输入 yes 后再回车.

接着会有类似于: Hi jamesnulliu! You've successfully authenticated, but GitHub does not provide shell access. 的提示.

如果提示: git@github.com: Permission denied (publickey),
可能是网络连接失败, 可以再试几次.

4.3. Clone 远程储存库至本地

请参考 4.1. 创建一个远程 GitHub 储存库 先创建一个远程储存库, 储存库中应该包含两个文件: README 和 LICENSE.

我们假设创建的远程储存库的名字为 Test.

接着请参考 4.2. 生成 SSH 密钥 & 公钥 生成一对能连接到 GitHub 的密钥.

上述步骤做完后, 请参考 Fig.7 复制远程储存库地址:


Figure 7. 复制 GitHub 储存库的步骤.

  1. 进入 GitHub, 点右上角头像
  2. 在弹出栏点 Your repositories 进入你所有储存库的页面
  3. 查找创建的储存库的名字
  4. 点击蓝色的链接进入储存库主页
  5. 点击 <> Code 图标
  6. 在弹出窗口点击 SSH
  7. 点击小方块复制储存库地址

回到你的电脑, 我们假设在 "~" 下 创建一个文件夹叫 "projects".

注意: 在 Linux 下, 如果你的用户名是 "james", 那么在终端输入路径时, 开头的 "~" 会被系统自动替换为 "/home/james"; 而如果是 Windows, "~" 会被自动替换为 "C:/Users/james".

打开终端, 切换路径到 "~/projects" (或者你可以在文件夹内右键空白处, 直接在 "~/projects" 打开终端):

cd ~/projects

输入以下指令将你刚刚创建的远程 Git 储存库 clone 至本地 (请将 <RepoAddress> 替换为 Fig.7 中第7步复制的仓库地址):

git clone <RepoAddress>

Clone 完成后, "~/projects" 内将出现一个新的文件夹,
该文件夹的名字与 GitHub 上你创建的远程 GitHub 储存库的名称相同 (对于 Fig.7, 我 clone 下来的文件夹应该叫 "Test");

文件夹内部存在一个隐藏的 .git 文件夹,
因此该文件夹已经包含了一个本地 Git 储存库 (无需再使用 git init 命令创建一个本地 Git 储存库),
并且本地 Git 储存库还连接到了一个远程 GitHub 储存库.

4.4. 将本地项目直接连接至远程储存库

4.3. Clone 远程储存库至本地 中, 我们 clone 下来了一个新创建的远程储存库, 然后直接在里面写代码.

然而很多时候是我们先创建了一个工程,
写了一些代码,
然后希望把已经写好的代码直接连接到一个新的远程储存库中.

比如我用 Visual Studio 2022 创建了一个 C++ 项目叫 HelloWorld, 那么我一定会在本地已经有一个叫 "HelloWorld" 的文件夹. 这个时候我希望在 GitHub 上创建一个远程储存库也叫 "HelloWorld", 然后直接将本地的 "HelloWorld" 项目链接过去.

为了直接将本地项目直接连接至远程储存库, 请参考前文, 先完成以下四步:

  1. 创建一个远程 GitHub 储存库 (参考 4.1. 创建一个远程 GitHub 储存库).
  2. 在本地已经包含项目文件的工作区内创建一个本地 Git 储存库 (在工作区路径下使用 git init 命令) (参考 3.1. 在工作区内创建本地 Git 储存库).
  3. 生成一对可用的 ssh 密钥和公钥 (如果已经有密钥, 可以跳过) (参考 4.2. 生成 SSH 密钥 & 公钥).
  4. 复制远程 GitHub 储存库的 ssh 地址 (参考 4.3. Clone 远程储存库至本地 中的 Fig.7).

接着打开终端, 将终端路径切换到本地的工作区内,
通过以下命令使本地 Git 储存库指向远程储存库 (将 <sshAddress> 改为复制的地址):

git remote add origin <sshAddress>

假设远程储存库的默认分支名为 main,
先 pull 远程储存库中的内容:

git pull origin main

然后将本地 Git 储存库的当前分支切换到 main :

git checkout main

将本地的 main 分支与远程的 main 分支连接:

git branch --set-upstream-to=origin/main main

提交本地更改至本地 git 储存库:

git add .
git commit -m "Initial Update"

4.5. Push

请先参考 4.3. Clone 远程储存库至本地 clone 一个远程储存库到本地, 或者参考 4.4. 将本地项目直接连接至远程储存库 建立一个本地 Git 储存库和远程储存库的连接.

总之你应该有一个 工作区 + local Git repo, 同时本地 Git repo 连接到了 remote GitHub repo 的结构.

请先在工作区 创建一个 "SHU.txt" 文件, 然后将终端路径切换到工作区内.

3.2. 将改动 commit 至本地 Git 储存库 中, 我们已经讲述了如何将本地的改动commit 至 local Git repo.
请参考该节内容, 将 "我创建了 SHUSHU.txt" 这个 modification commit 到本地 Git 储存库中.

如果你成功了, 当再次输入 git status 时, 应该会出现类似下面的提示:

On branch main
Your branch is up to date with 'origin/main'

接着只要输入以下指令, 就能将 "我创建了 SHUSHU.txt" 这个 modification push 到 remote GitHub repo 上了 (请将 <branch name> 替换为 GitHub repo 中对应的分支名, 默认应该是 main):

git push origin <branch name>

刷新 GitHub 上的 Repo 页面, 能够发现 "SHUSHU.txt" 已经被同步至 (remote) GitHub repo.

4.6. Pull

当本地工作区 (local repo) 的项目版本落后于远程储存库 (或者说远程储存库 中有新更新), 就需要将远程储存库 中的改动 pull 至 local.

具体来说, 打开终端, 切换路径到工作区内;

你需要确保自己的项目有工作区 + Git repo, 同时 Git repo 连接到了 GitHub repo 的结构 (你可以通过参考 4.3. Clone 远程储存库至本地 clone 一个远程储存库到本地, 或者参考 4.4. 将本地项目直接连接至远程储存库 来完成这个结构).

然后输入命令:

git pull

即可将 GitHub repo 中的改动 pull 至 local.

4.7. Adding Sub-Modules

为什么要添加 Sub-Module? 因为你的当前项目可能用到别人的项目的代码, 如果别人的项目更新了, 通过将别人的项目添加为你的项目的 Sub-Module 的方式, 就能快速同步别人的更新.

假设你已经有了一个项目, 项目有工作区 + Git repo, 同时 Git repo 连接到了 GitHub repo 的结构.

在工作区内打开终端, 输入以下命令可以将他人的 Github 项目添加为当前你的项目的 sub-module:

git submodule add <url> <path>

例如你的工作区路径为 "D:/projects/project1/", 他人的 Github 项目链接为 "git@github.com:12345/project2";

输入指令 git submodule add git@github.com:12345/project2 ./p2 后, 在 "D:/projects/project1/" 路径下会出现一个新文件夹 "p2", 文件夹内就是 project2 的全部内容.

当他人更新了 project2 的代码, 你只需要在 "D:/projects/project1/p2" 路径下打开终端, 输入 git pull 即可.