Git学习
git命令前置
1 | git init 把这个目录变成Git可以管理的仓库 |
集中式和分布式版本控制系统的区别
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。集中式版本控制系统最大的毛病就是必须联网才能工作
分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
创建版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
创建一个空目录
1 | mkdir learngit |
通过git init
命令把这个目录变成Git可以管理的仓库
命令git add
告诉Git,把文件添加到仓库:
1 | git add readme.txt |
命令git commit
告诉Git,把文件提交到仓库:-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
1 | git commit -m "wrote a readme file" |
运行git status
命令看看结果:git status
命令可以让我们时刻掌握仓库当前的状态
1 | git status |
git diff
这个命令看看:顾名思义就是查看difference,显示的格式正是Unix通用的diff格式
1 | git diff readme.txt |
版本回退
在Git中,我们用git log
命令查看历史记录:git log
命令显示从最近到最远的提交日志
在Git中,用HEAD
表示当前版本,也就是最新的提交1094adb...
(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
使用git reset
命令:回退到上一个版本
1 | git reset --hard HEAD^ |
git reflog
用来记录你的每一次命令:可以查看 commit id
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为创建Git版本库时,Git自动创建了唯一一个master
分支,所以,现在,git commit
就是往master
分支上提交更改。
简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
为什么Git比其他版本控制系统设计得优秀?Git跟踪并管理的是修改,而非文件
git checkout -- file
可以丢弃工作区的修改:
命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
命令git reset HEAD <file>
可以把暂存区的修改撤销掉(unstage),重新放回工作区
版本库中删除该文件,那就用命令git rm
删掉,并且git commit
:
把误删的文件恢复到最新版本:git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
1 | git remote add origin git@github.com:L1aovo/LFI_exp.git关联远程仓库 |
删除远程库,可以用git remote rm <name>
命令。使用前,建议先用git remote -v
查看远程库信息:根据名字删除,比如删除origin
:
1 | $ git remote rm origin |
克隆仓库
1 | $ git clone git@github.com:michaelliao/gitskills.git |
创建dev
分支,然后切换到dev
分支:
1 | git checkout -b dev |
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
1 | git branch dev |
把dev
分支的工作成果合并到master
分支上:
1 | git merge dev |
删除dev
分支:
1 | git branch -d dev |
创建并切换到新的dev
分支,可以使用:
1 | git switch -c dev |
直接切换到已有的master
分支,可以使用:
1 | git switch master |
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
或者git switch <name>
创建+切换分支:git checkout -b <name>
或者git switch -c <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
带参数的git log
也可以看到分支的合并情况:
1 | git log --graph --pretty=oneline --abbrev-commit |
用git log --graph
命令可以看到分支合并图。
Git会用Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
1 | git merge --no-ff -m "merge with no-ff" dev |
Git还提供了一个stash
功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
1 | git stash |
master
创建临时分支:
1 | git checkout -b issue-101 |
用git stash list
命令看刚才的工作现场
用git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用git stash drop
来删除;
git stash pop
,恢复的同时把stash内容也删了:
cherry-pick
命令,让我们能复制一个特定的提交到当前分支:
用git cherry-pick
,我们就不需要在dev分支上手动再把修bug的过程重复一遍。
1 | git branch -d feature-vulcan |
强行删除:
1 | git branch -D feature-vulcan |
查看远程库的信息,用git remote
:
1 | git remote |
如果要推送其他分支,比如dev
,就改成:
1 | git push origin dev |
当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master
分支。不信可以用git branch
命令看看:
命令git rebase
把分叉的提交历史“整理”成一条直线,看上去更直观。缺点是本地的分叉提交已经被修改过了。
命令git tag <name>
就可以打一个新标签:
1 | git tag v1.0 |
命令git tag
查看所有标签:
1 | git tag |
找到历史提交的commit id,然后打上
比方说要对add merge
这次提交打标签,它对应的commit id是f52c633
,敲入命令:
1 | git tag v0.9 f52c633 |
git show <tagname>
查看标签信息:
还可以创建带有说明的标签,用-a
指定标签名,-m
指定说明文字:
1 | git tag -a v0.1 -m "version 0.1 released" 1094adb |
标签打错了,也可以删除:
1 | git tag -d v0.1 |
命令git push origin <tagname>
:
1 | git push origin v1.0 |
一次性推送全部尚未推送到远程的本地标签:
1 | git push origin --tags |
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
1 | git tag -d v0.9 |
然后,从远程删除。删除命令也是push,但是格式如下:
1 | git push origin :refs/tags/v0.9 |
Git工作区的根目录下创建一个特殊的.gitignore
文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
不需要从头写.gitignore
文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
有些时候,你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore
忽略了.如果你确实想添加该文件,可以用-f
强制添加到Git:
1 | git add -f App.class |
.gitignore
写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore
命令检查:
1 | git check-ignore -v App.class |