• 18_Git笔记(530行)


    proxy   10.10.11.10
    client  10.10.11.11
    web1    10.10.11.12
    web2    10.10.11.13

    proxy:
    1. Git安装
    ]# yum -y install git
    ]# git config --global user.name "zk"
    ]# git config --global user.email "349012093@qq.com"
    ]# git --help
    最常用的 git 命令有:
       add        添加文件内容至索引
       bisect     通过二分查找定位引入 bug 的变更
       branch     列出、创建或删除分支
       checkout   检出一个分支或路径到工作区
       clone      克隆一个版本库到一个新目录
       commit     记录变更到版本库
       diff       显示提交之间、提交和工作区之间等的差异
       fetch      从另外一个版本库下载对象和引用
       grep       输出和模式匹配的行
       init       创建一个空的 Git 版本库或重新初始化一个已存在的版本库
       log        显示提交日志
       merge      合并两个或更多开发历史
       mv         移动或重命名一个文件、目录或符号链接
       pull       获取并合并另外的版本库或一个本地分支
       push       更新远程引用和相关的对象
       rebase     本地提交转移至更新后的上游分支中
       reset      重置当前HEAD到指定状态
       rm         从工作区和索引中删除文件
       show       显示各种类型的对象
       status     显示工作区状态
       tag        创建、列出、删除或校验一个GPG签名的 tag 对象

    2. 创建版本库
    ]# mkdir mymenu
    ]# cd mymenu/
    mymenu]# git init  # 初始化仓库
    初始化空的 Git 版本库于 /root/mymenu/.git/

    初始化了一个空的仓库,目录下多了.git目录
    系统自动创建了唯一一个master分支
    版本控制系统只能跟踪文本文件的改动,且编码方式是utf-8

    3. 文件的基本操作
    mymenu]# echo 'Hello World!' > readme.txt

    3.1 添加文件到仓库
    mymenu]# git add readme.txt

    3.2 提交文件到仓库
    mymenu]# git commit -m "a new file"
    [master(根提交) 17a73da] a new file
     1 file changed, 1 insertion(+)
     create mode 100644 readme.txt

    如果提交的备注写错了,可以用以下命令修改刚刚提交的备注
    mymenu]# git commit --amend  (进入vim编辑模式)
    [master bcd3382] A new file
     1 file changed, 1 insertion(+)
     create mode 100644 readme.txt

    3.3 修改文件
    mymenu]# echo '123' > readme.txt
    提交文件到仓库
    mymenu]# git add readme.txt
    mymenu]# git commit -m "change to 123"
    [master ae3d174] change to 123
     1 file changed, 1 insertion(+), 1 deletion(-)

    3.4 每次commit都会生成一个“快照”
    查看历史记录
    mymenu]# git log
    commit ae3d174701f89d8b68ebd143818c81a9717d5963
    Author: zk <349012093@qq.com>
    Date:   Thu Jan 9 07:08:19 2020 +0800

        change to 123

    commit bcd3382da570951e3ce8cb411adb127f7af8d1bd
    Author: zk <349012093@qq.com>
    Date:   Thu Jan 9 07:02:24 2020 +0800

        A new file

    git的版本号是用SHA1计算出来的一个16进制数
    如果嫌输出信息太多,可以加上--pretty=oneline
    mymenu]# git log --pretty=oneline
    ae3d174701f89d8b68ebd143818c81a9717d5963 change to 123
    bcd3382da570951e3ce8cb411adb127f7af8d1bd A new file

    3.5 回退历史版本
    mymenu]# git reset
    首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交bcd3382...,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

    回退上一版本
    mymenu]# git reset --hard HEAD^
    HEAD 现在位于 bcd3382 A new file

    这时再次查看历史版本
    mymenu]# git log
    commit bcd3382da570951e3ce8cb411adb127f7af8d1bd
    Author: zk <349012093@qq.com>
    Date:   Thu Jan 9 07:02:24 2020 +0800

        A new file

    之前那个版本已经看不到了,这时如果想回到之前那个版本,需要知道版本号,git内部有个指向当前版本的head指针,将指针从当前版本指回去,所以git回退版本特别快
    mymenu]# git reset --hard bcd3382
    HEAD 现在位于 bcd3382 A new file
    [root@proxy mymenu]# git log
    commit bcd3382da570951e3ce8cb411adb127f7af8d1bd
    Author: zk <349012093@qq.com>
    Date:   Thu Jan 9 07:02:24 2020 +0800

        A new file

    3.6 查看历史命令
    mymenu]# git reflog
    bcd3382 HEAD@{0}: reset: moving to HEAD^
    ae3d174 HEAD@{1}: commit: change to 123
    bcd3382 HEAD@{2}: commit (amend): A new file
    17a73da HEAD@{3}: commit (initial): a new file

    3.7 查看状态
    mymenu]# git status
    # 位于分支 master
    无文件要提交,干净的工作区

    4. 工作区和暂存区
    Git和SVN的一个不同之处就是有暂存区的概念

    名词解释:
    工作区(Working Directory):指的是在电脑里能看到的目录,比如mymenu文件夹就是一个工作区

    版本库(Repository):.git目录,Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

    git add     是把需要提交的文件添加到暂存区
    git commit  是把暂存区的所有内容提交到当前分支

    5. 修改
    5.1 修改文件
    mymenu]# echo "bbb" >> readme.txt
    mymenu]# git add readme.txt
    再次修改
    mymenu]# echo "ccc" >> readme.txt
    提交
    mymenu]# git commit -m "test add lines"
    [master 9fc3bc0] test add lines
     1 file changed, 1 insertion(+)

    这时我们发现,第二次的修改未提交,这是为什么呢?
    第一次修改-->git add-->第二次修改-->git commit
    add将工作区的修改存入暂存区,但是第二次修改并未存入暂存区,git commit只负责把暂存区的修改提交,所以正确的顺序应该是:
    第一次修改 --> git add --> 第二次修改 --> git add --> git commit

    提交后,查看工作区和版本库里面最新版本的区别:
    mymenu]# git diff HEAD -- readme.txt
    diff --git a/readme.txt b/readme.txt
    index c7ee920..9c2428f 100644
    --- a/readme.txt
    +++ b/readme.txt
    @@ -1,2 +1,3 @@
     Hello World!
     bbb
    +ccc

    5.2 撤销修改
    丢弃工作区的修改 git checkout -- file
    (--很重要,没有--,就变成了“切换到另一个分支”的命令)
    mymenu]# git checkout -- readme.txt

    命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
    一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
    一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
    总之,就是让这个文件回到最近一次git commit或git add时的状态。

    把暂存区的修改撤销掉(unstage),重新放回工作区 git reset HEAD <file>
    mymenu]# git reset HEAD readme.txt
    mymenu]# cat readme.txt
    Hello World!
    bbb
    git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

    6 删除文件
    工作区中删除文件
    mymenu]# rm readme.txt
    rm:是否删除普通文件 "readme.txt"?y
    此时并没有提交,从版本库同步回来
    mymenu]# git checkout -- readme.txt
    mymenu]# ls
    readme.txt
    git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

    从版本库删除文件并提交
    mymenu]# git rm readme.txt
    rm 'readme.txt'
    mymenu]# git commit -m "remove readme.txt"
    [master 42c64dd] remove readme.txt
     1 file changed, 2 deletions(-)
     delete mode 100644 readme.txt

    7. 分支管理
    7.1 介绍
    每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

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

    每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。
    当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:
    git-br-create

    Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
    不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
    git-br-dev-fd

    假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:
    git-br-ff-merge
    所以Git合并分支也很快!就改改指针,工作区内容也不变!

    合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
    git-br-rm

    7.2 master分支添加一个文件
    mymenu]# echo "test"> test.txt
    mymenu]# git add test.txt
    mymenu]# git commit -m "add test.txt"
    [master ad6084d] add test.txt
     1 file changed, 1 insertion(+)
     create mode 100644 test.txt

    7.3 创建并切换到分支 dev
    mymenu]# git branch dev
    mymenu]# git checkout dev
    切换到分支 'dev'

    查看分支及当前所在分支
    mymenu]# git branch
    * dev
      master

    git branch命令会列出所有分支,当前分支前面会标一个*号。
    然后,我们就可以在dev分支上正常提交,比如对test.txt做个修改,再提交,dev分支的工作完成后,我们就可以切换回master分支:
    mymenu]# echo "aaa" >> test.txt
    mymenu]# cat test.txt
    test
    aaa
    mymenu]# git add test.txt
    mymenu]# git commit -m "add aaa"
    [dev ca10c10] add aaa
     1 file changed, 1 insertion(+)

    mymenu]# git checkout master
    M    test.txt

    切换到分支 'master'
    mymenu]# cat test.txt
    test

    切换回master分支后,再查看一个test.txt文件,刚才添加的内容不见了!
    因为那个提交是在dev分支上,而master分支此刻的提交点并没有变

    7.4 合并某个分支到当前分支 git merge <name>
    现在,我们把dev分支的工作成果合并到master分支上:
    mymenu]# git merge dev
    更新 ad6084d..ca10c10
    Fast-forward
     test.txt | 1 +
     1 file changed, 1 insertion(+)

    合并后,再查看test.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

    7.5 删除分支 git branch -d <name>
    合并完成后,就可以放心地删除dev分支了:
    mymenu]# git branch -d dev
    已删除分支 dev(曾为 ca10c10)。

    删除后,查看branch,就只剩下master分支了:
    mymenu]# git branch
    * master

    7.6 解决冲突
    创建并切换到一个新的分支feature1
    mymenu]# git checkout -b feature1
    M    test.txt
    切换到一个新分支 'feature1'

    在feature1在修改test.txt文件,追加字符"bbb"
    mymenu]# cat test.txt
    test
    aaabbb

    提交
    mymenu]# git add test.txt
    mymenu]# git commit -m "add bbb to aaa"
    [feature1 e81e428] add bbb to aaa
     1 file changed, 1 insertion(+), 1 deletion(-)

    切换到master分支
    mymenu]# git checkout master
    切换到分支 'master'

    在master分支上,在"aaa"后追加"ccc",提交:
    mymenu]# cat test.txt
    test
    aaaccc
    mymenu]# git add test.txt
    mymenu]# git commit -m "add ccc to aaa"
    [master a013cc7] add ccc to aaa
     1 file changed, 1 insertion(+), 1 deletion(-)

    当两个分支都分别有了新的提交,这种情况下无法进行快速合并,只能试图把各自的修改合并起来,这样有可能会造成冲突:
    mymenu]# git merge feature1
    自动合并 test.txt
    冲突(内容):合并冲突于 test.txt
    自动合并失败,修正冲突然后提交修正的结果。

    这时我们必须手动解决冲突后再提交,git status可以查看冲突的文件:
    mymenu]# git status
    # 位于分支 master
    # 您有尚未合并的路径。
    #   (解决冲突并运行 "git commit")
    #
    # 未合并的路径:
    #   (使用 "git add <file>..." 标记解决方案)
    #
    #    双方修改:     test.txt
    #
    修改尚未加入提交(使用 "git add" 和/或 "git commit -a")

    查看test.txt文件的内容:
    mymenu]# cat test.txt
    test
    <<<<<<< HEAD
    aaaccc
    =======
    aaabbb
    >>>>>>> feature1

    Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:
    mymenu]# cat test.txt
    test
    hhhhhhhh

    再提交,冲突解决
    mymenu]# git add test.txt
    ymenu]# git commit -m "conflict fixed"
    [master 8ce55da] conflict fixed

    用git log --graph --pretty=oneline --abbrev-commit可以看到分支的合并情况,包括分支合并图(--graph)、一行显示(--pretty=oneline)、提交校验码缩略(--abbrev-commit)显示:
    mymenu]# git log --graph --pretty=oneline --abbrev-commit
    *   8ce55da conflict fixed
    |  
    | * e81e428 add bbb to aaa
    * | a013cc7 add ccc to aaa
    |/  
    * ca10c10 add aaa
    * ad6084d add test.txt
    * 42c64dd remove readme.txt
    * 9fc3bc0 test add lines
    * bcd3382 A new file

    最后,删除feature1分支
    mymenu]# git branch -d feature1
    已删除分支 feature1(曾为 e81e428)。

    7.7 分支管理策略
    通常,合并分支时,Git会用快速合并模式(Fast forward),但这种模式下,删除分支后,会丢掉分支信息。
    如果用普通合并模式,从分支历史上就可以看出分支信息。
    那么,如何使用普通合并模式呢?我们可以用--no-ff参数

    mymenu]# git merge --no-ff -m "merge with no-ff" dev

    分支策略
    master分支是最稳定的,只能用于发布新版本,平时不能在上面进行开发,要在新建的分支上进行开发,比如dev,这时dev是不稳定的,到产品1.0发布时,将dev分支和master分支合并,在master分支上发布1.0版本。

    7.8 bug分支
    修复bug时,我们会创建一个bug分支进行修复,修复完合并,删除分支。
    git stash命令的作用就是将目前还不想提交的但是已经修改的内容进行保存至堆栈中,后续可以在某个分支上恢复出堆栈中的内容。

    模拟bug状态
    mymenu]# git checkout -b dev
    切换到一个新分支 'dev'
    mymenu]# cat test.txt
    test
    hhhhhhhh
    mymenu]# echo "mmmmm" >> test.txt

    mymenu]# git stash
    Saved working directory and index state WIP on dev: 8ce55da conflict fixed
    HEAD 现在位于 8ce55da conflict fixed

    切换到master去修复bug
    mymenu]# git checkout master
    切换到分支 'master'
    mymenu]# cat test.txt
    test
    hhhhhhhh

    修复了bug后回到dev分支
    mymenu]# git checkout dev
    mymenu]# cat test.txt
    test
    hhhhhhhh

    我们先查看下stash
    mymenu]# git stash list
    stash@{0}: WIP on dev: 8ce55da conflict fixed

    恢复工作现场
    方法1:
        用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除
        可以多次stash,恢复指定的stash;
       mymenu]# git stash apply stash@{0}

    方法2:
        用git stash pop,恢复的同时把stash内容也删了:
       mymenu]# git stash pop
    # 位于分支 dev
    # 尚未暂存以备提交的变更:
    #   (使用 "git add <file>..." 更新要提交的内容)
    #   (使用 "git checkout -- <file>..." 丢弃工作区的改动)
    #
    #    修改:      test.txt
    #
    修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
    丢弃了 refs/stash@{0} (5272bd4e95f7fb8d9c86bad4cbba49f650992a54)

    查看恢复
    mymenu]# cat test.txt
    test
    hhhhhhhh
    mmmmm

    mymenu]# git add test.txt
    mymenu]# git commit -m "add mmmm"
    [dev 09a7d99] add mmmm
     1 file changed, 1 insertion(+)

    7.9 不合并删除分支
    开发一个新功能,需要新建一个分支。
    如果这个功能还未合并就要取消,要使用-D强行删除
    mymenu]# git checkout master
    切换到分支 'master'

    mymenu]# git branch -D dev
    已删除分支 dev(曾为 09a7d99)。

    7.10 多人协作
    当你从远程克隆时,git自动把本地master分支和远程master分支对应起来,远程仓库默认名为origin

    查看远程库的信息
    mymenu]# git remote

    查看远程库的详细信息
    mymenu]# git remote -v

    7.10.1 推送分支
    将本地master分支推送到远程库
    如果不推送到远程,本地分支对于其它人就是不可见的
    mymenu]# git push origin master

    7.10.2 抓取分支
    如果本地分支推送到远程库的文件有冲突,推送失败,我们就得先从远程库中抓取最新的提交合并到本地,解决冲突再提交。
    mymenu]# git pull

    如果git pull报错:没有指定本地分支与远程分支的链接,我们就要手动设置一下
    mymenu]# git branch --set-upstream-to=origin/<远程分支名> 本地分支名

    7.10.3 Rebase
    rebase操作可以把本地未push的分叉提交历史整理成直线;
    目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

    8. 标签管理
    切换到需要打标签的分支上

    8.1 新建一个标签(默认为HEAD,也可以指定一个commit id)
    创建带有说明的标签,用-a指定标签名,-m指定说明文字
    git tag <标签名>
    git tag <标签名> <commit id>
    git tag -a <标签名> -m "备注"

    mymenu]# git checkout -b dev
    切换到一个新分支 'dev'

    mymenu]# git tag latest

    8.2 查看标签
    mymenu]# git tag
    latest

    mymenu]# git show latest
    commit 8ce55da2adc004c1986e2e31ef6029b8c884ad49
    Merge: a013cc7 e81e428
    Author: zk <349012093@qq.com>
    Date:   Thu Jan 9 22:05:02 2020 +0800

        conflict fixed

    diff --cc test.txt
    index c590ac8,0c93a2d..f4d7480
    --- a/test.txt
    +++ b/test.txt
    @@@ -1,2 -1,2 +1,2 @@@
      test
    - aaaccc
     -aaabbb
    ++hhhhhhhh

    PS:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。

    8.3 删除标签
    创建的标签都只存储在本地,不会自动推送到远程,所以打错的标签可以在本地安全删除;
    git tag -d <标签名>

    如果标签已经推送到远程,要先从本地删除,再从远程删除
    git tag -d <标签名>
    git push origin :refs/tags/<标签名>

    mymenu]# git tag -d latest
    已删除 tag 'latest'(曾为 8ce55da)

    8.4 推送标签到远程
    推送某个标签到远程 git push origin <tagname>
    推送全部尚未推送到远程的本地标签 git push origin --tags

    git push origin <标签名>
    git push origin --tags

  • 相关阅读:
    费马小定理
    Big Number阶乘位数计算(斯特林公式)
    V
    矩阵快速幂求斐波那契
    奇迹
    缘分
    求导
    拓扑排序
    线段树
    单调栈
  • 原文地址:https://www.cnblogs.com/luwei0915/p/12169437.html
Copyright © 2020-2023  润新知