道破——Git Bash

1. 原理

Git是一个基于快照的分布式版本控制系统,通常用于代码版本控制。

在使用上需了解工作区暂存区本地仓库远程仓库,尤其是分支的概念。

工作区暂存区本地仓库分支是组成一个本地计算机代码版本控制中最核心的功能。

远程仓库是为保证不同时间、不同地点的开发人员协同工作,保证代码数据安全、分布式部署在不同机房的系统, 类似GitHub、GitLab、Gitee等开放托管站点,也可以是自己公司内部搭建的私有托管服务。

一个简单且完整的项目代码版本控制流程:

  1. 提交: 从初始化git init开始,对工作区文件的修改通过git add加入暂存区, 通过git commit提交到本地仓库,再通过git push提交到远程仓库

  2. 获取: 从远程仓库通过git clone克隆一份完整相同的项目代码副本到本地仓库, 通过git pull拉取远程仓库中项目代码的所有修改。

  3. 项目代码版本控制通过分支快照实现。 项目代码第一次提交到本地仓库需要创建或指定一个主分支main,也就是发行版分支, 以后创建的每个分支都是从指定的任意分支拷贝, 通过创建不同的分支,可以实现项目开发中不同开发小组的协同工作, 一个项目被分成"功能A"分支"功能B"分支"功能C"分支等等, 最后通过git merge将测试好的功能代码合并到发行版分支。 在本地仓库每一次git commit都生成一个版本快照, 并且通过索引实现保留多个提交版本的变更历史记录。 分支快照非常符合多元宇宙的概念。

访问 Git CheatSheet ,大致了解一下Git的工作原理。

也可访问 Git Book ,下载Pro git这本书,书中有超级详细的讲解。

2. 安装

前往 Git官网 下载最新版安装包,
一般情况下,安装步骤都选默认即可。

3. 常用命令

3.1. 配置本地用户信息

对你的commit操作设置关联的用户名

1
git config --global user.name "[name]"

对你的commit操作设置关联的邮箱地址

1
git config --global user.email "[email address]"

启用有帮助的彩色命令行输出

1
git config --global color.ui auto

3.2. 创建仓库

当着手于一个新的仓库时,你只需创建一次。要么在本地创建,然后推送到 GitHub;要么通过 clone 一个现有仓库。

在使用过 git init 命令后,使用以下命令将本地仓库与一个 GitHub 上的空仓库连接起来:

1
git init

将现有目录转换为一个 Git 仓库

1
git remote add origin [url]

Clone(下载)一个已存在于 GitHub 上的仓库,包括所有的文件、分支和提交(commits)

1
git clone [url]

3.3. 分支操作

分支是使用 Git 工作的一个重要部分。你做的任何提交都会发生在当前“checked out”到的分支上。使用 git status 查看那是哪个分支。

创建一个新分支

1
git branch [branch-name]

切换到指定分支并更新工作目录(working directory)

1
git switch -c [branch-name]

将指定分支的历史合并到当前分支。这通常在拉取请求(PR)中完成,但也是一个重要的 Git 操作。

1
git merge [branch]

删除指定分支(-D属于强制执行)

1
2
git branch -d [branch-name]
git branch -D [branch-name]

查看本地分支

1
git branch

查看远程分支

1
git branch -r

拉取远程分支

1
2
git checkout -b 本地分支 origin/远程分支
git pull origin 远程分支 

列出当前分支的版本历史

1
git log

列出文件的版本历史,包括重命名

1
git log --follow [file]

展示两个分支之间的内容差异

1
git diff [first-branch]...[second-branch]

3.4. 文件处理

将文件进行快照处理用于版本控制

1
git add [file]

将文件从Git仓库中删除,文件也一起删除,如果文件已经add到暂存区,加-f参数强制删除

1
2
git rm [file]
git rm -f [file]

将文件从Git仓库中删除,但仍想保留在当前工作目录中

1
git rm --cached [file]

查看即将提交的内容

1
git diff --cached

如果没有--cached,将显示尚未添加到索引中的任何更改

获得当前仓库状态

1
git status

将文件快照永久地记录在版本历史中

1
git commit -m "[descriptive message]"

输出指定commit的元数据和内容变化

1
git show [commit]

严重危险操作,需考虑数据丢失的后果。

撤销所有 [commit] 后的的提交,在本地保存更改

1
git reset [commit]

放弃所有历史,改回指定提交。

1
git reset --hard [commit]

3.5. 同步仓库

查看远程仓库地址

1
git remote -v

添加远程仓库地址,aliasname为别名,
以后可以替代URL直接用,如果不指定aliasname,默认命名为origin

1
git remote add aliasname https://github.com/xxx/xxx.git

在本地为远程仓库的别名换个名

1
git remote rename aliasname newaliasname

在本地不再使用并删除指定远程仓库

1
2
git remote remove aliasname
git remote rm aliasname

查看origin仓库的更多信息

1
git remote show origin

如果想拉取origin仓库中有但你没有的信息

1
git fetch origin

拉取远程仓库的更新 git pull是git fetch和git merge的结合

1
git pull

将所有本地分支提交上传到origin仓库

1
git push

将本地当前分支提交上传到origin仓库main分支, 注意每一次上传到新指定的分支都要加-u参数, 以后再上传到同一分支就直接git push就可以了。 -u就相当于指定默认的仓库地址和分支。

1
git push -u origin main

3.6. 标签操作

查看已有的所有标签

1
git tag

查看指定匹配已有的所有标签

1
git tag -l "v1.0.*"

创建标签(轻量标签和附注标签)

1
2
git tag v1.0
git tag -a v1.0 -m "Release 1.0"

查看标签信息

1
git show v1.0

如果以前提交的版本忘打标签了,可以后期打标签

1
2
3
4
5
6
7
8
9
git log --pretty=oneline

15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added commit
4682c3261057305bdd616e23b64b0857d832627b added todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write

以上列出了提交历史,你需要在命令的末尾指定提交的校验和(或部分校验和)。

1
git tag -a v0.5 6d52a27

推送指定标签

1
git push origin tagname

推送所有标签

1
git push origin --tags

删除本地仓库指定标签

1
git tag -d tagname

删除远程仓库指定标签

1
git push origin --delete tagname

从远程仓库拉取标签

1
git checkout tagname

但这样有一个问题就是远程仓库的标签是不建议修改的,修改后默认提交到远程仓库,远程仓库的标签也不会发生变化,建议直接从远程仓库拉取标签到本地并创建一个新分支,想提交再打新标签。

1
git checkout -b newbranch tagname

4. .gitignore 文件

有时一些文件最好不要用 Git 跟踪。这通常在名为.gitignore的特殊文件中完成。

你可以在 github gitignore 找到有用的 .gitignore 文件模板。

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

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 忽略所有的 .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

5. ssh key

ssh key是一对密钥(公钥/私钥),用于通过ssh的方式免密提交到远程仓库。

生成新的ssh key

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

一路回车即可。

6. 完整的例子

创建一个新项目并提交到远程仓库。

1
2
3
4
5
6
7
8
mkdir my-project
cd my-project
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/xxx/my-project.git
git push -u origin main

将已存在的项目提交到远程仓库。

1
2
3
4
cd my-project
git remote add origin https://github.com/xxx/my-project.git
git branch -M main
git push -u origin main

从远程仓库拉取一个项目到本地。

1
2
3
git clone https://github.com/xxx/my-project.git
cd my-project
ls

7. 参考

Git 介绍

Git Docs

Git Cheat Sheets

Git Commands

Git Book