# Git

Git 是一个分布式版本控制系统，它的目标是速度，数据完整性和可扩展性。Git 是免费软件，遵循 GNU 通用公共许可证版本 2（或更高版本）发布

下面是一些和Git相关的软件包
| 软件包              | 命令                  | 说明                    |
|------------------|---------------------|-----------------------|
| git              | git(7)              | Git 快速、可扩展、分布式的版本控制系统 |
| gitk             | gitk(1)             | 有历史功能的 Git 图形仓库浏览器    |
| git-gui          | git-gui(1)          | Git 图形界面（无历史功能）       |
| git-email        | git-send-email(1)   | 从 Git 用电子邮件发送收集到的补丁   |
| git-buildpackage | git-buildpackage(1) | 用 Git 自动制作 Debian 包   |
| dgit             | dgit(1)             | Debian 档案库的 git 交互操作  |
| imediff          | git-ime(1)          | 交互式的分开 git 提交的辅助工具    |
| stgit            | stg(1)              | 封装的 git (Python)      |
| git-doc          | N/A                 | Git 官方文档              |
| gitmagic         | N/A                 | "Git 魔术"，易于理解的 Git 手册 |

## 配置 Git 客户端

你可以在 "`~/.gitconfig`" 里面设置几个Git接下来需要使用的全局配置，比如说你的名字和电子邮件地址。

```Shell
git config --global user.name "Name Surname"
git config --global user.email yourname@example.com
```

你也可以按如下所示定制 Git 的默认行为。

```Shell
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global push.default current
```

如果你习惯使用 CVS 或 Subversion 命令，你也许希望设置如下几个命令别名。

```Shell
git config --global alias.ci "commit -a"
git config --global alias.co checkout
```

你能够通过如下方式检查你的全局配置：

```Shell
git config --global --list
```

当然你也可以为每个项目单独设置配置，这样的话，你就可以在不同的项目中使用不同的用户名和电子邮件地址了，只需要在项目的根目录下运行上面的命令（去掉--global）即可。

## 基本的 Git 命令

Git 操作涉及几个数据。

- 工作树目录保持面向用户的文件，你可以对它们做出改变。
  - 需要被记录的改变，必须明确的被选择并暂存到索引。这是 git add 和 git rm 命令。
- 索引保持暂存文件。
  - 在接下来的请求之前，暂存文件将被提交到本地仓库。这个是 git commit 命令。
- 本地仓库保持已经提交的的文件。
  - Git 记录提交数据的链接历史并在仓库里面将它们作为分支组织。
  - 本地仓库通过 git push 命令发送数据到远程仓库。
  - 本地仓库能够通过 git fetch 和 git pull 命令从远程仓库接收数据。
    - git pull 命令在 git fetch 后执行 git merge 或 git rebase 命令。
    - 这里，git merge 联合两个独立分支的历史结尾到一个点。（在没有定制的 git pull ，这个是默认的，同时对上游作者发布分支到许多人时，也是好的 ）
    - 这里，git rebase 创建一个远程分支的序列历史的单个分支，跟着本地分支。（这是定制 pull.rebase true 的情况，对我们其余的用途有用。）
- 远程仓库保持已经提交的文件。
  - 到远程仓库的通信，使用安全的通信协议，比如 SSH 或 HTTPS。

工作树是在 .git/ 目录之外的文件。在 .git/ 目录里面的文件，包括索引、本地仓库数据和一些 git 配置的文本文件。

这里是主要的 Git 命令概览。

| Git 命令                         | 功能                                     |
|--------------------------------|----------------------------------------|
| git init                       | 创建(本地)存储库                              |
| git clone URL                  | 克隆远程存储库到本地仓库工作目录树                      |
| git pull origin main           | 通过远程仓库 origin 更新本地 main 分支             |
| git add .                      | 增加工作树里面的文件仅作为预先存在的索引文件                 |
| git add -A .                   | 增加工作树里面的所有文件到索引（包括已经删除的）               |
| git rm filename                | 从工作树和索引中删除文件                           |
| git commit                     | 提交在索引中的暂存改变到本地存储库                      |
| git commit -a                  | 添加工作树里的所有的改变到索引并提交它们到本地仓库（添加 + 提交）     |
| git push -u origin branch_name | 使用本地 branch_name 分支更新远程仓库 origin（初始启用） |
| git push origin branch_name    | 使用本地 branch_name 分支更新远程仓库 origin（随后调用） |
| git diff treeish1 treeish2     | 显示 treeish1 提交和 treeish2 提交的不同         |
| gitk                           | VCS 存储库分支历史树的图形界面显示                    |

## Git技巧

