zoukankan      html  css  js  c++  java
  • Git

    Git是分布式版本控制系统,SVN和CVS是集中式版本控制系统。

    集中式和分布式的区别?

    使用方式:

    1.建一个空文件夹(或者说一个目录)learnGit,不一定要是空的

    2.git init把这个目录变成git可以管理的仓库

    所有的版本控制系统,都只能跟踪文本文件的改动,txt,网页,程序代码等。图片,视频属于二进制文件,也能用版本控制系统管理,但是没法跟踪文件的变化,只能知道改了多少数据量(比如10k),但是不知道具体改了什么

    微软的word是二进制格式,所以不能用git管理。

    编码问题,强烈建议使用标准的UTF-8编码!

    不要使用微软自带的记事本编辑文本

    写好一个文件,比如readme.txt在learnGit下,cd 到这个目录,然后git add readme.txt,把文件添加到仓库

    然后git commit -m “worte a readme file”

    -m后面是本次提交的说明

    一句commit可以提交多个文件,比如add了两个文件进去,commit一次提交多个文件。

    之后我们修改了readme文件的内容,这个时候再git status,这条命令可以知道当前仓库的状态,比如这里是readme被修改了,但是没有提交

    要如何看到到底修改了什么内容呢?git diff readme.txt,可以看到变化的是git is free变成了git is a free software

    git status 查看有哪些改动

    git dff 查看改动的具体内容

    知道修改了什么,觉得没问题,可以提交就可以add进仓库了,然后再git status查看一下,Git提示将被提交的是readme

    然后commit后,再git status,可以发现就没有要待提交的文件了,工作目录是干净的 working directory clean

    版本回退

    然后不断的修改,用git log可以查看查看历史记录

    log太长可以可以加上--pretty=oneline查看精简版的log,前面长串的“乱码”是commit id(版本号),这个东西通过SHA1计算出来的

    当前的readme是这样的

    要如何回到之前的版本呢?要回滚Git必须知道版本号,Git用HEAD表示当前版本,上一个版本叫做HEAD^,上上个版本叫HEAD^^,往上100个版本叫做HEAD~100

    再git log的时候,发现少了append GPL那条了,那我又后悔了,要如何再滚回来呢?这个时候如果命令行没有关闭,是可以查到之前的append GPL对应的版本号的,然后就可以reset了

    注意:版本号可以不用写全的,比如这里本来是05a870e,但是我只打了05a8也是可以的。现在readme又回到有GPL的这个版本了。那如果命令行已经关闭了,要怎么办?

    用git reflog,清楚的记录了每一次命令,这里从前面三条可以看到滚回到前一个版本,然后又滚回来,然后又滚回去,所以现在readme是上一个版本,下面的第四条可以看到GPL这个版本的版本号,

    有了版本号就可以再滚回最新版本了

    git log和git reflog的区别?

    git log可以查看提交历史(只有commit)

    git reflog可以查看命令历史(比如会包括reset这种)

    版本回滚的原理是Git内部有个指向当前版本的HEAD指针,在回滚的时候,git只是移动下这个指针,然后把工作区的文件改了而已

    暂存区

    工作目录Working Directory,就是电脑里能看到的目录,比如learnGit这个文件夹

    版本库repository,工作目录下的.git隐藏目录就是版本库,版本库里放了很多东西,最重要的就是叫做stage的暂存区,Git自动创建的master分支,以及master的一个指针HEAD

    git add实际上是把文件添加到暂存区

    git commit把暂存区的所有内容提交到当前分支

    也就是说如果修改了但是没有add到暂存区,那么commit的时候就不会commit这次的修改

    撤销修改

    这时,修改了readme,然而没有add进暂存区,然后发现这个修改不行,可以checkout -- filename来撤销掉这次的修改

    如果已经add到暂存区了,要撤销这个修改,要先把暂存区的这个修改unstage,重新放回到工作区。

    使用git reset HEAD file

    下图可以看到,本来readme的修改是Changes to be committed,变成了Changes not stage for commit

    也就是说这个修改已经滚出暂存区回到工作区了,然后再像之前说的checkout -- file就可以将这个修改撤销掉了

    如果已经commit了,那么就用之前的 git reset --hard commit_id 来回滚

    删除文件

    删除也是一种修改。比如,新建一个test,然后提交。

    删除可能出现在资源管理器中删除,或者rm,这个时候Git知道你删掉了文件,工作区和版本库就不一致了,再git status就会看到哪些文件被删除了。

    这个时候有两种选择(情况):1.确实是要删掉;2.删错了

    如果确实要删掉,那么git rm test,然后git commit,这样就可以把版本库里的删除掉了

    如果删错了,因为版本库还有一个,所以可以用git checkout -- test恢复。这里的恢复就是将版本库里的版本替换中工作区的版本,无论是修改还是删除,都可以这样干

    注意rm和git rm的区别

    rm删除一个文件,操作的是工作区的。

    git rm是提交一个操作(rm)到暂存区,然后再commit这个操作到版本库(可以在执行该命令后通过git status来查看),这样Git就把版本库里的对应文件删除了。再执行这个命令的时候,会自动执行rm,也就是说会自动把工作区的文件删除了。

    远程仓库

    远程仓库有两个用处:代码备份,协作完成

    1.先有本地仓库

    在GitHub点击New Repository新建一个仓库。Repository name填learngit

    cd到learnGit文件夹:

    将本地仓库跟远程仓库关联:git remote add origin https://github.com/Yuijam/learngit.git 

    把当前分支推送到远程:git push -u origin master

    再刷新一下远程库,就可以看到本地提交过去的东西了

    2.先有远程仓库

    新建一个仓库gitskills,勾上初始化README选项,其余默认

    克隆到本地:$ git clone https://github.com/Yuijam/gitskills.git 

     

    GitHub提供两种协议,SSH和HTTPS,SSH我没有成功,可能是公司网络端口的问题?

    据说SSH比较快,HTTPS比较慢,而且每次push都要输入口令

    分支

    HEAD严格的说不是指向提交,而是指向master,master指向提交,HEAD指向的是当前分支

    一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点

    每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长

    这个讲得很清楚了

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840038939c291467cc7c747b1810aab2fb8863508000

    新建一个分支。-b参数表示新建一个分支并切换到这个分支,相当于两条命令 git branch dev , git checkout dev

    使用git branch查看当前分支。会列出所有分支,打*号的是当前分支

    修改readme并提交,然后切换到master,发现readme没有变,因为是在dev分支上改变的,所以当然没有改变

    用git merge dev将dev分支合并到当前分支,也就是master,再查看一下readme发现确实改变了,然后删除掉dev分支。Git鼓励使用完分支后,合并代码,然后删掉分支这种做法,因为过程安全。

    处理冲突

    合并并不会总是一帆风顺

    新建一个分支 featurel并修改readme,然后add,commit。

    再回到master分支,修改readme,add,commit。

    合并两个分支,出现冲突,并且指明了是在readme,这个时候git status可以看到具体情况,都修改了readme。注意到这里由(master)变成了(master|MERGING)

    那么怎么办?

    要处理完冲突再提交。可以直接查看到readme的内容变化了,Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容

    然后修改好readme,commit提交即可。用git log --graph --pretty=oneline --abbrev-commit可以查看到分支的合并情况。

    分支管理策略

    再新建并切换到dev分支,修改readme(注意,这里就只在下面添加一行hhh,如果在内容里面改,下面就需要处理冲突),并add,commit

    切换到master,git merge dev合并。注意这里切换回master后并没有修改什么东西,也没有提交什么东西。

    看到log有点奇怪,居然少了分支信息!!!

    要怎么才能看到做过合并呢?

    git merge --no-ff -m "merge with no-ff" dev

    这样就看到分支历史了。原因是合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

    --no-ff参数,表示禁用Fast forward。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

    Bug分支

    有这样一种情况,你在dev分支下做某个功能,做到一半,接到一个任务,处理一个bug,比如这个bug是在master分支下的

    这个时候因为代码没写完,不好提交,然后又要去处理那边的bug,怎么办?可以用git stash把工作现场储藏起来,等之后恢复现场后继续工作。

    这里readme修改后没有add,在git stash后再查看git status发现工作区已经是干净的了。

    然后再切换到master分支,新建一个issue101的分支来修复bug(这里用在readme里面添加一行 fix bug表示),然后add,commit后再切换到master,合并分支,然后删掉issue101

    这个时候bug修复好了,就可以回来继续之前dev的未完成的工作了。

    通过git stash list来查看之前的工作现场。要恢复有两个办法:

    1.用git stash apply来恢复,但是恢复后,stash内容不会删除,要继续用git stash drop来删除

    2.用git stash pop来恢复,恢复的同时把stash内容也删除

    这里用git stash pop恢复,然后再git stash一下发现里面没有东西了

    git status可以看到工作区的内容恢复了。

    当有多个stash时,也就是list里面有多个时,可以用git stash apply来指定要恢复哪个

    git branch -D branch-name 来删除未合并的分支,注意这里是大写的D,写d没用

    多人协作

    远程仓库的默认名是origin

    查看远程仓库的信息,用git remote

    git remote -v 可以显示更详细的信息:

    下面显示了可以抓取和推送的origin地址。

    推送分支

    git push origin master 表示把本地master分支推送到远程origin仓库

    也可以推送其他分支,比如 git push origin dev

    并不是所有分支都要推送过去,视情况而定, 比如bug分支

    当从远程clone时,默认情况下,只能看到本地的master分支,比如远端有一个dev分支,clone过来git branch一看发现只有master一个分支

    用 git checkout -b dev origin/dev 创建远程origin的dev分支到本地,这样就可以继续在dev下修改了

    如下图

    当你在dev做了修改,比如修改了readme,添加了一句 linux edit,add commit 没问题。

    这个时候准备push的时候,如果有人也修改了dev的readme,然后push上去了。这个时候你去push就会出问题,如下

    git提示需要git pull,那么就git pull一下,结果发现自动合并失败。要处理冲突,处理冲突

    解决冲突的办法跟之前解决冲突一样的,也是修改了readme后,add,commit,然后再push就没问题了。

    因此,常用的步骤是这样的:

    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

    标签管理

    发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。

    Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。

     

    打标签步骤:

    1.切换到要打标签的分支

    一般是master?master代表着要发布的稳定版本。dev也是可以的。

    2.git tag v1.0

    这样就打了一个标签。默认标签是打在最新提交的commit上的,如果要打以前标签,怎么打?也就是说要怎样给指定的commit打上标签

    方法是找到历史提交的commit id

    用 git log --pretty=oneline --abbrev-commit 查看到历史commit,找到要打tag的commit id

    然后git tag <tagname> <commit-id>就可以了

    git tag可以查看所有标签

    git show <tagname>可以查看标签信息

    创建带有说明的标签: git tag -a v0.1 -m "version 0.1 released" <commit id>

    删除标签

    git tag -d v0.1

    tag不会自动推送到远程,所以这里可以在本地删除。

    推送标签到远程

    git push origin <tagname> 

    如果tag已经推送到远程了,这时要删除就要这样搞

    1.先把本地的tag删除了

    git tag -d v1.0

    2.再把远程的删除了

    git push origin :refs/tags/v1.0

    可以到github上的release那里看看是否真的删除了

    忽略文件 

    提交的时候有些比较重要的文件,比如各种key什么的,密码什么的不希望提交,这个时候怎么办?

    1.在工作区新建一个 .gitignore 文件,把要忽略的文件名填进去,Git就会自动忽略这些文件了

    比如在文件里写上:

    *.txt

    Git在就会把txt忽略掉

    配置别名 

    单词太长?那就取个别名

    比如用 co代替checkout ,用 br 代替 branch,可以这样写

    git config --global alias.co checkout

    git config --global alias.br branch

    --global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用

    在撤销修改一节中知道,git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回到工作区。既然是一个unstage操作,就可以配置一个unstage别名

    git config --global alias.unstage 'reset HEAD'

    这样当敲 git unstage test.py 

    实际执行的就是 git reset HEAD test.py

    配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用

    每个仓库的Git配置文件都放在.git/config文件中

     

    当前用户的Git配置文件放在用户主目录下的一个隐藏文件 .gitconfig中。如下图,可以看到里面包含了之前设置的别名,所以配置别名也可以直接修改这个文件。或者从这个文件中删除别名。

  • 相关阅读:
    Linux软件安装中RPM与YUM 区别和联系
    Linux分区类型EXT2、EXT3、EXT4详解
    【转】SQLServer数据库还原数据库后因孤立用户问题导致无法登陆的处理
    CVE-2018-8045 Joomla内核SQL注入漏洞
    SQL注入漏洞靶场-sqli-labs学习[1-10]
    SQL注入漏洞
    文件包含漏洞
    CSRF的攻击与防御
    XSS漏洞的基本原理
    Linux高性能服务器编程(一):TCP/IP协议族
  • 原文地址:https://www.cnblogs.com/i-love-kobe/p/6722278.html
Copyright © 2011-2022 走看看