预备知识:(想查命令的直接下拉)
1、我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
2、Git管理的是修改而不是文件,因此如果你没有修改文件,即使你执行了git add 后,git state将提示没有任何改变。
3、假如有如下操作:
第一次修改 -> git add
-> 第二次修改 -> git commit
当你用git add
命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit
只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。所以此时你必须再次git add和git commit才能将第二次提交了
4、任何版本控制软件只能处理文本文件
5、Git是分布式版本控制系统,Github是一个网站,在这上面你可以Fork一个开源项目,自己讲拥有Fork后的仓库的读写权限,可以推送pull request给官方仓库来贡献代码。(当然,官方接不接受就是另外一回事了)
例子大致如下:
HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEAD
指向的就是当前分支。一开始的时候,master
分支是一条线,Git用master
指向最新的提交,再用HEAD
指向master
,就能确定当前分支,以及当前分支的提交点:每次提交,master
分支都会向前移动一步,这样,随着你不断提交,master
分支的线也越来越长;当我们创建新的分支,例如dev
时,Git新建了一个指针叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示当前分支在dev
上:Git创建一个分支很快,因为除了增加一个dev
指针,改改HEAD
的指向,工作区的文件都没有任何变化!不过,从现在开始,对工作区的修改和提交就是针对dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变;在master下合并dev的话,如果采用快速合并git就将master移向dev所在的地方即可
7、git分支合并有时会造成某些问题,例如在两个分支中修改了同一个文件,这时git就不知道要保存哪一个分支的修改,此时会显示冲突合并不成功。只有手动解决了冲突,并且重新提交之前有冲突的文件,才能合并成功
git stash
一下,然后去修复bug,修复后,再git stash pop
,回到工作现场。
git branch -D <name>
强行删除。
master
分支和远程的master
分支对应起来了,并且,远程仓库的默认名称是origin
13、master
分支是主分支,因此要时刻与远程同步;
-
dev
分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步; -
bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
-
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
-
本地新建的分支如果不推送到远程,对其他人就是不可见的;
-
在本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name
,本地和远程分支的名称最好一致;
-
建立本地分支和远程分支的关联,使用
git branch --set-upstream branch-name origin/branch-name
;
14、忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的
.class
文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
本地Git操作:
1、创建本地仓库: git init
2、将文件加入暂存区(可以添加多个):git add <filename>3、提交到仓库: git commit -m "本次提交的备注"
4、查看状态:git status
5、查看修改的地方:git diff
6、查看历史版本记录:git log
加上后置参数 --pretty=oneline可以成行显示 --graph可以用图表示各版本关系 --abbrev-comit显示缩略commit信息
7、查看历史指令:git reflog
-----------------------------------------------------------------------
8、回退到指定版本:git reset --hard 版本号(如果是HEAD^则为上一版本,HEAD^^则为上上版本,HEAD~n为往上第n个版本)9、如果要撤回版本回退的话:
先查询历史指令,找到版本commit id: git reflog
接着,退到相应版本:git reset --hard 版本id
<实际上8、9是对指针进行操作>
(你.git所在的文件夹为工作区,而.git文件夹为版本库)
10、撤销修改:(当然这是在你还没推送到远程仓库前)
情景1:只在工作区修改还未放到暂存区:git checkout -- filename删除工作区中的修改(注意:--
很重要,没有--
,就变成了“切换到另一个分支”的命令)
情景2:在工作区修改后并且已推送到了暂存区但是还没提交到本地仓库:先用git reset HEAD filename,就能将暂存区的修改回退到与上一次相同,这样只剩工作区有修改了了,即回到了情景1,再用情景1的方法让工作区回退。
情景3:提交到了本地仓库,用git reset --hard HEAD^回退回上一版本,在根据情急2进行下一步处理
11、删除
删除文件:git rm filename(这时是对暂存区和工作区进行删除操作)接着用git commit提交之后仓库里的文件将被删除。
恢复被误删的文件:
a、未提交,首先git reset HEAD filename让暂存库回退,接着git checkout -- filename使工作区回退
b、如果你已经提交了,你得先回退版本库,即 git reset --hard HEAD^(此操作顺带也将暂存区回退了),因此再执行git checkout -- filename即可
/*在这里做一个小小的总结:
git checkout -- filename其实是用暂存库的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”)
git reset HEAD filename其实是用版本库的版本替换暂存库的版本
git reset --hard HEAD^其实是用版本库的上一个版本替换版本库现有版本*/
-----------------------------------------------------------------------
12、查看远程库信息:git remote -v
(显示可以抓取fetch和推送push的远程库地址,如果没有推送权限,则不会显示push的地址)
关于远程仓库的操作:
1、你可以自己搭建git服务器,但是github网站提供了很好的服务,不用自己搭建服务器可以直接在github上注册一个账号,之后利用一下命令创建ssh连接:
$ ssh-keygen -t rsa -C "youremail@example.com"
(如果你的用户主目录的.ssh文件下已经有了id_rsa和id_rsa.pus两个文件就不用执行上一步,其中前者存放你的私钥,后者存放你的公钥)
然后登陆你的github账号,在个人中心的ssh key中添加新的ssh key,然后将id_rsa.pus的内容复制到add new key的文本框里就可以了(这里没有添加passparse故没有设置ssh-agent)。
详细的官方教程:点我啊
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。你可以关联其他人的github仓库,但是你没发推送因为你电脑的公钥不在对方账户的ssh key列表里。
2、本地库关联到远程库:git remote add origin git@server-name:path/repo-name.git;
(server-name是服务器的名字,如:github.com;path是远程仓库的路径,在github中是你的用户名; repo-name是远程仓库名)
第一次推送分支内容,要加参数u(例子为master分支):git push -u origin master;
之后的推送更新命令:git push origin master
(pull: 远程库->本地 push:本地->远程库)
3、克隆远程库:git clone git@server-name:path/repo-name.git
分支管理:
1、查看所有分支:git branch
2、创建新分支并切换:git checkout -b <branch-name>(这是只是在暂存区)
【可以分成两条命令:创建git branch<branch-name>和切换git checkout <branch-name>】
你在分支b做的所有事情,如果你还没有合并,则当你切换回分支a时,你是看不到你在分支b做的事情的,例如在分支b下,你在
readme.txt文件中添加了一句话“branch test”,并且执行git add和git commit命令,之后切会分支a,打开readme.txt文
件,你会发现你添加的那句话不在里面。
3、合并分支:git merge <branch-name> (命令git merge是将当前分支与你指定的分支合并)
(普通合并为:git merge --no-ff -m "log text" <branch-name>)
4、删除分支:git branch -d <branch-name>
5、保存当前工作状态:git stash
查看此分支保存的工作状态:git stash list
恢复工作状态:
方法1:git stash apply stash@{n}恢复指定的状态n(不加stash@{n}则默认为最近的工作状态)
再执行 git stash drop进行删除
方法2:git stash pop (恢复最近保存的工作状态)
(当你开开心心的在做今天的工作时,突然有人跟你说你前两天写的代码有bug要进行修复,但是你现在手头上工作还没做完,直
接提交的话不是一个好习惯【防止他人在这个时间点pull到的是你这未完成的工作,埋雷】,这时就可以用该命令将你现在的工
作状态保存下来,这样你就能够去创一个新的分支修复前两天的bug,改好bug后再回到你之前工作的分支,重现工作状态。)
6、强制删除一个未被合并的分支:git branch -D <branch-name> (将参数d改成D)
多人协作:
-
首先,可以试图用
git push origin branch-name
推送自己的修改,如果远程库没有该分支将会自动创建; -
如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并; -
如果合并有冲突,则解决冲突,并在本地提交;
-
没有冲突或者解决掉冲突后,再用
git push origin branch-name
推送就能成功!
如果git pull
提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命
令git branch --set-upstream branch-name origin/branch-name
。
标签管理:
标签实际上是指向某个commit的指针,类似于分支,但是标签不能移动。git设置标签的目的是为了方便查看commit
信息不用去记复杂commit id
1、新建一个标签:git tag <name> <commit-id>
如果没有commit-id则默认为接下来的第一次commit打上标签
2、创建带有说明信息的标签:git tag -a <tagname> -m "blabla"
3、用pgp签名标签:git tag -s <tagname> -m "blabla"(前提是你配置好了gpg)
4、查看所有标签:git tag
5、查看指定标签:git show <tagname>
6、推送标签到远程库:git push origin <tagname>
7、推送所有未推送过的本地标签到远程:git push origin --tags
8、删除本地标签:git tag -d <tagname>
9、删除远程指定标签:git push origin :refs/tags/<tagname>
忽略特殊文件:
有时你的git工作区不得不存放你的数据库密码等等的配置文件这一系列其他敏感信息或者一些非文本文件(如编译过程产生的.class文件、.pyc文件等),这时你可以编写.gitignore文件(使用windows的同学可以使用文本编辑器的“另存为",这样就不会提示你要输入文件名字了),文件里是你想要忽略的特殊文件名,然后将.gitignore文件提交到git仓库里,这时你可以尝试add该特殊文件,git将会告诉你无法add,因为在.gitignore文件中规定要忽略这个文件了。
.gitignore文件的内容像这样:
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:
db.ini
deploy_key_rsa
命令设置别名:
有时候命令太长,你可以为该条命令设置简单的别名,到时候直接调用这条别名
例如:
git config --global alias.st status (其中加上参数--global是对该系统当前用户都适用,不加就只对当前仓库)
这时你就可以通过命令:git st 查看状态了
(这里给个实用的:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
试着用git lg查看日志吧!你会发狂的!)
要删除的话,就找到对应的配置文件(用户目录下的.gitconfig文件或当前仓库下的.gitconfig),打开后删除对应行
自行搭建Git服务器:
如果你不想使用github的话,可以自己搭建git服务器,这里我就不写了,网上一搜都有。
——强烈推荐从这里学习git,非常详细,感谢廖雪峰老师