title: Git
date: 2021-06-22 11:37:26
tags: [版本控制, Git]
Git
第一次学习 Git 的时候好像还是 19 年,那时候才刚上大学,才大一下学期,只会用 txt 编写,现在不一样啦,学会了 markdown,所以打算用 markdown 来重新写一篇关于 Git 的使用手册。
概述
Git 是用 C 语言开发的分布式版本控制系统。
分布式和集中式的版本控制系统有什么区别呢?
分布式版本控制系统的代表是 Git。
集中式版本控制系统的代表是 Svm。
集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
分布式版本控制系统根本没有中央服务器,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件 A,你的同事也在他的电脑上改了文件 A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
参考:廖雪峰
Git 基本操作
Git 常用的是以下 6 个命令:git clone、git add 、git commit、git checkout、git push、git pull。
- workspace:工作区(就是你在电脑里能看到的目录)。
- staging area:暂存区/缓存区(存放在
.git
目录下的 index 文件中(.git/index
))。 - local repository:版本库或本地仓库(
.git
目录)。 - remote repository:远程仓库。
本地仓库
什么是本地仓库
就是一个目录中的所有文件(除了 .gitignore
中忽略的文件)都被 Git 管理起来。每个文件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以还原。
什么是 .gitignore
简单的来说,就是在这个文件中申明那些文件你不希望被 Git 管理的文件。github 提供的.gitignore。
初始化本地仓库命令
git init
首先创建一个新的文件夹并进入该文件夹,再执行上述命令。这一步骤会生成一个.git
的目录,这个目录是 Git 来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把 Git 仓库给破坏了。(.git
目录默认是隐藏的)
克隆远程仓库到本地
git clone 不指定分支
git clone <https/ssh> [本地项目名(可选项)]
git clone 指定分支
git clone -b <branchname> <https/ssh> [本地项目名(可选项)]
<branchname>是分支名,<https/ssh> 是拷贝项目的链接。如果你想要一个不一样的名字, 你可以在该命令后加上你想要的名称。
提交与修改
命令 | 说明 |
---|---|
git add <file/.> | 添加文件/所有文件到暂存区。(如需上传目录,目录中必须要有文件) |
git status [-s] | 查看本地仓库当前的状态,显示有变更的文件。-s 参数获得简短的输出结果(-s 是可选项)。 |
git diff | 比较文件的不同。 |
git commit | 提交暂存区到本地仓库。 |
git rm | 删除工作区文件。 |
git mv | 移动或重命名工作区文件。 |
git diff
- 尚未提交到暂存区的改动:git diff
- 查看已提交到暂存区的改动: git diff --cached
- 显示摘要而非整个 diff:git diff --stat
- 可以查看工作区和版本库里面最新版本的区别:git diff HEAD – <file>
git commit
提交暂存区到本地仓库中
git commit -m [message] // [message]可以是一些备注信息,[message]要用引号包裹起来。
提交暂存区的指定文件到本地仓库中
git commit [file1] [file2] ... -m [message] // [message] 可以是一些备注信息。
git rm
git rm 删除文件有以下几种形式:
-
将文件从暂存区和工作区中删除:
git rm <file>
以下实例从暂存区和工作区中删除 runoob.txt 文件:
git rm runoob.txt
-
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f。
强行从暂存区和工作区中删除修改后的 runoob.txt 文件:
git rm -f runoob.txt
-
如果想把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 –cached 选项即可:
git rm --cached <file>
以下实例从暂存区中删除 runoob.txt 文件:
git rm --cached runoob.txt
git mv
git mv 命令用于移动或重命名一个文件、目录或软连接。
git mv [file] [newfile]
如果新文件名已经存在,但还是要重命名它,可以使用 -f 参数:
git mv -f [file] [newfile]
我们可以添加一个 README 文件(如果没有的话):
git add README
然后对其重命名:
git mv README README.md
提交日志
命令 | 说明 |
---|---|
git log | 查看历史提交记录,以便确定要回退到哪个版本。 |
git reflog | 查看历史命令记录,以便确定要回到未来的哪个版本。 |
git blame <file> | 以列表形式查看指定文件的历史修改记录。 |
git log
这个的用法实在是太多了,想详细学习的可见这个链接。
git log
git log --oneline // 查看历史记录的简洁的版本
git log --pretty=oneline // 查看历史记录的简洁的版本(但有完整版本号)
git log --graph // 查看历史中什么时候出现了分支、合并
git log --reverse // 逆向显示日志
git blame <file>
如果要查看指定文件的修改记录可以使用 git blame 命令,格式如下:
git blame <file>
git blame 命令是以列表形式显示修改记录,如下实例:
git blame a.txt
// d3890a1d (WE 2021-06-22 13:32:09 +0800 1) adsasdasdasdd
远程操作
命令 | 说明 |
---|---|
git remote | 远程仓库操作 |
git pull | 下载远程代码并合并 |
git push | 上传远程代码并合并 |
git remote
显示所有远程仓库:
git remote -v
显示某个远程仓库的信息:
git remote show [remote] // [remote] 仓库名
其他相关命令:
git remote rm name # 删除远程仓库
git remote rename old_name new_name # 修改仓库名
git pull
git pull 命令用于从远程获取代码并合并本地的版本。
git pull 其实就是 git fetch 和 git merge FETCH_HEAD 的简写。 命令格式如下:
git pull <远程主机名> <远程分支名>:<本地分支名>
更新操作:
git pull
// 或
git pull origin
将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并。
git pull origin master:brantest
如果远程分支是与当前分支合并,则冒号后面的部分可以省略。
git pull origin master
上面命令表示,取回 origin/master 分支,再与本地的 brantest 分支合并。
git push
git push 命用于从将本地的分支版本上传到远程并合并。
命令格式如下:
git push <远程主机名> <本地分支名>:<远程分支名>
如果本地分支名与远程分支名相同,则可以省略冒号:
git push <远程主机名> <本地分支名>
以下命令将本地的 master 分支推送到 origin 主机的 master 分支。
$ git push origin master
相等于:
$ git push origin master:master
如果本地版本与远程版本有差异,但又要强制推送可以使用 --force 参数:
git push --force origin master
删除主机分支可以使用 --delete 参数,以下命令表示删除 origin 主机的 master 分支:
git push origin --delete master
Git 分支管理
命令 | 说明 |
---|---|
git branch | 查看所有本地分支 |
git branch <branchname> | 创建分支 |
git checkout <branchname> | 切换分支 |
git switch <branchname> | 切换分支 |
git checkout -b <branchname> | 创建分支并切换到该分支 |
git switch -c <branchname> | 创建分支并切换到该分支 |
git branch -d <branchname> | 删除分支 |
git branch -D <branchname> | 强制删除分支 |
git merge <branchname> | 合并分支 |
2.23 前后的变化
操作 | 2.23- | 2.23+ |
---|---|---|
查看所有本地分支 | git branch | git branch |
切换分支 | git checkout <branchname> | git switch <branchname> |
创建分支并切换到该分支 | git checkout -b <branchname> | git switch -c <branchname> |
Git 文件恢复
Git 中文件恢复涉及到两个命令,一个是 checkout,一个是 reset,reset 除了重置分支之外,还提供了恢复文件的能力。
git checkout -- aaa # 从staged中恢复aaa到worktree
git reset -- aaa # 从repo中恢复aaa到staged
git checkout -- HEAD aaa # 从repo中恢复aaa到staged和worktree
git reset --hard -- aaa # 同上
新的 restore 命令专门用来恢复 staged 和 worktree 的文件
git restore [--worktree] aaa # 从staged中恢复aaa到worktree
git restore --staged aaa # 从repo中恢复aaa到staged
git restore --staged --worktree aaa # 从repo中恢复aaa到staged和worktree
git restore --source dev aaa # 从指定commit中恢复aaa到worktree
可以看到 restore 提供 checkout 和 reset 两个命令才能提供的文件恢复能力,也提供了更好的语义。
worktree:工作区。
staged:修改区。(修改过的文件)
HEAD:暂存区。(add 后的文件)
Git 版本回退
git reset 命令用于回退版本,可以指定退回某一次提交的版本。
git reset 命令语法格式如下:
git reset [--soft | --mixed | --hard] [HEAD]
–mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。
git reset [HEAD]
实例:
$ git reset HEAD^ # 回退所有内容到上一个版本
$ git reset HEAD^ hello.php # 回退 hello.php 文件的版本到上一个版本
$ git reset 052e # 回退到指定版本
–soft 参数用于回退到某个版本:
git reset --soft HEAD
实例:
$ git reset --soft HEAD~3 # 回退上上上一个版本
–hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交:
git reset --hard HEAD
实例:
$ git reset --hard HEAD~3 # 回退上上上一个版本
$ git reset --hard bae128 # 回退到某个版本回退点之前的所有信息。
$ git reset --hard origin/master # 将本地的状态回退到和远程的一样
Git 标签管理
命令 | 说明 |
---|---|
git tag <tagname> [commit id] | 打标签(commit id 为可选项,默认为最新提交的commit id) |
git tag | 查看所有标签(以字典序排序) |
git tag -d <tagname> | 删除标签 |
git show <tagname> | 查看标签信息 |
git push origin <tagname> | 推送标签到远程 |
git push origin --tags | 推送全部尚未推送到远程的本地标签 |
因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
git tag
可以创建带有说明的标签,用-a
指定标签名,-m
指定说明文字:
git tag -a v0.1 -m "version 0.1 released" 1094adb
git tag -d
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
git tag -d v0.9
然后,从远程删除。删除命令也是 push,但是格式如下:
git push origin :refs/tags/v0.9
Git 保存与恢复断点
命令 | 说明 |
---|---|
git stash | 把当前工作现场储藏起来,等以后恢复现场后继续工作 |
git stash list | 查看断点列表 |
git stash apply | 恢复断点前的状态 |
git stash drop | 删除断点 |
git stash pop | 恢复断点前的状态并删除断点 |
git stash
你可以多次 stash,恢复的时候,先用git stash list
查看,然后恢复指定的 stash,用命令:
git stash apply stash@{0}
Git 一些小技巧
命令 | 说明 |
---|---|
git cherry-pick <版本号> | 复制一个特定的提交到当前分支 |
git rebase | 可以把本地未push的分叉提交历史整理成直线 |
Git 自定义
git config --global alias.GitName 'XXX' //GitName 的作用为 XXX
可以通过 GitName 来调用 XXX
推荐:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"