本文是本人技术文档的处女作,有很多不足之处还望包涵。
本文分为以下几个part食用,从概念到操作,让你Git技能点upupup~~
- 什么是Git
- Git的重要概念
- Git的基本使用
- 撤销与版本回退
- 分支管理
- stash的使用
Part1—什么是Git?
Git是一个分布式版本控制系统,分布式版本控制系统最大的特点就是没有一台“中央服务器”,每一台电脑都可以拥有一个完整的版本库,也正因为如此,当你工作的时候并不需要联网,你可以在自己的电脑上尽情码代码,只要在有网络的时候推送到云端上即可。
Git因其分布式特点而具有较高的安全性。因为每个人的电脑上都有一个完整的版本库,哪怕有一台电脑上的版本库不见了也不必惊慌,因为还可以在另一台电脑上找到啊~
Git虽然说没有“中央服务器”管理所有版本,但是在使用Git时,却有一台充当“中央服务器”角色的设备,这台服务器只是为了方便大家提交修改,不起其他作用,没有这台设备也可以正常工作,只是大家提交修改不方便。
好了,大概了解了什么是Git之后,我们开始正式学习使用Git,但是在此之前,让我们先弄清楚Git中非常重要的几个概念吧😎
Part2—Git的重要概念
在Git中,有工作区、暂存区、版本库及远程仓库这四个非常重要的概念,可以说你在使用Git时,一切指令都是围绕着这“两区两库”。因此,弄懂它们对掌握使用Git来说是必须的哟!
现在,让我们逐一攻破它们吧😉~
1️⃣工作区(workspace)。工作区指的是你电脑中你所看到的文件夹,例如,我在本地新建了一个vue_study的文件夹,这个vue_study就是一个工作区。我可以在这个工作区中新建文件,进行我的工作。
2️⃣版本库(repository)和暂存区(stage/index)。当你使用Git管理你的版本时,在你的工作区中可以看到一个 .git 的隐藏文件夹,这个隐藏的文件夹不属于工作区,而是Git的一个版本库,这个版本库包含着很多东西,其中最重要的一个概念就是 暂存区 。当你创建一个版本库时,会自动创建一个mater分支,这个master分支也在.git版本库中,.git中还包含了指向mater分支的HEAD指针。(请注意,HEAD指针并不总是指向master分支的,而是指向当前所在的分支。)
从以下这幅图中,也可以更直观的看出工作区、暂存区、版本库之间怎么工作的。我们使用Git时,首先在工作区完成我们的工作代码,然后把本地修改过的代码提交到版本库中。把本地代码提交到版本库中需要两个步骤:1. 首先将本地的修改添加到暂存区中(git add),2. 从暂存区中再把所有更改提交到当前分支(git commit)。
3️⃣远程仓库。远程仓库是位于远程服务器上的版本库,例如github就是Git的一个远程仓库。在远程服务器上管理着你的所有版本,当你本地的代码丢失时,你可以很便捷地从远程仓库再一次获取你的版本库到本地。
Part3—Git的基本使用
现在,让我们真正开始使用Git来管理我们的代码吧~
- 当我们第一次使用Git时,如何让本地的工作区托管给Git控制呢?
我们只需要一个简单的命令,就可以将本地的目录变成Git可以管理的仓库:
我们在终端下进入本地的目录,然后执行git init
,就可以将本地工作区变为Git仓库。
像这样,vue_study已经托管给git啦。
- 如果你想从远程仓库(如github、gitee)下载一个项目到本地,则可以使用
git clone [url]
。 [url]为项目的地址。 - 将本地修改过的文件添加到暂存区:
git add <fileName>
,如果要将本地所有的修改都添加到暂存区,则使用git add .
。 - 将暂存区保存的修改提交到当前分支:
git commit -m "[message]"
。[message]
表示的是本次提交所添加的备注,你可以添加任何备注,不过为了便于管理,最好还是添加有意义的备注,方便后续查看自己每次提交都做了什么。
使用
git commit -a
可以直接把工作区的修改提交到当前分支上。
- 如果你想把自己的项目上传到github,在你第一次使用github时,首先你需要关联一个github仓库:
git remote add origin git@github.com:<github账户/repo-name.git>
,然后将本地版本库推送到远程仓库:git push -u origin master
。
在第一次推送master分支时,加上-u参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令,直接
git push
就可以把本地版本库推送到远程仓库。
origin是远程仓库的名字,远程仓库的名字可以自定义,但是在Git中origin代表远程仓库是一件约定俗成的事情。
- 当你多次提交后,想要查看自己的提交历史,可以使用:
git log
,如果想要查看简介版的历史记录,可以使用
git log --pretty=oneline
- 查看当前工作区中的状态:
git status
- 如果git status告诉你有文件被修改过,查看修改内容:
git diff
part3—撤销与版本回退
在本文的第二部分介绍了一些git的基本使用,但是在实际操作中,我们经常会需要撤销某些修改或者是找回某个版本。在这一个part将进行相关操作的介绍。
撤销修改
- 某个文件还没有添加到暂存区,且在工作区进行了修改。这种情况下想要撤回工作区的修改,使用:
git checkout -- <file>
。这个时候撤销修改后,工作区会回到和版本库一模一样的状态。 - 某个文件已经添加到暂存区了,并且在工作区进行了修改,想要撤回工作区的修改,使用:
git checkout -- <file>
。撤销修改后,工作区会回到最近一次add
或commit
时的状态。 - 想要撤回已经添加到暂存区的修改,使用:
git reset HEAD <file>
,这会将已经add进暂存区的修改撤销到工作区,文件从staged状态变为unstaged状态。
删除文件
在工作区删除文件也是一种修改,是可以使用git status查看到修改状态的
- 删除工作区的文件:鼠标右键直接删除或者使用命令
rm <file>
进行文件删除。 - 删除版本库中的某个文件:
git rm <file>
, 然后提交删除:git commit -m ""
- 如果不小心删除了工作区的某个文件,不要惊慌,我们还可以从版本库中找回来:
git checkout -- <file>
。这是因为删除也是一种修改,所以我们可以使用这条命令进行撤销修改的操作。
请注意,如果某个文件从未被添加到版本库就被删除了,那么很遗憾的告诉你,你再也找不回来啦~所以,要记得不时地把修改提交到版本库哦
版本回退
如果想要回到历史提交的某个版本,只需要进行两步操作,首先使用git log
查找你想要回退的那个版本的commit_id,
如图所示,commit后面那一长串字符串就是你每次所提交到版本库时对应的commit_id,说通俗点,我们可以理解为当前所提交版本所对应的“版本号”。找到版本号后,使用
git reset --hard <commit_id>
就可以令工作区回退到那个版本了!*一般来说,写版本号的时候,没必要写全,只要写前几位,git会自动去找到对应的版本号的,但也不能只写前两位,因为Git可能会找到多个版本号,就无法确定是哪一个了!!*值得注意的是,使用git reset --hard
回退到历史版本后,使用git log将查看不到这个版本之后的版本所提交的历史记录了。
举个🌰,HEAD指向当前分支的当前版本(我们称作A),HEAD^指向的是上一个版本,HEAD^^指向的是上上个版本,上100个版本就是HEAD-100。因此我们回退到上一个版本只需要使用
git reset --hard HEAD^
。回退到这个版本后,我们将在git log中无法查看A的提交历史了。
当你回退到某个历史版本,又想回到现在这个版本,Git也是有办法帮助你的~
与版本回退同理,想要回到现在这个版本,我们首先需要获取到现在这个版本对应的版本号。你可能会纳闷了,刚刚不是说git log查看不到现在这个版本的提交记录了,还怎么查看版本号呢???
表着急~万能的Git怎么会没有办法呢?
在Git中,git reflog
记录了你的每一次命令,只需要在这里面找到现在这个版本commit操作对应的commit_id就可以啦,这里再强调一次,每次commit时都要在-m后添加一条有效的message,这样方便我们快速找到对应的版本。
找到commit_id后,再执行一次
git reset --hard <commit_id>
,就可以回到现在这个版本啦~
在这里不得不提一下,
git reset
命令的工作模式,--hard
只是其中一种。
git reset的三种工作模式
--hard
:这种模式会把工作区和暂存区的修改都删除。--soft
:这种模式会保留工作区的修改,并把reset
带来的新的差异放进暂存区。--mixed
:不带参数时的默认模式,这种模式会保留工作区的修改,清空暂存区的内容。也就是说,工作区的修改、暂存区的内容以及由reset
所导致的新的文件差异,都会被放进工作区。
part4—分支管理
什么是分支呢?
分支类似于科幻电影中的“平行空间”,你在平行空间做的事情并不干涉你在现实空间,分支也是为了多人协作不互相干扰而诞生的。例如,你和你同事同时在做一个项目,在没有分支的时候,你的代码还没提交会影响到你同事的后续工作,但是现在有了分支,你和你同事只需要各自在自己的分支上完成自己的工作,并不会互相产生影响。
在我们创建一个版本库的时候,会自动创建一个master分支,这是主分支。一般来说放的是最终的项目代码,工作过程中,不建议直接在这个分支上做修改。我们应该创建属于自己的分支,这样我们就可以在我们自己的分支上为所欲为😎(认真做项目)。做完后只需要合并到主分支,就可以供别人使用啦。
- 创建一个新分支:
git branch <banchName>
,branchName是你的分支名字。 - 切换到别的分支上:
git checkout <branchName>
。git switch <branchName>
也是切换分支的命令,比`git checkout 更直观更易理解。
从创建分支到切换分支一步到位可以使用:
git checkout -b <branchName>
或者git switch -c <branchName>
- 查看所有分支:
git branch
。*表示当前所在的分支。 - 合并成功后,想删除自己的分支:
git branch -d <branchName>
- 合并分支。这里以和主分支合并为例,介绍一下合并分支的步骤:
- 第一步:从当前分支切换到master分支。
git checkout master
。 - 第二步:将分支与主分支合并:
git merge <branchName>
- 第一步:从当前分支切换到master分支。
合并完成后,主分支也可以看到你的分支中的内容了。
这种合并分支采用的是fast-forward的模式,当删除分支后,将看不到合并分支的信息了。还有一种普通模式:--no-ff,这种模式合并分支后,可以看到合并分支的历史,能看出来曾经合并过。这个合并模式会触发一次新的commit,因此后面加上-m的命令。即
git merge --no-ff -m ""
。
- 当同时在不同的分支下,修改了同一个文件时,合并分支就会产生冲突。解决合并冲突的办法:在工作区把内容改成我们想要的样子,再重新commit,然后就会合并成功啦。
使用
git log --graph
可以看到分支合并图。
当产生合并冲突时,使用git status可以看到哪个文件存在冲突。
- 强制删除一个还没有被合并的分支:
git branch -D <branchName>
- 把本地分支的修改推送到远程仓库:
git git push origin <branchName>
。origin表示远程仓库。 - 获取远程分支的变化到本地,并且与本地分支合并:
git pull
。 - 如果你的本地分支和远程分支没有关联,那么使用git pull是获取不到远程分支的变化,并且会报错。
建立本地分支和远程分支的关联,使用git branch --set-upstream <branchName> origin/<branchName>
;
part5—stash的使用
在工作过程中,我们常常会遇到这样的场景:手头的活正干到一半,同事就有另一个分支上的bug需要你去处理,但是你当前的工作又不想提交到版本库,这时你切换分支会报出本地还有未提交的修改的错误。遇到这种情况时,可以使用stash来临时存储你正在做的工作。stash就是git中用来临时“储藏”代码的一块空间,你可以在需要的时候把“储藏”的代码拿出去。
- 把当前修改的代码放进临时存储区:
git stash
- 查看stash中存储的内容:
git stash list
- 把存储的代码从stash中取出来有两种方式:
git stash pop
:把内容取出后,stash中的相应内容会自动删除。git stash apply
:把内容取出后,stash中的相应的内容保留下来了,需要使用git stash drop来手动删除
当stash中有多次保存的内容时,要谨慎使用git stash pop 和git stash apply。因为,git stash pop 和git stash apply永远都是取出最新“存储”的内容。如果是要取回某一次存储的内容,则需要:首先使用git stash list查看当前stash中有多少次保存的内容,想要取出哪次保存的内容,就使用 git stash pop stash@{number},number是一个数字,是stash内容的索引,从0开始。
-
清空stash中储存的内容:
git stash clear
最后,用一张经典的Git操作流程图来做Ending...
读到这里,本文对Git的相关介绍就告一段落啦,Git还有许许多多的命令,但是很多在日常工作中并不会用上,本文主要介绍了一些工作中常用的命令,熟悉掌握这些命令,在工作中大多时候都可以游刃有余地使用Git管理自己的代码啦~