文章

Git 基础操作总结

Git 是一个强大而灵活的版本控制系统,掌握其基础配置和常用操作能够有效提高开发效率。

下载 Git

Git 官方网站下载。 打开 https://git-scm.com/download,根据不同类型的系统下载对应的 Git 客户端。

配置 Git

Git 配置的三个层级

Git 通过 git config 命令来管理配置文件,这些配置存储在三个不同的地方,按优先级顺序(从高到低)为:

系统级配置 (/etc/gitconfig)

  • 针对整个系统的配置文件,影响系统上所有用户和仓库。
  • 可以通过 git config --system 来修改此配置文件,但需要管理员权限。
  • 这个配置文件用于设置系统范围的全局行为,如某些工具的路径等。

用户级配置 (~/.gitconfig~/.config/git/config)

  • 只影响当前用户下的所有 Git 仓库。使用 --global 选项时,Git 会读写此文件。
  • 这是最常用的配置层级,适用于配置用户名、电子邮件等,影响当前用户下的所有仓库。

仓库级配置 (.git/config)

  • 针对特定仓库的,它只会影响当前仓库。如果没有明确指定 --global--system,则默认会修改此配置文件。
  • 适用于特定仓库的个性化设置,例如特定仓库的远程仓库 URL 或分支设置等。

配置覆盖规则

  • 配置有层级结构,仓库级配置.git/config)会覆盖用户级配置~/.gitconfig)的内容。而用户级配置会覆盖系统级配置/etc/gitconfig)的内容。

查看所有配置

查看当前 Git 环境的所有配置项及其来源(即它们存储在哪个配置文件中)。

$ git config --list --show-origin
  • 按下 Q 键可以退出查看状态。

检查特定配置项

例如,查看当前的用户名和电子邮件配置:

$ git config user.name
$ git config user.email

配置全局用户名和电子邮件

对于常规的 Git 操作,配置用户名和电子邮件是必需的。特别是提交代码时,Git 会将这些信息附加到每次提交记录中。

$ git config --global user.name "your name"
$ git config --global user.email "your_email@example.com"

SSH 密钥配置

当使用 SSH 格式的仓库 URL 时,Git 会通过 SSH 密钥进行身份验证,确保与远程仓库的安全连接。Git 会使用配置的私钥进行加密认证,而不需要每次输入用户名和密码。

创建 SSH 公钥和私钥

1.打开 Git Bash(可以通过右键点击文件夹选择 "Git Bash Here")。

2.在 Git Bash 中生成 SSH 密钥对,运行以下命令:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

说明:

  • -t rsa 指定了使用 RSA 算法生成密钥。
  • -b 4096 指定密钥的位数,4096 位比默认的 2048 位更安全。
  • -c 后面的内容是使用的 GitHub 账户邮箱,用于标识该公钥。

3.提示确认保存密钥的路径时,按 Enter 键(默认保存路径为 ~/.ssh/id_rsa),如果你希望使用不同的文件名,按提示输入新名称。

4.如果希望给 SSH 密钥设置密码,输入密码并确认。如果不设置密码,按两次 Enter 键跳过。

检查生成的密钥

生成 SSH 密钥后,会在 ~/.ssh 文件夹(例如,Window 系统下的 C:\Users\Administrator\.ssh)下看到有两个文件:

  • id_rsa:这是私钥,不能与任何人分享,应该保存在本地计算机上。
  • id_rsa.pub:这是公钥,可以公开分享,通常上传到 GitHub。

将公钥添加到 GitHub

1.复制公钥内容:用文本编辑器打开 id_rsa.pub,复制里面的所有内容。

2.登录 GitHub,进入 SSH and GPG keys 设置页面。

3.点击 New SSH key 按钮,在弹出的框中粘贴你复制的公钥内容,给它一个易于识别的标题(例如 "My Laptop SSH Key")。

4.点击 Add SSH key 完成。

例如,GitHub 的设置界面:

