git使用指南
参考链接:
- git book,官方说明文档
- 廖雪峰git教程,通俗易懂的讲解
- Learn Git Branching,快速学习git的通关游戏
以下是正文:
git是什么
git是目前应用最广泛的分布式版本控制系统,主要用来进行文本文件的版本管理(不支持word文件,因为word文件是二进制形式),可以在本地或远程保存文件的每一次修改,可用于团队的协作开发。
-
本地版本控制
为了解决本地文件更新迭代需要复制大量副本以及无法快速查找具体修改的问题而提出,大多采用简单的数据库来记录文件的历次更新差异。主要针对个人使用,无法方便地进行多人合作。 -
集中式版本控制
主要解决的是多个开发者协同工作的问题。这类系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,协同工作的人需要连接这台服务器进行文件的提取和更新。
缺点包括:服务器的单点故障,当服务器出现故障时,其他用户无法进行工作,并且可能会造成数据的丢失。此外,每次工作都需要联网提取最新的工作进度,否则无法开始。 -
分布式版本控制
每个客户端都是完整仓库的镜像,包括完整的历史记录,并不需要一个单一的服务器,这也避免了单点故障造成的损失。
但实际上,分布式版本控制系统通常也存在一台充当“中央服务器”的电脑,它仅用于方便“交换”大家的修改。如GitHub提供的免费的git服务,企业内部自己搭建的git服务器。
git相关概念
工作区和版本库,版本库包括暂存区和git目录。工作区就是本地的文件夹,而版本库就是.git,可以使用git对工作区的每个文件的修改、删除等操作进行跟踪。
-
工作区
就是电脑里可以看到的目录,不包括.git隐藏目录。 -
暂存区
暂时存储要提交的一个或多个文件。
-
git目录
存储该仓库所有已提交的修改,树的结构。
git常用命令
本地命令
创建版本库
git init
在一个空的文件夹或者非空文件夹执行以上命令,就可以在当前文件夹中创建一个版本库(仓库)。
向版本库中添加文件
git add <filename>
将某文件从工作区添加到版本库的暂存区。
--> git add多个文件和文件夹操作git commit -m "note text"
用于将暂存区中的所有修改记录提交到本地git目录中,-m选项用于添加一些注释文本,方便自己和其他人查看。
版本管理(回退、撤销修改、删除等)
git status
查看版本库当前的状态。git diff <filename>
查看工作区的文件与上次提交后的文件有何区别,发生了哪些修改。
或者可以使用git diff HEAD -- <filename>
。
版本回退
git reset --hard commit_id
撤销已提交的修改
将当前版本设置为commit_id指向的记录,即让HEAD指针指向该条记录。commit_id也可以写成HEAD^(表示上一个版本),或者HEAD~n(表示往回退n个版本)。直接在分支上回退,但不支持远程分支的更改。git log
可以查看提交的历史记录。可以提供穿梭到过去时需要的commit_id。
使用--pretty=oneline
可以使输出中的每条记录简化为一行内容。
使用--graph --pretty=oneline --abbrev-commit
可以图形显示分支的情况。git reflog
该命令记录git的每一次命令,可以提供回到未来时需要的commit_id。git revert commit_id
实际上是重新提交一个到回退目标的修改,这种撤销方式支持远程分支,不影响之前已提交的内容。commit_id也可以换成HEAD^以及HEAD~n。
撤销修改
git checkout -- <filename>
撤销工作区的修改
撤销该文件在工作区的所有修改,如果已添加到暂存区(add),那么就回到与暂存区相同的状态;如果没有添加到暂存区,那么就回到和git目录中相同的状态(上次commit)。
该命令实际上是用版本库中的版本替换工作区的版本。当工作区中的文件被误删后还可以使用这条指令进行还原。git reset HEAD <filename>
撤销暂存区的修改
可以撤销暂存区的该文件的修改,并放回到工作区。此时再使用上条命令就可以把工作区中的修改也撤销。- 撤销git目录的修改,即版本回退。
删除文件
git rm <filename> + git commit -m "message"
从版本库中删除文件。
分支管理
创建\转换分支
git branch
查看分支。带星号的为当前分支。git branch <branchname>
创建分支。git checkout <branchname>
git switch <branchname>
切换分支。git checkout -b <branchname>
git switch -c <branchname>
创建并切换分支。git branch -f <source> <destination>
强制修改分支位置。
合并分支
git merge <branchname>
将参数branch合并到当前分支上git merge --no-ff -m <message> <branchname>
优先使用,可使master稳定
使用--no-ff选项表示禁用Fast forword(直接移动指针完成合并),此时在合并时会产生一个新的提交,可以使用-m选项添加注释文字。
git rebase <branchname>
rebase的作用就是使提交的记录合并为一条直线,按照提交的先后顺序。
git rebase -i HEAD~n
针对当前分支的最新的n条记录,交互式复制(有可视化弹窗),并可进行排序,也可指定哪些记录不需要复制。
删除分支
git branch -d <branchname>
以上命令可以删除已合并的分支。
如果要强制删除未合并的分支,可以使用选项-D
。
工作现场的保存和恢复
当存在场景如下:正在自己的分支上进行代码编写,突然要求改一个bug,需要创建一个新的分支进行修复,那么当前的分支上的工作由于还未完成,无法提交,那么如何对其进行保存呢。
git stash
该命令可以保存当前分支的工作现场。git stash list
查看工作现场。git stash apply
+git stash drop
apply指令可以恢复之前保存的现场,但是不能删除保存的内容,需要再用drop命令删除。
可以stash多次,那么恢复时apply后加stash编号即可,如stash@{0}
。git stash pop
在恢复的同时也可以删除stash中的内容。
复制某个提交到某个分支
git cherry-pick <commit_ids>
复制提交记录到当前分支。
提交记录的标签
git tag <tagname> <commit_id>
向commit_id打标签tagname,如果不指定commit_id,那就是打在当前分支的最新的提交上。
带有说明的标签,使用-a
跟标签号,-m
跟解释文字。git tag
查看标签。git show <tagname>
查看说明文字。git describe <ref>
<ref>可以是任何能被Git识别成提交记录的引用,如果你没有指定的话,Git会以你目前所检出的位置(HEAD)为参考点。
它输出的结果是这样的:
<tag>_<numCommits>_g<hash>
tag表示的是离ref最近的标签,numCommits是表示这个ref与tag相差有多少个提交记录,hash表示的是你所给定的ref所表示的提交记录哈希值的前几位。git tag -d <tagname>
删除标签。git push origin <tagname>
推送标签到远程。git push origin --tags
一次性推送所有未推送的标签到远程。git push origin :refs/tags/<tagname>
删除远程的标签,前提是本地的标签已经删除-d。
远程命令
本地与远程仓库的初始化关联/删除关联
git remote add origin git@github.com:yourname/repo-name.git
将GitHub仓库与本地已有的仓库关联。git remote -v
查看远程库的信息。git remote rm <repo-name>
实际上是删除远程仓库与本地仓库之间的关联,并没有物理删除远程库。
克隆远程库
先创建远程库,然后从远程库克隆生成本地的仓库
git clone git@github.com:yourname/repo-name.git
给定远程库的地址,然后克隆到本地。
远程分支和本地分支
git checkout -b <branchname> origin/<branchname>
本地无对应分支,创建与远程仓库的某分支关联的本地分支。git branch --set-upstream-to=origin/<branchname> <branchname>
本地有对应分支,设置本地分支与远程分支的链接。
抓取分支
git fetch
从远程仓库下载本地仓库中缺失的提交记录,仅更新远程分支指针,但并不会改变本地仓库的状态。git pull
git pull --rebase
拉取当前分支的更新的记录,使本地与远程同步。
=git fetch + git merge
=git fetch + git rebase
推送分支
git push
git push -u origin <source>:<destination>
-u选项不仅会把本地的分支内容推送到远程的分支,还会把本地的分支与远程的分支关联起来,在之后的推送和拉取时就可以简化命令。
在已关联的分支上进行推送时,无需使用-u选项。
origin表示仓库的默认名,source为本地的分支名,destination为远程的分支名,如果两者相同则可以只写一个,无需冒号。