简单的学习了 git 一下自己的理解 方便回顾

git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。 最早,肯定只有一台机器有一个原是版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,没有主次之分。
一台电脑上也可以克隆多个版本库,只要不在同一个目录下。
分布式版本控制的好处之一,完全不需要考虑远程库的存在,也就是没有网络的情况下是可以正常工作,当有网络的时候,再把本地提交推送一下就完成了同步。而SVN在没有联网的时候是拒绝干活的。

//锁定文件  防止  git pull的时候同步代码  和本地代码有冲突  导致代码丢失   先stash(锁定)代码   再 pull(拉)代码  然后 stash pop (释放)代码   最后 解决冲突。
git stash    锁定文件  可以多次  stash    用git stash list  可以查看stash几次代码
恢复文件
git stash apply  还原之前的文件   
git stash pop   在提交之后再pop还原之前的文件
两者的区别   git stash list  可以查看  stash了几次     pop恢复文件  会把list中的记录删除   apply恢复不会删除  
git stash apply stash@{0}   恢复到哪一次stash代码的状态


在提交代码的时候   如果在服务器上abandon掉
在git上输入  git reset HEAD~  一次才行
不然代码提交不上去

git版本控制分为四块   
工作区        正常写代码的区域
暂存区        通过 git add <file> 命令   把文件添加到暂存区
本地代码库    通过 git commit <file> 命令 把代码提交到本地代码库   commit之后 暂存区就没有任何内容了
远程代码库    通过 git push origin HEAD:远程分支   把代码提交到远程代码库

//查看修改
git status  查看仓库当前的状态,有无文件修改,有无文件添加或删除
git diff <file>  文件名可以加也可以不加  用来查看文件修改的内容  有文件名是查看当前文件的修改  无文件名
git diff HEAD -- <file>  查看工作区文件和代码库文件的不同(区别是 HEAD 可以针对不同的版本去比较  HEAD可以换成commit id)
git diff --cached 查看暂存区内的内容与版本库里最新版本的差别

//版本回退
git log  查看git仓库中的版本数量   提供的版本信息比较全面  版本号   作者  日期 都有   但版本比较多  容易让人眼花缭乱   简洁的版本信息  用  git log --pretty=oneline
回退版本   git内部是通过指针指向每一个版本的HEAD  所以回退的很快
注意Git的版本号(commit id)是SHA1值ea34578d5496d7dd233c827ed32a8cd576c5ee85
$ git reset --hard HEAD^   // 退回到相对于当前版本的上一个版本 HEAD 表示当前版本
$ git reset --hard HEAD^^  // 退回到相对于当前版本的上上一个版本  HEAD 代表当前版本
$ git reset --hard HEAD~100 //退回到相对于当前版本的上 100 个版本去  HEAD 表示当前版本
$ git reset --hard 3628164  // 退回到指定的版本   这里不需要全部写commit id  Git 回去自动适配
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL

$ git reflog   // 在退回到旧版本之后可以查看旧版本之前的提交日志
当我们想从一个旧版本退回到新版本但是我们关闭了shell窗口,不能查看之前的commit id了,就可以通过
$ git reflog 查看到之前的版本的commit id

//撤销修改
git checkout -- <file> 丢弃工作区的修改   就是把<file>文件在工作区的修改全部撤销, 这里有两种情况
    一种是<file>自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态
    一种是<file>已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加暂存区后的状态。
    总之,就是让<file>回到最近一次git commit和git add时的状态。
git checkout -- <file>命令中的 -- 很重要,没有 -- ,就变成了“切换到另一个分支”的命令

如果文件修改只是通过git add 添加到暂存区,还没有commit
可以用命令  git resete HEAD <file>可以把暂存区的修改给撤销掉,重新放回工作区  git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。在通过 git checkout -- <file> 来回退工作区的修改

如果文件commit提交到本地版本库  但是没有提交到远程分支
直接通过 git reset --hard HEAD^ 直接回退到上一个版本

//删除操作
在本地删除一个文件  git stauts 会告诉你 有本地文件删除了  
    如果文件没用  可以 git rm <file>直接删除
    如果是误删文件  通过 git checkout -- <file> 轻松恢复误删的文件   git checkout -- <file> 的作用就是用版本库郦的版本替换工作区的版本,无论工作区是修改还是删除都可以一键还原
git rm <file>用于删除一个文件,如果一个文件已经被提交到版本库,那么你永远不用担心误删文件,但要小心,你只能恢复文件到最新的版本,你会丢失最近一次提交后的修改内容

//推送到远程仓库
git push -u origin master   由于远程仓库是空的,所以第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送到远程新的master分支,还会把本地的master分支和远程的
master分支关联起来,在以后的推送或者拉取是就可以简化命令。  以后提交可以直接使用命令 git push origin master 推送最新修改。
origin是远程仓库的名字,这是Git的默认叫法,也可以改成别的,但origin这个名字一看就知道是远程仓库。

