zoukankan      html  css  js  c++  java
  • 廖雪峰Git教程学习笔记

    廖雪峰git简单教程学习笔记

    教程地址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
    1、可以这样设计目录,在d: eposisoty 在这个目录下面有很多的仓库。
    mkdir learngit
    cd learngit
    >>git init          #这样就把learngit 初始化成了一个仓库
    >>git status        #说明当前仓库的状态并且会提醒你可能可以做的操作
    在learngit目录下面新建一个文件readme.txt,并添加到git仓库中,一次如下的操作
    >>git add readme.txt
    >>git commit -m "wrote a readme file"   #-m后面是说明性的文字,方面查看修改的内容
    把一个文件提交到git仓库中分为上面两部,add命令可以一次添加很多文件,依次用空格分开,比如向下面这样:
    >>git add file1.txt file2.txt
    >>git commit -m "add 2 files"

    2 版本、撤销……相关
    2.1 修改上面创建的 reame.txt文件的内容,然后
    >>git status    #这个命令可以让我们时刻掌握仓库当前的状态。
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)

            modified:   readme.txt

    no changes added to commit
    上面的信息告诉我们readme.txt被修改了,但是还有装备调教的修改,这是我们可以使用git diff来查看做出了怎样的修改。
    >>git diff readme
    diff --git a/readme.txt b/readme.txt
    index 629f6b7..be836b4 100644
    --- a/readme.txt
    +++ b/readme.txt
    @@ -1,2 +1,2 @@
    -Git is a version control system
    +Git is a distributed version control system
     Git is free software
    No newline at end of file
    -表示这一行消失了,+表示这一行是后来出现的
    知道文件做了什么修改,这时我们可以放心的提交文件了。
    >>git add readme.txt
    >>git status 会提醒当前的工作目录的状态
    >>git commit -m "add word distributed"
    commit 就是一个快照功能,当你玩DevilCry的时候没过一关,游戏都会有一个存档,当你下次登录游戏的时候可以接着之前的关卡打怪。在git中每次我们git commit -m 时就是我们手动存档。

    2.2 版本回退
    就是会到对应的commit快照点。可以使用git log 来查看所有的commit点
    >>git log       #列出对应的commit点
    如果嫌输出的内容较多可以加上参数 --pretty=oneline
    git log --pretty=oneline    如下:
    8debcc13d05bd5627a01c875e20780523f572ba7 append gpl
    dc79b71e4175992e89c3539c10710ad87a2fd54e add a word [distributed]
    e0e4517d9b45969ba73b111bc59a42f7a97fe71a wrote a readme file

    在git中,当前版本用HEAD表示,上一个版本用HEAD^,上上一个版本用HEAD^^,一次类推,当然太多的时候,^数不清,这个时候我们用HEAD~100表示之前的第100个版本。
    >>git reset --hard HEAD^    就会回退到前一个版本
    这是在查看git log --pretty=oneline会发现只剩下两个commit了。
    dc79b71e4175992e89c3539c10710ad87a2fd54e add a word [distributed]
    e0e4517d9b45969ba73b111bc59a42f7a97fe71a wrote a readme file
    如果再想回退到最新的版本。这是可以使用git reflog 来查看命令历史:
    $ git reflog --pretty=oneline
    dc79b71 HEAD@{0}: reset: moving to HEAD^    #注意 使用commitid时,只需要7位就够了
    8debcc1 HEAD@{1}: commit: append gpl
    dc79b71 HEAD@{2}: commit: add a word [distributed]
    e0e4517 HEAD@{3}: commit (initial): wrote a readme file
    使用下面的命令:
    git reset --hard 8debcc1

    2.3工作区和暂存区
    工作区(working directory)就是你在电脑中能看到的一个目录,比如之前创建的learngit
    版本库(Repository)就是工作区中的一个隐藏的目录.git,这个不算是工作区,而是git的local版本库..git中存放了很多的东西,其中最重要的就是stage(或者称之为index)的暂存区,还有一个git为我们自动创建的master分值,以及一个纸箱master的指针叫做HEAD.HEAD和branch的概念后面介绍。
    在来 回头看前面网Git版本库中添加文件的操作,是分两步执行的:
    1)git add filename :实际上是把文件修改添加到暂存区;
    2)git commit提交更改,实际上是把暂存区的所有内容提交到当前的分支branch
    因为我们创建Git版本库的时候,Git自动为我们创建了一个分支branch master,所以现在git commit就是网master上面提交东西(因为当前只有一个分支)。一旦使用commit之后,就会吧stage(暂存区)中的内容提交到版本库中的某一个branch,清空stage。

    2.4 管理修改。
    为什么Git比其他的版本控制系统设计的优秀,因为Git跟踪管理的是修改,而不是文件。Git中修改(changge)是一个广义词,新增一个文件也是一种修改,说这句话的对象是相对于整个Git仓库而言的。
    每当我们对某个文件修改之后,如果不add到暂存区,那就不会加入到commit中。

    2.5 撤销修改
    1)场景:你修改了working flow中的文件,然后别的什么都没做,比如你在readme.txt中加了一行,my stupid boss...。你如果想撤销这个修改。因为这个修改只是在工作区,可以有下面两个选择:
        i)手动删除掉readme.txt的内容
        ii)>>git checkout -- readme.txt.这条语句可以把readme.txt在工作区的修改全部撤销。这条命令执行以后会让文件回到最近一次git commit或者git add时的状态。
    2)场景:在工作区修改完以后,执行了
    git add readme.txt
    操作,这时修改已经到了stage暂存区了,也就是说在commit的话,就要进入本地版本库的某一个branch了。这时stage中的内容是我们不想要的,如果此时commit的话,版本就要被刷新了,因为已经执行过了add操作,所以working flow和stage中的readme.txt是一样的,这时要想撤销修稿,我们可以使用如下步骤:
        i)git reset HEAD readme.txt然后在丢弃工作区的修改,使用场景1)中指令:
        ii)git checkout -- readme.txt
    3)场景:已经完成了git commit -m "message"也就是说,影提交到本地的master分支了,这个时候使用前面提到的,版本回退指令:
    get reset --hard HEAD^.
    如果已经把修改提交到了远程的代码仓库,那么久无力回天了。

    说明:要经常用git status指令,并且要回看懂其返回的状态信息:当前branch,接下来怎么做,具体的修改内容是什么。
    1)修改working flow中的readme.txt文件之后
    $ git status
    On branch master                #当前在master branch
    Changes not staged for commit:  #还没有add到stage,你可以选择下面的两个操作
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)

            modified:   readme.txt  #具体“什么操作”修改了“那个文件”

    no changes added to commit (use "git add" and/or "git commit -a")
                                    # 还没有提交commit
                                    
    如果git add readme.txt之后:
    $ git status
    On branch master                #当前所在的branch
    Changes to be committed:        #说明当前git已经吧修改提交到了stage等待下一步commit
      (use "git reset HEAD <file>..." to unstage)

            modified:   readme.txt  

    2.6文件的删除与恢复
    比如在learngit中新建了一个文件 tet.txt
    git add test.txt
    然后 吧文件添加到stage中,git add test.txt
    rm test.txt 删除文件
    这种情况下可以使用git checkout -- test.txt从 stage中吧文件回复出来
    另一种情况,是add test.txt之后然后commit,这个时候rm test.txt可以使用 git reset --hard test.txt回复

    3 添加远程仓库
    3.1 公共的代码托管仓库是GitHub,当然你也可以搭建自己的Git服务器。这里介绍的是GitHub。当然首先你应当注册一个Github的账户。Git和支持SSH加密通信协议。
    1)创建SSH KEy。当然创建之前可以先查看一下主目录下面有没有.ssh目录,这个目录里面(win7.ssh目录在C:usersadministrator下面)有两个文件:id_rsa和id_rsa.pub,这两个是SSH Key的密钥对,前者是私有的,不能泄露,后者是公开的用来告诉别人的。如果没有的话,使用下面的指令创建:
    ssh-keygen -t rsa -C "1373779753@qq.com"    #生成 SSH Key,找到上面的文件,把id_rsa.pub中
        的内容拷出来。或者使用下面的指令:
    clip < ~/.ssh/id_rsa.pub    #把公共密钥拷贝到剪贴板。
    2)登录github账号,然后在setting中add ssh key出,new ssh key,标题任意,粘贴内容。
    为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
    当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。

    3.2本地有了一个Git仓库,可以在远程的GitHub上面创建一个仓库,远程的仓库既可以作为备份也可以开源给别人。
    1)先登录GitHub默认条件创建一个repository,learnit。
    2)在本地仓库的Git bash中执行下面的指令,就可以吧本地的Git和远程的Git关联
        git remote add origin git@github.com:yingquliang/learngit.git
    添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
    3)git push -u origin master
    把本地库的所有内容推送到远程库上。远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支。以后就可以不加 -u参数直接使用:
    git push origin master

    3.3从远程克隆。
    更多的我们都是先在Github远程端上创建一个仓库,然后每个人克隆到本地开始工作。
    在github上创建一个远程仓库 gitskills并勾选使用 README.md初始化。还是记住ssh的传输地址,在本地git bash中克隆:
     git clone git@github.com:yingquliang/gitskills.git
     要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
     
     4.分支管理
    分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
    现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
    4.1创建与合并分支
    分支到底是个啥,Git把每次提交的commit穿成一条时间线,这条时间线就是一个分支。
    Git本身就是linux之父用C语言写的,所以呀git里面其实是有很多指针的,这一章节关于分针的原理讲解就是指针的指向变化。
    当只有一个主分支master时,master指向的是当前的提交commit,而HEAD指向的是master,所以HEAD就指向了当前的分支。伪码描述:
        master  = current_commit;
        HEAD    = master
    当然上面的操作都是git完成的,上面只是为了更好的说明原理。
    创建一个新的分支,那么新分支就会指向master,然后head就只想当前的新分支,后续的操作都在新分支上,创建分支的原理如下:
        dev     = master
        head    = dev   之后的commit就在dev分支上
    合并分支:master = dev
    合并之后,就可以删除 dev = null
    当然上面的伪码描述的知识原理。具体的生动详细的讲解,见廖雪峰的页面:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840038939c291467cc7c747b1810aab2fb8863508000

    在当前的分支创建一个新的分支的方法:
    git checkout -b dev     #创建新的分支dev,并切换到这个新的分支,这条指令是下面两条的缩写:
        git branch cev
        git checkout dev

    之后再做的commit都是提交到当前的分支dev的,把设置branch这个事情给记下来:
        git add readme.txt
        git commit -m "branch test"
        # 这些修改都是在新的分支dev上完成的
    dev分支的工作完成后,就可以换回到master分支
        git checkout master
    然后再问把dev分支上的共偶作成果合并到master分支上:
        git merge dev   # 默认情况吧dev分支合并到当前分支上面
        合并之后甚至都可以直接删除dev分支了:
        git branch -d dev 将会以fast-forward的快速删除方式删除dev扥之
    4.2 解决冲突
    创建一个新的分支feature1 进行后面的开发:
    git checkout -b feature1    #创建 + 切换到feature1分支        
        然后在这个分支上面修改readme.txt文件,修改最后一行.并把修改提交到当前的feature分支
        git add readme.txt
        git commit -m "AND simple"
    做完feature1上面的工作之后,切换回master目录,
        git checkout master #切换到master分支
        接着在master目录下面修改readme.txt文件修改之后,提交到mster。add  /   commit
    现在吧feature1 合并到 master上面将会报错,发生冲突,这种充足git会先尝试解决,解决不了的时候,才回跑出来,这个时候你只能手动解决冲突。
        git merge feature1
        Auto-merging readme.txt
        CONFLICT (content): Merge conflict in readme.txt
        Automatic merge failed; fix conflicts and then commit the result.
        这个时候可以打开查看readme.txt文件,发现下面会列出的不同分支发生冲突出逇内容。
    手动修改readme中对应错误提示下面的内容,然后 **再 add  commit即可
    然后可以使用下面的指令查看,用commit表示的 分支合并路径
    $ git log --graph --pretty=oneline --abbrev-commit
    *   5d0e866 conflicts fixed
    |
    | * 49e5cc0 AND simple
    * | 51c63ca & simple
    |/
    * 47fdfc1 branch test
    * a022dcf tack changes of files
    * c556222 git tacks changes
    * 898a3ab understand how stage work
    * 8debcc1 append gpl
    * dc79b71 add a word [distributed]
    * e0e4517 wrote a readme file
    最后再删除分支
    git branch -d feature1

    4.3分支管理策略
    直接使用 git merge dev命令合并dev分支时,将会使用fast-forward策略合并,fast-forward合并分支后,使用git log --graph是查看不到合并图的。为了避免这种情况的发生,可以在merge指令后面加上 --no-ff参数:
        git merge --no-ff -m "merge with no-ff" dev
            注意,这个指令会自动产生一个commit所以最好加上一条commitmessage
    然后再用 git log --graph --pretty=oneline --abbrev-commit查看
    分支策略
    在实际开发中,我们应该按照几个基本原则进行分支管理:
    首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
    那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
    你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
    所以,团队合作的分支看起来就像这样:


    4.4bug分支
    了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
    当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交。
    并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?
    幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
        $ git stash
    现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支
        $ git checkout master           #切换到主分支
        $ git checkout -b issue-101     #在主分支上创建bug修复的分支
    现在修复bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:
        git add readme.txt
        $ git commit -m "fix bug 101"
    修复完成后,切换到master分支,并完成合并,最后删除issue-101分支
        $ git checkout master
        $ git merge --no-ff -m "merged bug fix 101" issue-101
        $ git branch -d issue-101
    接着回到dev分支干活
        git checkout dev
        $ git status
        # On branch dev
        nothing to commit (working directory clean)
    工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看
        git stash list
        stash@{0}: WIP on dev: 6224937 add merge
    工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
        一是用git stash apply stash@{0}恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
        另一种方式是用git stash pop,恢复的同时把stash内容也删了
    再用git stash list查看,就看不到任何stash内容了.
    回复stash保存的工作现场的方法:
        git stash apply stash@{0}  #恢复到stash@(0) 工作现场
        git stash drop stash@{0}    #删除{0}工作现场
        或者下一条指令,直接完成上面两部的工作:
        git stash pop

    4.5Feature分支
    软件开发中,总有无穷无尽的新的功能要不断添加进来。
    添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
    你终于接到了一个新任务:开发代号为Vulcan的新功能,该功能计划用于下一代星际飞船。
    于是准备开发:
    $ git checkout -b feature-vulcan
    5分钟后,开发完毕:
        $ git add vulcan.py
        $ git status
        $ git commit -m "add feature vulcan"
    切回dev,准备合并.
    就在此时,接到上级命令,因经费不足,新功能必须取消!
    虽然白干了,但是这个分支还是必须就地销毁:
    $ git branch -d feature-vulcan
    销毁失败。Git友情提醒,feature-vulcan分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用命令
        git branch -D feature-vulcan。
        
    ###4.6多人协作
    `$ git remote    #查看远程库信息`
    origin
    或者,用git remote -v显示更详细的信息:
    `$ git remote -v`
    origin  git@github.com:michaelliao/learngit.git (fetch)
    origin  git@github.com:michaelliao/learngit.git (push)
    上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
    推送分支:就是把该分支上的所有本地提交推送到远程库----

     git push -u origin master  # 前面已经提及,origin(远程仓库)中,可能还没有master分支,向远成仓库推送本地master,首次推送时,要把本地的和远程的关联,使用-u参数。
       ``` $ git push origin master    #把本地master上面的commit都推送到远程的master上
        $ git push origin dev       #把本地dev上面的commit都推送到远程的master上```
        但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
        master分支是主分支,因此要时刻与远程同步; dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
        feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
    抓取分支
    多人协作时,大家都会往master和dev分支上推送各自的修改。
    模拟一个你的小伙伴,可以在另一台电脑(注意要把SSHKey添加到GitHub)或者同一台电脑的另一个目录下克隆 :
        $ git clone git@github.com:yingquliang/learngit.git
    当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支
        $ git branch
        * master
    现在,你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:
        `$ git checkout -b dev origin/dev`
    现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:
        $ git commit -m "add /usr/bin/env"
        [dev 291bea8] add /usr/bin/env
        1 file changed, 1 insertion(+)
        $ git push origin dev
        Counting objects: 5, done.
        Delta compression using up to 4 threads.
        Compressing objects: 100% (2/2), done.
        Writing objects: 100% (3/3), 349 bytes, done.
        Total 3 (delta 0), reused 0 (delta 0)
        To git@github.com:michaelliao/learngit.git
        fc38031..291bea8  dev -> dev
    你的小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:
        $ git add hello.py
        $ git commit -m "add coding: utf-8"
        [dev bd6ae48] add coding: utf-8
        1 file changed, 1 insertion(+)
        $ git push origin dev
        To git@github.com:michaelliao/learngit.git
           ! [rejected]        dev -> dev (non-fast-forward)
        error: failed to push some refs to 'git@github.com:michaelliao/learngit.git'
        hint: Updates were rejected because the tip of your current branch is behind
        hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
        hint: before pushing again.
        hint: See the 'Note about fast-forwards' in 'git push --help' for details.
    推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:
    git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
        $ git branch --set-upstream dev origin/dev
        Branch dev set up to track remote branch dev from origin.
    再pull:
        $ git pull
    这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push
        $ git commit -m "merge & fix hello.py"
        [dev adca45d] merge & fix hello.py
        $ git push origin dev
    因此,多人协作的工作模式通常是这样:
        首先,可以试图用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。
    这就是多人协作的工作模式,一旦熟悉了,就非常简单。

    5 标签管理
    发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
    Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。
    5.1创建标签
    在Git中打标签非常简单,首先,切换到需要打标签的分支上:
        $ git branch
        * dev
        master
        $ git checkout master
        Switched to branch 'master'
    然后,敲命令git tag <name>就可以打一个新标签:
        $ git tag v1.0
    可以用命令git tag查看所有标签:
        $ git tag
        v1.0
    默认标签是打在最新提交的commit上的。
    有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?
    方法是找到历史提交的commit id,然后打上就可以了:
        $ git log --pretty=oneline --abbrev-commit】
        6a5819e merged bug fix 101
        cc17032 fix bug 101
        7825a50 merge with no-ff
        6224937 add merge
        59bc1cb conflict fixed
    比方说要对add merge这次提交打标签,它对应的commit id是6224937,敲入命令:
        $ git tag v0.9 6224937
    再用命令git tag查看标签:
        $ git tag
        v0.9
        v1.0
    注意,标签不是按时间顺序列出,而是按字母排序的。
    查看 某个具体标签的信息:
        $ git show v0.9
        commit 622493706ab447b6bb37e4e2a2f276a20fed2ab4
        Author: Michael Liao <askxuefeng@gmail.com>
        Date:   Thu Aug 22 11:22:08 2013 +0800

            add merge……
    可以看到,v0.9确实打在add merge这次提交上。
    还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
    $ git tag -a v0.1 -m "version 0.1 released" 3628164
    用命令git show <tagname>可以看到说明文字:
        $ git show v0.1
        tag v0.1
        Tagger: Michael Liao <askxuefeng@gmail.com>
        Date:   Mon Aug 26 07:28:11 2013 +0800
        version 0.1 released
        commit 3628164fb26d48395383f8f31179f24e0882e1e0
        Author: Michael Liao <askxuefeng@gmail.com>
        Date:   Tue Aug 20 15:11:49 2013 +0800
        append GPL
    还可以通过-s用私钥签名一个标签:
        $ git tag -s v0.2 -m "signed version 0.2 released" fec145a 签名采用PGP签名,因此,必须首先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错:
        gpg: signing failed: secret key not available
        error: gpg failed to sign the data
        error: unable to sign the tag
        如果报错,请参考GnuPG帮助文档配置Key。

    5.2 操作标签
    如果标签打错了,也可以删除:
        $ git tag -d v0.1
        Deleted tag 'v0.1' (was e078af9)
    因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
    如果要推送某个标签到远程,使用命令git push origin <tagname>
        $ git push origin v1.0
        Total 0 (delta 0), reused 0 (delta 0)
        To git@github.com:michaelliao/learngit.git
        * [new tag]         v1.0 -> v1.0
    或者,一次性推送全部尚未推送到远程的本地标签:
        $ git push origin --tags
    如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
        $ git tag -d v0.9
    如果标签打错了,也可以删除:
        $ git tag -d v0.1
        Deleted tag 'v0.1' (was e078af9)
    因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。

    如果要推送某个标签到远程,使用命令git push origin <tagname>:
        $ git push origin v1.0
        Total 0 (delta 0), reused 0 (delta 0)
        To git@github.com:michaelliao/learngit.git
        * [new tag]         v1.0 -> v1.0

    或者,一次性推送全部尚未推送到远程的本地标签:
        $ git push origin --tags
        Counting objects: 1, done.
        Writing objects: 100% (1/1), 554 bytes, done.
        Total 1 (delta 0), reused 0 (delta 0)
        To git@github.com:michaelliao/learngit.git
        * [new tag]         v0.2 -> v0.2
        * [new tag]         v0.9 -> v0.9

    如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
        $ git tag -d v0.9
        Deleted tag 'v0.9' (was 6224937)
        然后,从远程删除。删除命令也是push,但是格式如下:
        $ git push origin :refs/tags/v0.9
        
    6.使用GitHub 可以在github上把别人的开源项目fork到自己的github仓库中,然后再从自己的仓库中吧这个项目克隆到本地,在本地自己可以接着开发这个项目。然后可以把本地的修改push到自己的github上。可以在github上,把自己修改的项目向原作者pull request。

    7 自定义git
    7.1git有很多的配置,最开始使用
        git config --global user.name "yourname"
        git config --global user.email "youremaliaddress"
    git config --global color.ui true   配置颜色的
    还有很多 具体 可以 git config  --help 将会打开帮助文档
    7.2忽略特殊文件:
    有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋心里肯定不爽。
    好在Git考虑到了大家的感受,这个问题解决起来也很简单,在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
    不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
    忽略文件的原则是:
        忽略操作系统自动生成的文件,比如缩略图等; 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
        忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

    举个例子:
    假设你在Windows下进行Python开发,Windows会自动在有图片的目录下生成隐藏的缩略图文件,如果有自定义目录,目录下就会有Desktop.ini文件,因此你需要忽略Windows自动生成的垃圾文件:
        # Windows:
        Thumbs.db
        ehthumbs.db
        Desktop.ini

    然后,继续忽略Python编译产生的.pyc、.pyo、dist等文件或目录:
        # Python:
        *.py[cod]
        *.so
        *.egg
        *.egg-info
        dist
        build

    加上你自己定义的文件,最终得到一个完整的.gitignore文件,内容如下:
        # Windows:
        Thumbs.db
        ehthumbs.db
        Desktop.ini

        # Python:
        *.py[cod]
        *.so
        *.egg
        *.egg-info
        dist
        build
        # My configurations:
        db.ini
        deploy_key_rsa
    最后一步就是把.gitignore也提交到Git,就完成了!当然检验.gitignore的标准是git status命令是不是说working directory clean。
    使用Windows的童鞋注意了,如果你在资源管理器里新建一个.gitignore文件,它会非常弱智地提示你必须输入文件名,但是在文本编辑器里“保存”或者“另存为”就可以把文件保存为.gitignore了。
    有些时候,你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了:
        $ git add App.class
        The following paths are ignored by one of your .gitignore files:
        App.class
        Use -f if you really want to add them.
    如果你确实想添加该文件,可以用-f强制添加到Git:
        $ git add -f App.class
    或者你发现,可能是.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore命令检查:
        $ git check-ignore -v App.class
        .gitignore:3:*.class    App.class
        Git会告诉我们,.gitignore的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。

    7.3配置别名:
    有没有经常敲错命令?比如git status?status这个单词真心不好记。
    如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的。
    我们只需要敲一行命令,告诉Git,以后st就表示status:
        $ git config --global alias.st status
    好了,现在敲git st看看效果。
    当然还有别的命令可以简写,很多人都用co表示checkout,ci表示commit,br表示branch:
        $ git config --global alias.co checkout
        $ git config --global alias.ci commit
        $ git config --global alias.br branch
    以后提交就可以简写成:
        $ git ci -m "bala bala bala..."
        --global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。

    在撤销修改一节中,我们知道,命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名:
        $ git config --global alias.unstage 'reset HEAD'
    当你敲入命令:
        $ git unstage test.py
    实际上Git执行的是:
        $ git reset HEAD test.py
        
    配置一个git last,让其显示最后一次提交信息:
        $ git config --global alias.last 'log -1'
    这样,用git last就能显示最近一次的提交:
        $ git last
        commit adca45d317e6d8a4b23f9811c3d7b7f0f180bfe2
        Merge: bd6ae48 291bea8
        Author: Michael Liao <askxuefeng@gmail.com>
        Date:   Thu Aug 22 22:49:22 2013 +0800

        merge & fix hello.py

    甚至还有人丧心病狂地把lg配置成了:
    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的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
    配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中:
    $ cat .git/config
    [core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
    [remote "origin"]
        url = git@github.com:michaelliao/learngit.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    [alias]
        last = log -1

    别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。
    而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:
    $ cat .gitconfig
    [alias]
        co = checkout
        ci = commit
        br = branch
        st = status
    [user]
        name = Your Name
        email = your@email.com
    配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置。
    7.4 大家git服务器
       教程中介绍的使用linux服务器。这一节没有实战 教程地址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137586810169600f39e17409a4358b1ac0d3621356287000

  • 相关阅读:
    痞子衡嵌入式:i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计
    痞子衡嵌入式:嵌入式Cortex-M裸机环境下临界区保护的三种实现
    《痞子衡嵌入式半月刊》 第 36 期
    痞子衡嵌入式:嵌入式MCU中标准的三重中断控制设计
    痞子衡嵌入式:了解i.MXRTxxx系列ROM中灵活的串行NOR Flash启动硬复位引脚选择
    痞子衡嵌入式:串行NOR Flash的页编程模式对于量产效率的影响
    《痞子衡嵌入式半月刊》 第 35 期
    痞子衡嵌入式:对比i.MXRT与LPC在RTC外设GPREG寄存器使用上的异同
    Springboot 配置文件、隐私数据脱敏的最佳实践(原理+源码)
    干掉 Postman?测试接口直接生成API文档,这个工具贼好用
  • 原文地址:https://www.cnblogs.com/OliverZhang/p/7217512.html
Copyright © 2011-2022 走看看