Git:基本使用
我们在写项目代码的时候,代码提交后,由于功能需求的修改或其他原因,可能会涉及到多次的修改,但修改之后,可能会把原来的代码·给改坏了,或还是觉得之前的代码更合适。
但是,尴尬的是,此时的代码已经被改的面目全非了,相仅通过记忆去复原代码,是非常帮困难的,即使改回来了,但若存在多次这样的操作,谁又能受得了呢,于是,Git就能帮我们解决这个问题。
Git的其中一个功能是用来记录之前代码版本,想要查找或恢复之前的代码,可以通过Git查找到。
目录
一. 安装Git
二、Git基本操作
配置GIt
认识工作区,暂存区,版本库:
添加一个文件,并提交到本地仓库:
对 .git文件的介绍:
修改文件:
版本回退:
撤销修改:
情况1:工作区的代码还未add到暂存区:
情况2:工作区的代码已经add了,但还未commit
情况3:已经进行了add,和commit命令:
删除文件:
三、分支管理
创建分支:
合并分支:
合并冲突:
删除分支:
分支管理策略:
bug分支:
一. 安装Git
Git 是开放源代码的代码托管⼯具,最早是在Linux下开发的。开始也只能应⽤于Linux平台,后⾯慢慢的被移植到windows下,现在,Git可以在Linux、Unix、Mac和Windows这⼏⼤平台上正常运⾏了.
下面以Linux-ubuntu平台为例子安装Git:
可以先输入git命令,查看系统有没有安装git.
git
Command 'git' not found, but can be installed with:
sudo apt install git
出现上面的结果,说明git还未安装。就需要安装一下,安装命令也是非常简单的,上面也已经给出来了:
安装git:
sudo apt-get install git -y
(若在root目录下,则可以不用加sudo,非root目录要加sudo)
查看git安装版本:
git --version
Windows安装过程链接:
https://www.bilibili.com/video/BV1hf4y1W7yT/?p=3&vd_source=b57c3f3e8a7507d4af7322c28f05fdbc
二、Git基本操作
我们提交后的代码都是放到远程仓库中的,自己在本地修改好代码后,要提交到远程仓库中。
要先创建一个本地仓库,用来存放自己的代码。
创建本地仓库:
git init
注意,创建本地仓库命令要在文件下执行。
创建成功后,就会发现在当前文件下,多了一个 .git 文件。.git是用来跟踪管理仓库的,不要手动修改这个目录里的文件,否则可能会把Git仓库破坏掉。
配置GIt
安装好Git后,要先配置用户名和e-mail地址。
配置命令:
git config [--global] user.name "your username"
git config [--global] user.email 'email@example.com"
填入你的用户名和邮箱就可以了。
其中的 --global选项是选填项,如果使用了这个选项,表示这台机器上的所有Git都会使用这个配置。要是想在不同仓库设置不同的用户名和邮箱,不加这个配置即可。
查看配置命令:
git config -l
删除配置命令:
git config [--global] --unset user.name
git config [--global] --unset user.email
认识工作区,暂存区,版本库:
工作区:就是你要写的代码的目录。在 .git文件的同目录下。
当前目录就是工作区,在这里可以创建文件等,可以进行提交.
暂存区:(index)是将你写的代码暂存的地方。一般在 .git目录下的index文件夹中。暂存区也叫做索引。
add后的数据都会先保存在这里.
版本库:也叫做仓库,(repository).⼯作区有⼀个隐藏⽬录 .git ,它不算⼯作区,⽽是 Git 的版本库。这个版本库⾥⾯的所有⽂件都可以被 Git 管理起来,每个⽂件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
在创建Git版本库的时候,Git会自动帮我们创建一个master分支,和一个指向master的一个指针HEAD。
通过git branch查看当前分支和已经存在的分支.(后面再将git命令),当前仅存在master分支,且前面的*表示HEAD指向它。
HEAD里面存储的就是指向当前分支的位置。
工作区修改完成后,执行 git add 命令,就会将内存存放到暂存区,暂存区的文件就会被修改。
git add 要提交的文件名
//git add .提交当前目录下的所有文件
执行git commit 命令,master分支会做出相应的修改,就是将暂存区的内容写入到了版本库中。
git commit -m"描述内容"
//-m 后面引号中填写一些关于提交的内容的描述,这个描述是不能少的,并且要好好写,是给我们自己看的
执行了这两个命令后,就完成了将修改提交到了本地的代码仓库中。
添加一个文件,并提交到本地仓库:
先创建文件
touch file1 //创建一个文件
git add [file1] [file2] [file3]... //将创建的一个或多个文件添加到暂存区
git commit -m"touch file1.txt" //提交到本地代码仓库
git commit命令执行后,会告诉我们哪些文件做了改动,改动的内容是什么。
add命令可以进行一次或多次,而commit命令只执行一次即可。
可以通过git log命令,查看提交历史:
git log [--pretty=oneline] [abbrev-commit]
//选填项:
//--prettyp=oneline: 以简洁的形式显示,一行显示一次提交结果
//abbrev-commit: commitId仅显示前10个数字
我们会看到每次的提交带有一大串数字,因为每次提交,都会生成commit Id(版本号),Git的commit id不是1,2,3……递增的数字,⽽是⼀个 SHA1 计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表⽰.可以通过增加abberv-commit仅显示前10个数字。
对 .git文件的介绍:
1. index 就是我们的暂存区,add 后的内容都是添加到这⾥的。
2. HEAD 就是我们的默认指向 master 分⽀的指针。
3. objects 为 Git 的对象库,⾥⾯包含了创建的各种版本库对象及内容。当执⾏ git add 命令时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新对象中,就位于 ".git/objects" ⽬录下。
修改文件:
对创建的文件的任何修改,都算修改。Git跟踪并管理的是修改,而非文件。
现在对file1文件进行一次修改:添加一行:I an studing.
可以通过git status命令查看当前仓库的状态:
git status //该命令用于查看上次提交后,文件是否有新的修改
可以看到 提示文件有被修改,但还未被添加和提交。
通过git status命令,我们只知道文件有被修改,但并不知道修改了什么,若是刚刚修改的,可以记得修改了什么内容,但若是很长时间之前的修改,谁又记得呢?Git知道这个情况,可以通过
git diff [file]命令查看:
git diff [file] //该命令用于显示工作区和暂存区的文件差异。
git diff HEAD --[file] //该命令用于查看工作区和版本库之间的差异。
// file要查看的文件名
-表示修改之前:有0行
+:表示修改之后,有一行代码添加
版本回退:
Git 能够管理⽂件的历史版本,这也是版本控制器重要的能⼒。如果有⼀天你发现之前前的⼯作做的出现了很⼤的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。
执行git reset命令用于版本回退:可以指定返回某一次提交的版本。
这里的回退指的是版本库中代码的回退,工作区和暂存区的代码是否回退,取决于命令的参数
git reset [--soft|--mixed|--hard] [HEAD]//选项说明://HEAD: 指要回退的版本,可直接写commit Id即可。
// HEAD: 表示回退到当前版本,
// HEAD^: 上一个版本
// HEAD^^: 上上个版本
//....以此类推。
//也可以使用 ~ 加 数字 表示:
//HEAD~0 : 表示当前版本
//HEAD~1 :表示上一个版本
//HEAD~2:表示上上个版本
//以此类推。//--soft : 仅回退版本库中的代码,工作区和暂存区的代码不回退。//--mixed: 为默认选项,使用时可以不带该参数。将暂存区内容回退为指定提交版本内容,工作区的内容保持不变。//--haed: 将工作区和暂存区的内容都回退到指定版本。切记,这个选项一定要慎用,因为一旦使用之前工作区未提交的代码将都找不到了。
当我们进行版本回退后,若发现还是原来的版本更好,Git也给我们提供了吃后悔药的机会。
还是使用git reset命令,但是必须要知道要返回的版本号,即commit ID。
当使用git log命令查找不到想要回退的版本号时,还可以通过git reflog命令查找:
git reflog //该命令用来记录本地的每一次命令
此处查到的是commit ID的部分。
git版本回退的速度时候非常快的,因为 Git 在内部有个指向当前分⽀(此处是master)的 HEAD 指针, refs/heads/master ⽂件⾥保存当前 master 分⽀的最新 commit id 。当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的version,通过修改HEAD的指向,即可实现版本回退到指定版本。
但是由于git更新版本的速度是非常快的,有可能查不到需要返回的版本的commit ID,就真的无法返回了,因此每一次的·git命令都应该慎重操作。
撤销修改:
当我们在工作区写了很长时间的代码,发现代码越写越乱,想回到修改之前,即上次提交的状态,Git也满足了我们。
情况1:工作区的代码还未add到暂存区:
当你还记得自己在哪些地方进行了修改,可以直接在原代码上修改即可;
要是已经改的很乱了,或者过了很长时间,忘记了修改了哪些地方,就是无法通过手动的方式进行恢复,Git提供了git checkout -- [file]命令让工作区文件回到最近一次add或commit状态。
git checkout --[file] //file:要恢复的文件名
情况2:工作区的代码已经add了,但还未commit
add后,就将代码保存到了暂存区,此时要恢复代码比较麻烦了。
法一:
在版本回退的时候的--mixed参数,使用这个参数吗,让暂存区的代码回退到当前版本库中代码的版本,暂存区中的代码就恢复到了上次提交代码的状态了;
然后再通过git checkout --[file]命令,将工作区的代码恢复即可。
git reset --mixed HEAD [file]
git checkout --[file]
法二:
此时仅进行了add,版本库中的代码还未被更新,可以直接使用版本回退命令,将回退参数设为 --hard ,直接将工作区和暂存区的代码都回退到当前版本库中的代码版本。
git reset --haed HEAD [file]
情况3:已经进行了add,和commit命令:
还是通过版本回退命令,回退到版本库中的上一个版本:
git reset --hard HEAD^
删除文件:
删除文件也是一个操作,要想将执行提交到本地仓库中,也需要执行add和commit命令。若不小心误删了文件,这也属于操作,按照撤销修改的命令执行,进行文件恢复即可。
三、分支管理
我们知道,在创建git的时候,他会为我们默认创建一个master分支,并让HEAD指定master分支,每次提交,Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分⽀。截⽌到⽬前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即 master 分⽀。
HEAD指向的不是提交,而是分支,此时指向的是master分支,master才是指向提交的,HEAD指向的是当前执行的分支。
每次提交,master分⽀都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越来越⻓,⽽HEAD只要⼀直指向master分⽀即可指向当前分⽀。
创建分支:
Git支持我们创建并查看分支,现在创建一个dev分支:
git branch //查看当前HEAD指向的分支和当前存在的分支git branch dev //创建一个dev分支git checkout dev //切换到dev分支,就是让HEAD指向dev分支,此后的操作都是在dev分支上执行的了//创建分支并切换到新创建的分支上,两条命令,可以合成一条执行:
git checkout -b dev //创建dev分支,并切换到dev分支上
查看当前分支,创建dev分支,并切换到dev分支上:
创建分支并切换到新创建的分支上,可以用git checkout -b dev命令一步实现。
合并分支:
不同的分支之间存在隔离性,在一个分支上进行的提交,在另一个分支上是不显示的,即一个分支的修改,对另一个分支不造成影响。
想要让两个分支上的结果合并到一个分支上,可以通过git merge来实现:
git merge dev //合并dev分支到master主分支上,这个操作必须要先切换到master分支上操作
该命令用于合并指定分支到当前分支上,因此在合并前,需要先切换到当前分支才行。
ast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。当然,也不是每次合并都能 Fast-forward,还有其他的合并方式。
合并冲突:
在合并分支的时候,并不一定能合并成功,有时候会遇到代码冲突的问题。
例如:master分支对file1文件进行了修改,并提交到了代码仓库,切换到dev分支,dev分支也对file1文件进行了修改,并提交到代码仓库,此时,dev分支想合并master分支,就会出现代码冲突的现象。这是因为两个分支都进行了新的提交,合并的时候不是在同一条主干上的,git不知道要以那个为准,就会发生合并冲突。
出现冲突后,需要自己手动处理冲突,然后再进行add,commit提交到代码仓库。
修改后保存,进行再次提交,推送。
用带参数的git log查看分支的合并情况:
git log --graph --pretty=oneline --abbrev-commit
删除分支:
分支合并后,就没有用了,就可以删除了:通过git branch -d 命令,将其删除:
git branch -d dev //删除dev分支
删除分支的时候,不能处在当前分支下,要切换到别的分支上执行该命令才行。
因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和直接在master分⽀上⼯作效果是⼀样的,但过程更安全。
当当要删除的分支上还有未被提交的内容时,Git会禁止删除分支,若想要强制删除,可以使用
git branch -D 分支名 命令进行删除。
git branch -D dev //强制删除dev分支
分支管理策略:
之前提到的fast forward模式,在合并分支的时候,若合并成功,就是采用的fast forward模式,这种模式下,当合并之后,删除分支后,查看历史分支时,就不知道这次的操作是最新的提交还是分支合并的,只能看到有一次提交。
当合并冲突的时候,就不是fast forward模式了,会进行一次新的提交,这样即使删除了合并的分支,也能知道上次的提交是合并的,还是一次提交。
Git支持我们强制禁止使用fast forward模式,禁止后,当merge时,就会生成一个新的commit,这样就能从历史分支上知道分支信息了。
在执行合并分支命令的时候,要想禁用fast forward模式,加上--no-ff 配置 :
git merge --no-ff -m"合并描述" dev //将dev分支采用非fast forward的方式合并到master分支上
禁用fast forward模式后,会创建一个新的commit Id,因此在合并的时候,要将描述写进去。
bug分支:
当在dev上开发项目,进行到一半,发现master分支上有一个bug,需要解决,在Git中,每个bug都可以创建一个临时bug分支,进行修复,修复后,合并bug分支到master分支上,合并后将bug分支删除。
但此时dev还未开发完,无法提交,可以通过Git提供的git stash命令,将当前工作区的信息存储起来,被存储的信息在将来某个时间可以恢复出来。
git stash //将当前还未完成的版本暂存起来
这个命令执行后,当前的状态就是上次提交代码的状态。
master分支上的代码修复后,要取dev分支上继续代码开发,此时可以通过git stash list命令。查看之前stash的代码保存在了哪里。要恢复代码时,通过git stash pop命令,恢复原来的代码,并将stash也给删除了。
git stash list //查看之前stash的工作现场存储在哪里了
git stash pop //将之前stash的工作现场恢复,并删除stash
总结:每当要实现一个新的功能时,需要在原来的代码上进行开发,就可以创建一个新的分支,创建完成后,再和主分支进行合并,你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀上,这样,既安全,⼜不影响别⼈⼯作。
并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成。