//远程仓库克隆到本地
正常使用git版本控制的流程是  先创建远程仓库   然后使用 git clone 命令克隆,git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。多人协同开发的时候,创建远程仓库,让每个人去远程仓库克隆代码就OK了。

//分支管理
分支就是科幻电影里的平行宇宙,当你正在电脑前努力学习git的时候,另一个你在另一个平行宇宙中学习SVN,如果两个平行宇宙互不干扰,那对现在的你也没啥影响。
不过,在某个时间点,两个平行宇宙合并了,结束即学会了git还学会了svn。
分支在实际中有什么用?加上你准备开发一个新功能,但需要两周才能完成,如果立刻提交,由于代码没写完,导致别人不能干活,如果全部写完提交,代码丢失的风险太大,
有了分支之后就不同了,创建一个属于自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,互不影响,直到开发结束,一次性合并到原来的分支上,即安全,有不影响别人干活。

//分支操作
每次提交,git就会把它们串成一条时间线,这条时间线就是一个分支,只有一条时间线,在git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以HEAD指向就是当前分支。
开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点。
当我们创建一个新的分支,例如dev,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上,Git创建一个分支很快,除了增加指针,改下HEAD的指向,工作区域的文件没有任何变换。
从现在开始,每次提交dev指针往前进一步,而master指针不变。假如在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并?最简单的就是把master指向dev的当前提交,就完成了合并。
所有Git合并分支也很快,就改改指针,工作区内容也不变,分支合并完成后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master主分支。
1.创建dev分支,然后切换到dev分支,  git checkout -b dev   -b 参数表示创建并切换,相当于两条cd 命令  git branch dev git checkout dev;
2.查看所有分支  当前所在分支   git branch   前面有×号,表示当前所在分支。  我们就可以在dev分支上正常提交了。
3.dev分支代码完成,切换回master分支; git checkout master    master分支还是之前的状态,因为之前的提交是在dev分支上提交的。
4.把dev分支的工作成果合并到master分支上   git merge dev   git merge命令用于合并指定分支到当前分支,合并后就可以看到之前修改提交的内容。
注意提示信息中会有Fast-forward信息,git告诉我们,这次合并是快进模式,也就是把master直接指向dev的当前提交,所以合并速度非常快。 当然,不是每次合并都能Fast-forward,还有其他的合并模式。
5.合并完成后,删除dev分支。 git branch -d dev

//合并出现冲突  无法快速合并(先解决冲突,解决冲突后,再提交,合并完成)
git status  可以告诉我们冲突文件   去冲突文件中解决冲突    HEAD是本地的     ========   后面的是  冲突的代码
git add <file> 把冲突文件添加到暂存区   表示标记冲突解决
git commit  表示冲突解决完成  提交

git log --graph    可以看到git 分支合并的图谱  很清晰的可以清除当前git 分支的情况
git log --graph --pretty=oneline --abbrev-commit    单行显示提交的信息    上面代码显示的是信息完全的信息

git在团队开发的时候   合并分支最好不要用fase-forward模式合并  因为fast-forward合并看不出来曾经合并过
合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。( git merge --no-ff -m "merge with no-ff" dev) 把dev分支合并到主分支

开发一个新功能最好在一个新的分支上面   
如果要删除一个没有被合并的分支,可以通过  git branch -D <name>  强行删除


//多人协同开发工作模式
1.首先,可以试图用git push origin branch-name 推送自己的修改
2.如果推送失败,则因为远程分支比你本地的新,需要先git pull试图合并;
3.如果合并有冲突,先解决冲突,并在本地提交
4.没有冲突或者解决冲突后,再用git push origin branch-name就可以推送成功。
如果git pull 提示 “no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令 git branch --set-upstream branch-name origin/branch-name.



//查看远程库信息    git remount -v


//git打标签  对应commit  因为commit对应的版本号很不好记   打上标签就很方便查找   tag是全局的tag,没有不同分支下tag这个概念,tag不属于某一个分支
git tag  查看所有标签
git tag <name> 就可以打一个新标签     可以用说明标签 -a 指定标签名  -m 指定说明文字
如果之前的标签忘记打了  现在想起来想添加一个   git tag <name> <commitID>  就可以添加上去了
git show <tagname>  可以查看 tag对应的commitID  

//删除标签   因为标签只保存在本地 不会自动推送到远程   所以打错标签可以在本地安全删除
git push origin <tagname> 把某个标签推送到远程
git push origin --tags   把标签全部推送到远程

如果标签在远程删除起来就比较麻烦  先从本地删除  在去远程删除
git tag -d <tagname>  本地删除标签
git push origin:refs/tags/<tagname>  删除远程标签

posted @ 2017-06-08 16:36  wlwqnj  阅读(1015)  评论(0编辑  收藏  举报