文章

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 的设置界面:

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/

忽略特定目录但保存目录结构

subdir/*
!subdir/.gitkeep
  • subdir/* 忽略目录中的所有文件。
  • subdir/.gitkeep 添加一个特殊的空文件 .gitkeep 以保留目录结构。

忽略特定目录下的文件

你可以指定 .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 平台(如 GitHub、Gitee、GitLab 等),并拥有不同的账号。为了确保提交记录正确归属,并避免权限冲突,我们需要为每个平台配置独立的 Git 账号和 SSH 密钥。

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

Git 每次提交都会绑定一个用户名和邮箱。首先可以查看当前是否设置了全局配置:

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

如果你希望不同项目使用不同账号,建议取消全局设置,以避免所有仓库都使用同一个默认账号。

取消全局配置命令:

git config --global --unset user.name
git config --global --unset user.email
  • 取消后,你必须为每个项目单独配置本地用户名和邮箱,否则提交记录将无法识别身份信息。

为不同仓库配置独立用户信息

每个 Git 仓库都可以有自己的用户名和邮箱,这些信息保存在该仓库的 .git/config 文件中,例如:

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

设置本地配置命令(不加 --global):

cd path/to/your/repo
git config user.name "YourName"
git config user.email "your@email.com"

>推荐做法:根据项目用途(工作 / 个人)分别配置,确保每次提交都能显示正确的身份。

为每个平台生成独立的 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/ 目录下生成两个私钥文件和对应的公钥文件(.pub)。不同的 SSH 密钥分别用于 GitHub 和 Gitee 的身份验证。

添加 SSH 公钥到对应平台账户

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

配置 SSH Config 文件

编辑 ~/.ssh/config 文件,指定不同主机使用不同的密钥:

# GitHub
Host github.com
    HostName ssh.github.com
    Port 22
    User git
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa.github

# Gitee
Host gitee.com
    HostName gitee.com
    Port 22
    User git
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa.gitee
  • 确保 Host 名称与远程仓库地址一致(如 git@github.com:username/repo.git)。
  • 如果使用代理或非标准端口,调整 Port 配置。
  • IdentityFile 指定了该仓库应该使用的私钥。

验证 SSH 密钥配置

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

GItHub:

ssh -T git@github.com

Gitee:

ssh -T git@gitee.com

如果看到类似如下提示,则表示连接成功:

Hi YourName! You've successfully authenticated, but GitHub does not provide shell access.

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 允许从远程仓库拉取更新,可以通过以下命令操作:

拉取特定分支(git fetch

git fetch 从远程仓库获取最新的提交和分支信息到本地,但不会自动合并到当前分支:

git fetch origin <branch_name>
  • 功能:获取远程仓库的更新,不会自动合并,适用于你希望先查看远程更新内容后再决定是否合并的情况。

合并远程分支(git merge

在使用 git fetch 拉取更新后,使用 git merge 将远程分支的内容合并到当前分支:

git merge origin/<branch_name>
  • 功能:手动合并远程分支的内容到本地当前分支,可以在此过程中解决合并冲突。

拉取并自动合并(git pull

git pullgit fetchgit merge 的等同操作,先从远程仓库拉取最新的提交,然后自动将其合并到当前分支:

git pull origin <branch_name>
  • 功能:拉取并合并远程仓库的更新,适用于需要自动合并的场景。

  • 注意:如果本地工作区有未提交的更改,合并时可能会发生冲突,需手动解决。

git clonegit fetch + git mergegit pull 之间的区别:

  • git clone:从远程仓库克隆整个项目到本地,适用于首次获取项目时。
  • git fetch + git merge:从远程获取更新,但不自动合并,适用于需要手动控制合并过程的情况。
  • git pull:执行 git fetchgit 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 仓库很大时,下载整个仓库的所有历史可能会很耗时和占用大量磁盘空间。可以使用浅克隆,只克隆最新的提交。这样能显著减少下载的时间和大小。

git clone 使用 --depth 参数进行浅克隆:

git clone --depth 1 <repository_url>
  • 这样,只会下载最新的提交,并且不包括历史提交。你可以使用 --depth <n> 来指定克隆的历史提交记录数量。

浅克隆的 git fetch 使用

你可以通过 git fetch 拉取远程更新并指定 --depth 来进行浅克隆。注意,git fetch 本身并不会进行工作区的更新,它只会更新远程仓库的提交和分支信息。

git fetch --depth=1 origin master
  • 使用 --depth 参数进行浅克隆(只获取指定数量的历史提交)。git fetch 仅更新本地的 Git 对象,并不会改变当前工作区的内容。

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 进行授权。