前言:在学习git之前首先需要了解几个概念:工作区,暂存区,版本库。
工作区:是电脑上写代码或者文件的目录。
暂存区:一般存放在.git目录下的index中,也称索引。(git add)
版本库:又称仓库,英文名:repository。工作区有一个隐藏目录.git,它就是Git的版本库。版本库中的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都能够进行追踪,以便任何时刻都可以追踪历史,在将来某个时刻可以进行还原。(git commit)
1.创建git本地仓库
在对应目录下使用git init就可以生成.git/文件,这个文件是Git这个软件里的核心。
2.git的基础操作
(1)添加文件
在包含.git的目录下创建一个file文件,可以使用git add 命名将文件添加到暂存区:
将一个或多个文件添加到暂存区:git add [file1] [file2] .....
将指定目录添加到暂存区:git add [dir]
将当前目录下所有文件添加到暂存区:git add .
再使用git commit 命名将文件添加到版本库:
将一个或多个文件添加到版本库:git commit [file1] [file2] -m "..."(-m 后面必须跟上代码说明)
将当前添加到的暂存区中的所有文件添加到版本库中:git commit -m "..."
(2)查看版本库的历史版本
使用命令:git log
当然这个命令后面可以跟许多参数:
①--pretty=oneline:可以简化输出的内容。
②--abbrev-commit:缩减commit id(是一个使用SHA1计算出来的非常大的数)
(3)查看.git文件
一般是使用tree .git/ 命令查看,这样可以使.git文件按照树形结构打印出来。
重要参数:
①index:暂存区,add添加后的内容存储在这
②HEAD:默认指向当前正在开发的指针
③master:保存当前最新的commit id
④objects:是Git的对象库,里面包含了创建的各种版本库对象及其内容。当git add时工作区的内容就会被写入到对象库中的一个新的对象中,就位于这个目录中。
commit id被分为两部分,前2为文件夹名称,后38为文件名称。这个id是经过sha算法加密过的,一般是不能直接查看的,但是可以通过git cat-file -p commitId 来进行查看。
(4)修改文件
当对某个文件进行一次修改过后,但还没有完成提交(还没有进行add和commit操作),当前只是知道了文件被修改,并且如果能够具体知道哪些代码被修改了就更好了。 git也为我们提供了命令:git diff [file] ,可以查看工作区代码与暂存区的区别。
(5)版本回退
如果某一天发现之前提交的代码出现了很严重的问题,需要回到某个指定的版本,此时该功能就显得很重要了。
使用git reset命令进行版本回退,可以指定返回某一次提交的版本。“回退”指将版本库中的内容进行回退,至于工作区和暂存区中的内容是否回退由参数决定:
完整的格式:git reset [--sort | --mixed| --hard] [HEAD]
解释:
--sort:对于工作区和暂存区中的内容都不变,只是回退版本库中的内容。
--mixed:默认选项,回退暂存区和版本库,不回退工作区。
--hard:回退暂存区,工作区和版本库。切记如果当前工作区有未提交的代码,不要使用该参数,否则会导致开发的代码全部丢失。
HEAD:可以直接写成commit id(也可以用缩写的commit id);HEAD:当前版本;HEAD^:上一个版本;HEAD^^:上上一个版本;以此类推....
如果在回退过程commit id丢失,可以使用git relog命令查看,它记录了本地的每一条命令,eg:
先提交了version2,然后再提交了version3,使用git reset 回退到了version3,然后想要回退到version3,发现使用给git log 找不到version3的commit id(master保存当前最新的commit id,而version3是在version2之后提交的,自然就找不到version3的commit id了),就可以使用给git relog查看是否还存在(有可能成功,有可能失败)。
(6)删除文件
如果想要删除版本库中的文件,可以有如下两种方式:
在linux环境下:
①使用rm命名直接删除工作区文件,然后还需要使用git add和commit命令来同步版本库中的内容。
②git提供了对应命令:git rm [file],会删除工作区和暂存区中的内容,还需要commit才能同步版本库中的内容
3.撤销修改
有三种情况:
情况一:对于工作区的代码还未add
可以使用git checkout -- [file]命令让工作区的文件回到最近一次add或者commit时的状态,需要注意的是命令中的 -- 很重要。
情况二:对于已经add但还未commit
先使用git reset [--mixed] [HEAD],--mixed为默认选项,回退暂存区和版本库中的内容,此时回到了情况一,然后再使用git checkout -- [file]命令即可。
情况三:对于已经add并且已经commit
先使用git reset [--hard] [HEAD],直接回退工作区,暂存区,版本库到指定版本即可。
4.配置git
(1)忽略特殊文件
在日常开发中,某些文件不想提交到远端,比如保存了数据库密码的配置文件,那怎么让git知道呢?
在git工作区的根目录下创建一个特殊的.gitignore文件,然后把想要忽略的文件名添加进去即可,然后git就可以自动忽略这些文件了。
.gitignore这个文件可以在创建仓库的时候,进行勾选创建,如果没有勾选,那么可以直接在本地进行创建,然后推送至远端仓库即可。
语法:
①*.txt:排除所有以.txt为后缀的文件,当然*也可以写在后面:2.*:排除以2为开头的所有文件。
如果已经被忽略的文件也想要add的话,可以通过命令git add -f [filename]强制添加。
如果.gitignore文件写的有问题,需要查找出来到底是哪个文件写错了,可以使用git check-ignore -v 文件名 进行检查。
(2)给命令配置别名
使用命令git config [--global] alias.别名 '命令'。
--global选项如果加上,那么每一个在当前本地创建的仓库的配置中都会有这么一个配置,就相当于一个全局配置。
eg:git config --global alias.st 'status' 命令生效,然后git status就可以简化成git st。
git config --global alia.lpa 'log --pretty=oneline --abbrev-commit' 命名生效,git log --pretty=oneline --abbrev-commit就可以简化成git lpa。
5.分支管理
(1)理解分支
截止到目前,都只是创建了一条分支:主分支(也叫master分支),如果没有创建其他的分支,那么每提交一次,master分支都会向前移动一步。
(2)创建分支
有两种方式:
①git branch 分支名:只是进行分支的创建,并不会切换。
②git checkout -b 分支名:采用此种方式,创建的同时还会切换到创建的新分支上。一旦切换HEAD就指向当前分支。
(3)切换分支
git checkout 分支名
eg:新建dev分支,并且从master分支切换到dev分支。
在新分支上的提交是不会对其他分支(master等)有影响的,也就是一个单独的开发环境,不受影响。
(4)合并分支
为了能够让master分支上也能看到dev分支上的新提交,就需要将dev分支合并到master分支,并且此时必须切换到另一个分支,不能在本分支上进行合并。
使用git merge 想要合并的分支名。
(5)删除分支
使用git branch -d 分支名。在删除时只能在其他分支进行不能在本分支上进行删除。
(6)合并冲突
实际在合并的时候,却是有可能合并失败的,不是一帆风顺的,有时候可能会解决代码冲突的问题。举个例子:(同时对一个文件(ReadMe)进行修改,在linux环境中)
现在有新建的dev分支和master分支:
现在dev上提交一次内容:
然后切换至master分支再进行一次内容提交:
可以看到此时ReadMe文件中是没有内容的。
此时两条分支的状态:
进行合并:
可以看到产生了冲突,让我们修理这个冲突然后再进行提交。
冲突: 保留想要的内容,然后再进行add和commit,冲突解决,解决后的状态:
小小建议:由于master主分支上一般都是放的是一些稳定运行的代码,所以在合并到master分支之前可以先在当前所在的分支合并一下master,如若有冲突就解决,然后再切换至master分支进行其他分支的合并。当然在实际开发中往往合并这一步要经过更多严格的步骤,才能够进行合并。
还可以使用git log --graph --pretty=oneline --abbrev-commit 来查看分支之间的关系:
(7)分支管理
通常进行合并的时候,git会采用Fast Forward模式,使用当前模式合并出来的结果:
Fast Forward模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来最新的提交到底是merge进来的还是提交的,所以git为我们提供了非Fast Forward模式,让我们能够明显看到当前到底是merge还是commit。
eg:创建一个分支dev2,提交内容,合并到master上去。
如果是Fast Forward模式:
直接将的dev2分支上的内容合并到master上,并不会创建新的一个commit。
(8)bug分支
假如现在正在dev分支上开发,开发到一半,突然发现master分支上有bug,需要解决。可以创建出一个bug分支来进行修复,然后删除,但是dev上的代码怎么办?
git为我们提供git stash命令,可以将当前工作区中的内容进行存储,被存储的内容可以将来在某个时刻,给取出来。
首先通过git stash list查看当前存储的工作区的代码
取出方式:
①git stash pop:在恢复的同时,也会把内容从stash中删除掉
②git stash apply + 恢复内容在stash中的标号:如果想要删除stash中的内容,还需要git stash drop 进行删除。
eg:
(9)删除临时分支
在开发中,如果某一个分支已经开发完毕,并且已经进行了提交,还未进行合并,但是现在却觉得这个分支上的功能没有必要了,想要删除当前分支,使用git branch -d 命令是不行的,必须要git branch -D命令强制进行删除。
6.远程操作
git是一个分布式版本控制系统,并且分布式版本控制系统的时候安全性要高很多,每个人的电脑中都有完整的版本库,某一个人的电脑坏掉了可以直接从其他任何一个人那里复制或者从远端拉取也可以。
(1)新建仓库
(2)克隆仓库
直接使用git clone 命令在指定文件目录下克隆就好。
有两种方式:
①Http方式:
git clone http对应的地址。
②ssh方式:采用此种方式的话比较麻烦,首先需要在本地进行SSH key的创建(前提是.ssh目录中没有id_rsa(私钥)和id_rsa.pub(公钥)这两个文件):
使用ssh-keygen -t rsa -C "邮箱"来进行生成上述两个文件。
其次是添加自己的公钥到远端仓库
最后在使用git clone ssh对应的地址 就可以完成克隆。
(3)向远端仓库推送
git push 远端仓库名 远端分支名:本地分支名;
如果远端分支名与本地分支名相等的话那么可以直接写成git push 远端仓库名 本地分支名。
(4)拉取远端仓库
git pull 远端仓库名 远端分支名:本地分支名;
如果远端分支名与本地分支名相等的话那么可以直接写成git pull 远端仓库名 本地分支名。
7.标签管理
标签就是对某一次commit的一个标识,相当于起了一个别名。
(1)创建标签
git tag 标签名:默认对当前最新一次commit创建标签。
如果想要对指定的commit进行创建标签:git tag 标签名 commitId(可以缩写)
(2)查看标签
git tag:查看当前所有标签。
git show 标签名:查看某一个具体的标签。
git tag -a 标签名 -m "标签说明" commitId:-a指定标签名,-m指定说明文字
(3)操作标签
git tag -d 标签名:删除标签
git push 远程仓库名 标签名:推送标签至远程仓库
如果标签已经在本地进行了删除,想要将远程仓库中的标签也进行删除的话,直接使用git push 远程仓库名 标签名是不能推送成功的,因为此时标签已经不存在了,得使用一种特殊得方式进行删除:git push 远程仓库名 :refs/tags/标签名
8.其他问题
远程分支删除后,但是还能在本地看到。想要得结果是远程删除了那么本地也应该看不到才对。可以采用如下方式进行解决:
首先git remote show 远程仓库名,此时如果远程某个分支被删除的话,那么就会有提示使用git remote prune进行删除。