| Git 命令行                                                                    | 功能                                                    |
|----------------------------------------------------------------------------|-------------------------------------------------------|
| gitk --all                                                                 | 参看完整的 Git 历史和操作，比如重置 HEAD 到另外一个提交、挑选补丁、创建标签和分支……      |
| git stash                                                                  | 得到一个干净的工作树，不会丢失数据                                     |
| git remote -v                                                              | 检查远程设置                                                |
| git branch -vv                                                             | 检查分支设置                                                |
| git status                                                                 | 显示工作树状态                                               |
| git config -l                                                              | 列出 git 设置                                             |
| git reset --hard HEAD; git clean -x -d -f                                  | 反转所有工作树的改变并完全清理它们                                     |
| git rm --cached filename                                                   | 反转由 git add filename 改变的暂存索引                          |
| git reflog                                                                 | 获取参考日志（对从删除的分支中恢复提交有用）                                |
| git branch new_branch_name HEAD@{6}                                        | 从 reflog 信息创建一个新的分支                                   |
| git remote add new_remote URL                                              | 增加一个由 URL 指向的远程仓库 new_remote                          |
| git remote remove origin                                                   | 移除远程仓库origin                                          |
| git remote rename origin upstream                                          | 远程仓库的名字从 origin 重命名到 upstream                         |
| git branch -u upstream/branch_name                                         | 设置远程跟踪到远程仓库 upstream 和它的分支名 branch_name。              |
| git remote set-url origin https://foo/bar.git                              | 改变 origin 的 URL                                       |
| git remote set-url --push upstream DISABLED                                | 禁止推送到 upstream（编辑 .git/config 来重新启用）                  |
| git checkout -b topic_branch ; git push -u topic_branch origin             | 制作一个新的 topic_branch 并把它推送到 origin                     |
| git branch -m oldname newname                                              | 本地分支改名                                                |
| git push -d origin branch_to_be_removed                                    | 删除远程分支（新的方式）                                          |
| git push origin :branch_to_be_removed                                      | 删除远程分支（老的方式）                                          |
| git checkout --orphan unconnected                                          | 创建一个新的 unconnected 分支                                 |
| git fetch upstream foo:upstream-foo                                        | 创建本地（可能是孤立的）upstream-foo 分支，作为upstream 仓库 foo 分支的一个拷贝 |
| git rebase -i origin/main                                                  | 从 origin/main 重新排序、删除、压缩提交到一个干净的分支历史                  |
| git reset HEAD^; git commit --amend                                        | 压缩最后两个提交为一个                                           |
| git checkout topic_branch ; git merge --squash topic_branch                | 压缩整个 topic_branch 到一个提交                               |
| git fetch --unshallow --update-head-ok origin '+refs/heads/*:refs/heads/*' | 反转一个浅克隆到一个所有分支的完整克隆                                   |
| git ime                                                                    | 分开最后的提交到一系列单个逐一文件的小提交。（要求 imediff）                    |
| git repack -a -d; git prune                                                | 本地仓库重新打包到一个单独的包中（这可能限制从删除分支里面恢复丢失数据等机会）               |

::: danger 警告
⚠️ 不要使用带空格的标签字符串。即使一些工具，如 gitk(1) 允许你使用它，但会阻碍其它 git 命令。
:::

::: warning 注意
如果一个本地分支推送到一个已经变基或者压缩过的仓库，推送这样的分支有风险，并要求 --force 选项。这通常对 main 分支来说不可接受，但对于一个移植到 main 分支前的特定分支，是可以接受的。
:::

::: tip
如果有一个可执行文件 git-foo 在路径环境变量 $PATH 里面,在命令行输入没有中划线的 "git foo"，则将调用 git-foo.这是 git 命令的一个特性。
:::

## Git参考资料

[Git - 简明指南](https://rogerdudler.github.io/git-guide/index.zh.html)  「推荐」

[Git - 官方文档](https://git-scm.com/doc)

[Git - 官方手册](https://git-scm.com/docs)

[廖雪峰老师博客](https://www.liaoxuefeng.com/wiki/896043488029600) 「推荐」

## GitHub

[GitHub - 官方网站](github.com)

GitHub是一个面向开发者的基于Web的Git版本控制仓库托管服务。它提供了分布式版本控制和源代码管理（SCM）功能，使开发者能够在全球范围内共同协作编写代码和协同开发项目。

在GitHub上，开发者可以创建存储库（repository）来存储其代码和其他项目文件，并与其他开发者共享和协作。GitHub还提供了一系列工具和功能，包括问题跟踪、代码审核、项目管理、团队协作、持续集成和部署等，以帮助开发者更有效地开发和管理项目。

GitHub还是一个开源社区，许多项目都是开放源代码的。这使得开发者可以访问和使用其他人的代码，了解其他人的代码实践，并在这些项目上进行贡献和协作。由于其广泛的社区和丰富的功能，GitHub已成为开发者社区的重要组成部分，并被广泛用于开源和商业项目的协作和管理。

deepin的开发者们也在GitHub上开发和维护着deepin的各个项目，欢迎大家加入我们的开发者社区。
[github上的linuxdeepin](https://www.github.com/linuxdeepin)
