git学习笔记
把我学的东西做了个总结供大家取用。
1.Git的来历,有兴趣的自己百度啊~~~
2.分布式管理方案与集中式管理方案
1)分布式版本控制系统根本没有“中央服务器”
2)在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。
3)分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
3.windows下安装git
安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
4.创建版本库
//创建一个空的目录
mkdir learngit
//指向新创建的目录
cd learngit
//pwd命令用于显示当前目录
PWD
//通过git init命令把这个目录变成Git可以管理的仓库:
git init
//用ls -ah命令可看见隐藏的git目录
5.把文件添加到版本库
明确:所有的版本控制系统都只能跟踪文本文件的改动,但是word文件是二进制格式,因此word的内容改动版本控制系统无法跟踪
1)新建txt文本在learngit目录下
2)$ git add readme.txt
3)git commit -m "this is a new file" -m后面输入的是本次提交的说明
问题:为什么Git添加文件需要add,commit一共两步呢?
答案:因为commit可以一次提交很多文件,所以你可以多次add不同的文件,
比如:
$ git add file1.txt
$ git add file2.txt file3.txt
6.版本回退
1)git log命令查看 或者 git log --pretty=oneline 注意:git的版本号不是123而是一串随机码
2)git中使用Head作为当前版本,上一个版本就是Head^ 如果是上100个版本则是:HEAD~100
回退到上一个版本命令:$ git reset --hard HEAD^
3)指定回到某个版本(可以往前找也可以往后找)
$ git reset --hard 1094a 版本号不用写全,写前几位就可以
原理解释:
Git是C语言写的,Git内部有个指向当前版本的指针,当你退回版本的时候Git仅仅是把指针指向先前版本,然后更新了工作区
问题:当在命令行情景下忘记了版本的commit id怎么办?
答案:使用Git的git reflog记录命令操作,可以使用这个命令找回
7.Git的工作区和暂存区
1)工作区(Working Directory),最早我们建的文件夹learngit就是工作区
2)版本库(Repository),使用ls -ah才能看见的目录.git就是版本库
版本库里面存放的最重要的东西就是被称为stage的暂存区,此外还有分支master以及指向他的指针HEAD
(1)git add命令将文件添加时实际就是将文件添加到暂存区
(2)git commit提交更改,实际就是把暂存区的所有内容提交到当前分支
3)使用git satus查看git状态
8.管理修改
1)Git跟踪管理的是修改,而非文件。
操作:
(1)在文件后增加一行内容“这是第二次修改”,添加 got add
(2)再次修改文件,提交 git cmmit -m
(3)查看文件状态,第二次修改没有被提交
原因:
git管理的是修改,当使用git add命令后,工作区的第一次修改被放入暂存区准备提交,但是工作区的第二次修改没有放入暂存区,所以git commit只负责把暂存区的修改提交了,提交后,用git diff HEAD -- LX.txt可以查看工作区和版本库里的区别
问题:如何提交两次不同的修改?
两次修改分别add,最后commit即可
9.撤销修改
1)场景一:当你改乱了工作区的某个文件的内容,想直接丢弃修改的时候
git checkout -- file放弃工作区的所有修改
git checkout -- file的含义是把制定文件的工作区修改全部撤销
分为两种情况:
(1)文件被修改后还没放入暂存区,撤销修改后和版本库内容一样
(2)文件被添加到暂存区后,又做了修改,撤销后版本回到添加到暂存区后的状态
注意:git checkout命令是切换到另一个分支,git checkout -- 才是版本回退
2)场景二:将修改提交到了暂存区,但是没有commit
使用git reset HEAD <file>可以把暂存区的修改撤销掉重新放回工作区
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区,这是当我们用HEAD的时候,表示最新版本
3)场景三:改错了内容并且提交到了版本库
在没有推送到远程版本库的情况下使用版本回退
10.删除文件
1)一般情况下,直接在文件管理器中删除或者使用rm命令删除$ git rm test.txt,使用rm命令需要commit文件
2)删错了文件使用git checkout --file
git checkout其实是用版本库里的版本替换工作区的版本,因此工作区中的所有操作都可以使用此命令意见还原
11.配置远程仓库
1)在github或者码云上添加自己的一个仓库
2)添加远程库$ git remote add origin git@github.com:yourGitHub/learngit.git
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
3)把本地库的内容推送到远程库中$ git push -u origin master
命令解释:push命令是将当前分支master推送到远程,u参数是将本地仓库和远程仓库关联起来,以后推送可以使用简化命令
4)关联远程仓库后$ g'i't即完成将修改推送到远程
12.从远程仓库克隆
$ git clone YourGitHub
13.创建于合并分支
1)主分支即master分支
2)严格来说HEAD不是指向提交,而是指向master,master才是指向提交的
所以HEAD指向的就是当前分支,如下图所示
3)当我们创建分支时
这样当前分支就在dev上
注意:git创建分支只增加了一个dev指针,改变了HEAD的指向,工作区的文件没有任何变化
4)当我们针对分支进行修改的时候
dev指针往前移动一步而master指针不变
5)当我们合并分支的时候
git合并分支合并也是修改指针而工作区不变
合并完分支甚至可以删除分支,删掉分支就是把dev指针删掉
6)操作:
(1)git checkout -b dev 创建dev分支,然后切换到dev分支
这条命令相当于两条命令:git branch dev
git checkout dev
(2)使用git branch命令查看当前分支,当前分支上会有一个*
(3)在分支上操作完后切换到master主分支
git checkout master
这时在分支上修改的文件在master上是看不到的,因为此时master的提交点没变,即:
(4)将dev分支的工作合并到master上
$ git merge dev 该命令是用于合并指定分支到当前分支
(5)删除dev分支 $ git branch -d dev
注意:git鼓励使用分支。使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。
14.解决冲突
操作:
1)准备分支featurel,$ git checkout -b feature1
2)将修改在分支featurel上提交
3)切换到master分支 $ git checkout master
4)在master分支上对相同文件进行修改并提交
此时的git内的情况为:
5)执行分支合并$ git merge feature1,此时Git无法执行快速合并,会出现冲突,提示如下:
Auto-merging LX.txt
CONFLICT (content): Merge conflict in LX.txt
Automatic merge failed; fix conflicts and then commit the result.
此时必须手动解决冲突后再提交,可使用git status命令查看冲突文件
此时git内的情况变为
6)使用git log查看分支合并情况
$ git log --graph --pretty=oneline --abbrev-commit
7)删除feature1分支 $ git branch -d feature1
15.分支管理策略
1)git分支合并时,如果可能git会用Fast forward模式,但是在这种模式下删除分支后会丢掉分支信息
2)强制禁用Fast forward模式,git就会在merger是生成一个新的commit,这样从分支历史上就可看出分支信息
3)操作:
(1)创建并切换dev分支 $ git checkout -b dev
(2)修改文件并提交
(3)切换回主分支master $ git checkout master
(4)合并分支dev 使用--no-ff参数表示禁用Fast forward
$ git merge --no-ff -m "merge with no-ff" dev
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
(5)使用git log查看分支历史
此时git内部
4)实际开发中master分支应该是非常稳定的,也就是仅仅用来发布新版本,平时不能在上边干活
5)平时干活都在dev上,即dev版本是不稳定的,到版本发布的时候将dev分支合并到master上
6)开发团队中每个人都有自己的分支,团队成员往dev分支上合并
16.BUG分支
1)每一个bug都可以通过一个分支来修复,修复后合并分支,然后将临时分支删除
场景1:你正在进行一个一天才能修复玩的bug,在dev分支上进行修改,这时有一个紧急bug,这个bug只需要两个小时
解决:(1)Git提供了stash功能可以把当前工作现场保存起来,等现场恢复后继续工作
$ git stash
(2)确定从哪个分支上修复bug,比如在master分支上修复,就从mater上创建临时分支
$ git checkout master
$ git checkout -b issue-101
(3)修复完成后切换到master,合并分支,删除bug修复分支
$ git checkout master
$ git merge --no-ff -m "merged bug fix 101" issue-101
(4)查看刚才的bug修复现场
$ git stash list
(5)回复bug分支前的工作现场
*1.$ git stash apply 使用这种方式回复后stash内容不删除,需要使用$ git stash drop删除
*2.$ git stash pop 使用这种方式的同事吧stash内容也删了
注意:可以多次stash,回复的时候先git stash list查看,然后使用$ git stash apply stash@{0}回复指定的stash
17.Feature分支
场景一:当添加一个新功能的时候,不希望这个功能搞乱了主分支,这样就可以每添加一个新功能就建一个feature分支,完成后,合并,最后删除该分支。如果开发完发现该功能不需要添加则将该没有合并的分支强制删除<大写D>$ git branch -D <name>
18.多人协作
1)当从远程仓库克隆时,Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库默认名称是origin
2)$ git remote 查看远程库信息 git remote -v显示更详细的信息
3)推送分支,将该分支上的所有本地提交推送到远程库,推送时要指定本地分支,这压根git就会把该分支推送到远程库对应的分支上
例如:$ git push origin dev
4)并不是一定要把本地分支往远程推送,例如master是主分支,因此时刻需要与远程同步;dev是开发分支,团队所有成员都要在上边工作,因此也需要时刻与远程同步bug分支只用于在本地修复bug没必要推送到远程;feature是否推送到远程,取决于该分支上是否有人协作开发
5)操作:
(1)从远程库Clone时,默认情况下,只能看到master分支要在master分支上开发,就必须创建远程origin的dev到本地,使用命令$ git checkout -b dev origin/dev
(2)在dev上继续修改,同时把修改dev分支push到远程$ git push origin dev
(3)如果步骤二出现冲突,使用git pull把最新的origin/dev抓下来,然后本地合并,解决冲突再推送$ git push origin dev
注意:如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。
19.Rebase
1)rebase操作可以把本地未push的分叉提交历史整理成直线;
2)rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。