![res/Pasted image 20240917231510.png](https://raw.githubusercontent.com/littlekj/linkres/master/obsidian/res/Pasted image 20240917231510.png)

测试 SSH 连接

验证 SSH 密钥配置是否成功,在 Git Bash 中执行以下命令:

ssh -T git@github.com

返回类似如下的信息:

Hi littlekj! You've successfully authenticated, but GitHub does not provide shell access.
  • 提示:您已成功通过身份验证,但 GitHub 不提供 shell 访问权限。这是 GitHub 的正常行为,并不表示您的设置存在任何问题。

配置 SSH 连接 GitHub

确保 Git 仓库使用 SSH 格式的 URL,格式如下:

git@github.com:username/repository.git

这样配置后,以后在 Git 操作(如 git pullgit push)时,Git 会自动使用 SSH 密钥进行认证,而无需输入用户名和密码。

启用 SSH 代理

SSH 代理(SSH Agent)是用于管理 SSH 私钥的工具。它的作用:

  • 避免每次输入私钥的密码:如果私钥设置了密码保护,使用 SSH 代理后,只需要输入一次私钥密码,之后的所有 SSH 连接都会使用已加载的私钥,而不需要再次输入密码。
  • 集中管理多个私钥:如果有多个 SSH 密钥,SSH 代理会在你本地的会话中管理它们,确保它们可以正确用于对应的连接。

在终端中启动 SSH 代理:

eval "$(ssh-agent -s)"

这将启动一个新的 SSH 代理进行并设置环境变量。

添加私钥到 SSH 代理:

ssh-add ~/.ssh/id_rsa

这样,SSH 代理会记住你的私钥,并在以后的 SSH 连接中使用它。当私钥设置了密码保护,第一次使用时,代理会要求你输入密码解锁私钥,并把私钥保存在内存中供后续使用。

配置个人访问令牌

当使用 HTTPS 格式的仓库 URL 时,GitHub 会要求通过个人访问令牌(Personal Access Token,PAT)进行身份验证,代替传统的用户名和密码方式。

生成个人访问令牌:

  • 登录到 GitHub
  • 点击页面右上角的头像,选择 Settings(设置)。
  • 在左侧栏中,找到并点击 Developer settings
  • 点击 Personal access tokens,然后点击 Tokens (classic) 选项。
  • 点击 Generate new token 按钮。
  • 在弹出的页面中,你可以选择令牌的权限(通常,你需要选择 repo 权限来访问仓库)。如果只是进行代码克隆和拉取,选择最基本的权限即可。
  • 为令牌选择一个过期时间(例如 30 天,90 天,或者没有过期时间),然后点击 Generate token
  • 生成后,会显示你的 Personal access token,需要记住这个令牌,之后将无法再次查看。

使用个人访问令牌:

在 Git 操作中,当拉取或推送代码时,Git 会要求你输入 GitHub 的用户名和密码。这时,输入 GitHub 用户名和生成的个人访问令牌。

凭证存储:

使用 git 存储和使用 Token 令牌时,可以利用凭据助手(credential.helper)来安全存储和管理令牌。例如,你可以使用 credential-storecache 来帮助存储 GitHub 的个人访问令牌。

配置 Git 使用 credential-store

git config --global credential.helper store

这会在全局范围内启动 credential-store,令牌凭据将被存储在一个纯文本文件中,默认路径是 ~/.git-credentials

在首次 Git 操作时,输入 Token 被存储到 ~/.git-credentials

或者手动添加凭据(URL 和 Token)到 ~/.git-credentials

https://<TOKEN>@github.com
  • 替换 <TOKEN> 为你的 GitHub 个人访问令牌。

.gitignore 文件

gitingore 文件用来管理 Git 跟踪文件的规则。

忽略指定类型的文件

通过 .gitignore 文件指定需要忽略的文件类型。

例如,忽略所有 .a 文件:

.a

使用 ! 取消忽略

如果之前忽略了某个类型的文件,但希望排除特定的文件类型(即跟踪文件),可以使用取消忽略。

例如:跟踪 lib.a 文件,尽管 .a 文件类型被忽略:

!lib.a

忽略特定目录

如果你希望忽略某个目录中的所有文件,可以使用目录路径。

例如:忽略名为 build 的目录及其内容:

build/

忽略特定目录下的文件

你可以指定 .gitignore 只忽略某个目录下的文件,而不影响其他目录。

例如:忽略当前目录下的 TODO 文件,但不影响 subdir/TODO 文件:

TODO

忽略特定文件,但不影响某些文件

通过具体的路径指定只忽略某些文件,而不忽略该路径下的其他文件。例如:

例如:忽略 doc/notes.txt,但不忽略 doc/server/arch.txt

doc/notes.txt

递归忽略文件

可以使用 ** 来表示递归忽略某个类型的文件。

例如:忽略 doc/ 目录及其所有子目录下的 .pdf 文件:

doc/**/*.pdf

注意事项:

.gitignore 只会忽略那些还没有被 Git 跟踪的文件。如果某个文件已经被提交到 Git 仓库中,它仍然会被版本控制跟踪,即使你在 .gitignore 中指定了忽略。

要停止跟踪已经被跟踪的文件,您需要清除 Git 缓存并重新提交。

停止跟踪已被跟踪的文件

如果某个文件已经被 Git 跟踪,但你修改了 .gitignore 来忽略它,你需要使用以下命令来停止 Git 对这些文件的跟踪:

git rm -r --cached .
git add .
git commit -m 'update .gitignore'

这样会清除 Git 缓存,移除不再需要跟踪的文件。

切换编辑器

描述如何配置 Git 使用不同的文本编辑器进行提交信息编辑。

以将默认编辑器更改为其他文本编辑器,如 EmacsNotepad++

  • 使用 Emacs
$ git config --global core.editor emacs
  • 配置 Notepad++(Windows 示例):
$ git config --global core.editor "'D:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"

多仓库管理账户配置

多个 Git 仓库项目管理不同账户配置的常见步骤。

检查全局用户名和邮箱配置

在 GIt 中,每个提交都需要关联一个用户名和邮箱。可以查看是否已全局配置这些信息:

git config --global user.name
git config --global user.email

如果你需要使用不同的 GIt 账号,可以取消全局配置(如果不想使用默认的账号):

git config --global --unset user.name
git config --global --unset user.email

这样可以避免多个仓库间使用相同的用户名和邮箱。

为每个账户生成不同的 SSH 密钥

为每个 Git 账号生成独立的 SSH 密钥对:

GitHub:

ssh-keygen -t rsa -C "your_email@example.com" -f ~/.ssh/id_rsa.github

Gitee:

ssh-keygen -t rsa -C "your_email@example.com" -f ~/.ssh/id_rsa.gitee

每个命令都会生成不同的 SSH 密钥,分别用于 GitHub 和 Gitee 的身份验证。

将 SSH 密钥添加到 GitHub/Gitee

进入 GitHub 或 Gitee 的账户设置,找到 SSH 密钥配置界面并添加生成的公钥(id_rsa.github.pubid_rsa.gitee.pub)。

创建 config 文件

~/.ssh/ 目录下创建 config 文件,用于指定每个仓库使用的不同 SSH 密钥。配置如下:

# github
Host github.com
HostName ssh.github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa.github

# gitee
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa.gitee
  • Host github.comHost gitee.com 是你在 Git 操作中指定的远程主机。
  • IdentityFile 指定了该仓库应该使用的私钥。

验证 SSH 密钥配置

通过以下命令来验证是否成功配置了 SSH 密钥:

GItHub:

ssh -T git@github.com

Gitee:

ssh -T git@gitee.com

成功连接后,会显示类似 "You've successfully authenticated" 的信息。

为不同仓库配置用户信息

每个仓库都可以有独立的用户信息配置,存储在该仓库的 .git/config 文件中:

[user]
    name = your_name
    email = your_email@example.com

这样每个仓库都可以配置不同的用户名和邮箱,避免全局配置冲突。

Git 相关操作

查看远程仓库

显示当前配置的远程仓库及其 URL:

git remote -v

克隆仓库

克隆方式有很多种,常见的克隆方式有:

HTTP 克隆

使用 HTTPS 协议克隆远程仓库,是最常见的克隆方式,适用于几乎所有支持 Git 的远程服务(如 GitHub、GitLab 等)。

git clone https://github.com/username/repository.git
  • 说明:
    • 不用配置 SSH 密钥,适用于没有配置 SSH 密钥的环境。
    • 但随着安全策略的变化,GitHub 不再允许直接使用用户名和密码进行身份验证,而是使用个人访问令牌。

SSH 克隆

通过 SSH 协议克隆仓库,通常用于安全的认证和访问 Git 仓库。

git clone git@github.com:username/repository.git

说明:

  • 需要配置 SSH 密钥环境。一旦配置,不需要每次推送或拉取手动验证身份。
  • username 是仓库所属的用户名。

例如:

git clone git@github.com:littlekj/helloBlog.git

本地克隆

除了从远程服务器克隆仓库,还可以从本地路径克隆仓库(将本地机器上一个仓库,复制到另外一个位置)。不需要网络连接,因为它直接访问本地文件系统。

通过本地文件路径克隆仓库:

git clone /path/to/repository

拉取仓库

  • 拉取远程仓库中的特定分支到本地,不会自动合并到当前所在的分支:
git fetch origin <branch_name>
  • 将远程分支合并到当前分支:
git merge origin/<branch_name>
  • 或者,直接在拉取时进行合并分支:
git pull origin <branch_name>

git clonegit fetch + git mergegit pull 的区别:

  • git clone
    • 从远程仓库克隆整个项目(包括所有分支和历史记录)到本地。
    • 在本地创建一个与远程仓库相同的新目录,并将所有文件和分支复制到该目录中。
    • 克隆后,你将拥有一个完整的本地仓库副本,可以进行修改、提交和推送。
  • git fetch + git merge
    • git fetch 从远程仓库获取最新的提交和分支信息到本地,但不会自动合并到当前分支。
    • git merge 将远程分支的内容合并到当前分支。
  • git pull
    • 等同于 git fetch + git merge,即先获取远程分支的最新内容,然后将其合并到当前分支。

切换分支

在 Git 中,分支用于记录项目的不同版本或特性。git checkout 命令常用于切换分支或恢复工作区文件。

切换到指定分支:

git checkout branch_name
  • 将切换到已有的 branch_name 分支。

创建并切换到新分支:

git checkout -b build
  • -b 指定一个 build 新分支,新分支是从当前所在的分支上创建的。

更改远程仓库 URL

推送更改到远程仓库,不仅可以用 HTTPS ,而且还可以使用更安全的 SSH 连接。

如果使用远程仓库 SSH 类型的 URL 地址推送,可能需要更改下 URL 地址。

首先,命令查看远程仓库当前 URL 类型:

git remote -v

可以看到类似的 URL:

origin  https://github.com/littlekj/helloBlog.git (fetch)
origin  https://github.com/littlekj/helloBlog.git (push)

选择将远程仓库 URL 更改为 SSH 类型:

git remote set-url origin git@github.com:littlekj/helloBlog.git

然后,使用 SSH 地址推送更改:

git push origin master

注意:如果你的仓库 URL 是 SSH 格式,那么 Git 会默认使用 SSH 密钥来进行身份验证。即使你尝试使用 HTTPS 方式操作,Git 会优先选择 SSH 认证方式(如果配置了 SSH 密钥)。这是因为 Git 会查看仓库的 URL,并使用相应的认证协议。

查看文件状态

查看当前文件状态,确认哪些文件被修改、添加或删除。

git status

跟踪文件和暂存更改

跟踪新文件或将已修改的文件暂存到暂存区:

git add <file>
  • 如果修改后再改动,需重新 git add

递归添加当前目录及其子目录下所有更改的文件:

git add .

查看未暂存的改动:

git diff

查看已暂存但未提交的改动:

git diff --staged

提交更改

提交暂存的更改,并附上提交说明:

git commit -m "提交说明"

跳过 git add,直接提交所有已跟踪文件的更改:

git commit -a

删除文件

从工作目录和暂存区删除文件:

git rm file

仅从暂存区删除,保留文件在本地:

git rm --cached file

重命名文件

重命名文件,并将操作暂存:

git mv oldname newname

推送更改到远程仓库

将本地的改动推送到远程的指定分支:

git push origin branch_name
  • origin 表示推送到你当前设置的远程仓库。它是 Git 默认的远程仓库名称,是一个别名。
  • origin 通常不需要替换为实际的远程仓库地址。除非有同一个本地仓库推送到不同远程仓库的场景。例如:
    • 一个仓库托管在 GitHub 上,另一个托管在 GitLab 上。
    • 在开发和生产环境中,使用不同的远程仓库进行部署。
  • branch_name 是你要推送的本地分支名称。

查看提交历史

查看提交历史记录:

git log

本地仓库添加到远程仓库

初始化本地仓库(如果未初始化)

git init

添加远程仓库

将远程仓库的 URL 添加到本地仓库:

git remote add origin <远程仓库URL>

检查是否添加成功

git remote -v

本地仓库至少有一次提交

如果没有进行过任何提交(即本地仓库为空),git push 命令将会报错,因为没有任何内容可以推送到远程仓库。

添加文件并进行第一次提交:

git add .
git commit -m "Initial commit"

如果没有本地提交的情况下推送,可以使用 --force 强制推送,但这会覆盖远程仓库内容,所以要谨慎使用。

强制推送的命令(谨慎使用):

git push --force origin master

所以,最好在本地有至少一次提交后再进行推送,避免覆盖远程仓库的内容。

推送本地仓库到远程仓库

将本地仓库的内容推送到远程仓库的指定分支(通常 mastermain):

git push -u origin master
  • -u--set-upstream 的缩写。它的作用是将本地的 master 分支与远程仓库 origin 仓库的 master 分支进行关联,并且设置本地分支的默认上游分支。后续,Git 会默认推送或拉取 origin 仓库的 master 分支。

后续推送

以后每次提交更改后,可以直接使用:

git push

Git 提交简易流程

克隆仓库

在本地计算机上克隆远程仓库:

git clone <仓库地址>

说明:

  • 默认情况下,Git 会克隆仓库的默认分支(通常是 mastermain)。
  • 参数选项:
    • --mirror:克隆整个仓库,包括所有的远程分支、所有的 Git 仓库信息和钩子脚本。完全复制仓库。
    • --branches:克隆指定的分支:git clone --branches <分支名> <仓库地址>

创建切换分支

在当前仓库中创建并切换到一个新的分支:

git checkout -b <分支名>

内容修改

在本地修改仓库的文件,进行新增、删除或编辑内容。修改内容并不会自动提交到 Git 仓库,需要通过 git addgit commit 来将这些改动记录下来。

添加更改

将工作目录中的所有更改(新增、修改、删除)添加到暂存区:

git add .

提交更改

将暂存区的更改提交到本地仓库,并附带一条简要的提交说明:

git commit -m "提交的简要说明"

推送更改

将本地分支的更改推送到远程仓库:

git push origin <分支名>

说明:

  • origin 是远程仓库的默认名称。
  • 推送时,确保远程仓库上有一个相同名称的分支,如果没有,可以使用 git push -u origin <分支名> 来创建远程分支。

参考文档

https://book.git-scm.com/book/zh/v2

本文由作者按照 CC BY 4.0 进行授权。