• Git 用法指导


    在这里插入图片描述

    1. 安装 Git

    1. linux 安装 Git

    # 试着输入git,看看系统有没有安装Git:
    $ git
    The program 'git' is currently not installed. You can install it by typing:
    sudo apt-get install git
    
    # 安装命令
    sudo apt-get install git
    
    '''
    如果是其他Linux版本,可以直接通过源码安装。
    先从Git官网下载源码,然后解压,依次输入:./config,make,sudo make install 这几个命令安装就好了。
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2. Mac 安装 Git

    两种安装Git的方法:

    1. 安装 homebrew,然后通过 homebrew 安装 Git,具体方法请参考 homebrew 的文档:http://brew.sh/。
    2. 更简单,也是推荐的方法
      • AppStore 安装 XcodeXcode 集成了 Git,不过默认没有安装,你需要运行 Xcode,选择菜单 “Xcode”->“Preferences”,在弹出窗口中找到 “Downloads”,选择 “Command Line Tools”,点 “Install” 就可以完成安装了。
      • XcodeApple 官方 IDE,功能非常强大,是开发 MaciOS App 的必选装备,而且是免费的!

    3. Windows 安装 Git

    Windows 上使用 Git,可以从 Git 官网直接下载安装程序,然后按默认选项安装即可。

    安装完成后,在开始菜单里找到 “Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明 Git 安装成功!

    在这里插入图片描述

    安装完成后,还需要最后一步设置,在命令行输入:

    $ git config --global user.name "Your Name"
    $ git config --global user.email "email@example.com"
    
    • 1
    • 2

    注意:

    git config 命令的 –global 参数,用了这个参数,表示你这台机器上所有的 Git 仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和 Email 地址。

    2. Git 常用命令

    1. Git SSH 配置

    Git 支持 SSH 协议,本地 Git 仓库和 GitHub 仓库之间的传输是通过 SSH 加密的,所以需要设置:

    1. 创建 SSH Key

      在用户主目录下,看看有没有 .ssh 目录,如果有,再看看这个目录下有没有 id_rsaid_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开 ShellWindows 下打开 Git Bash ),创建 SSH Key

      $ ssh-keygen -t rsa -C "youremail@example.com"
      
      • 1

      如果一切顺利的话,可以在用户主目录里找到 .ssh 目录,里面有 id_rsaid_rsa.pub 两个文件,这两个就是 SSH Key 的秘钥对,id_rsa 是私钥,不能泄露出去,id_rsa.pub 是公钥,可以放心地告诉任何人。

    2. GitHub 添加 SSH Key

      登陆 GitHub,打开 “Account settings”“SSH Keys” 页面

      然后,点 “Add SSH Key”,填上任意 Title,在 Key 文本框里粘贴 id_rsa.pub 文件的内容

      “Add Key”,你就应该看到已经添加的 Key

    2. Git 流程

    准备工作:

    • git clone 克隆远程仓库到本地库

      $ git clone git@github.com:michaelliao/gitskills.git
      Cloning into 'gitskills'...
      remote: Counting objects: 3, done.
      remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
      Receiving objects: 100% (3/3), done.
      
      • 1
      • 2
      • 3
      • 4
      • 5
    1. git add 把文件修改添加到暂存区

      '''
      git add 文件名: 提交指定的文件到暂存区
      git add . :    提交本地所有修改的文件到暂存区 (一般开发都使用)
      '''
      
      $ git add readme.txt 
      $ git commit -m "branch test"
      [dev b17d20e] branch test
       1 file changed, 1 insertion(+)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    2. git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支

      $ git commit -m "understand how stage works"
      [master e43a48b] understand how stage works
      2 files changed, 2 insertions(+)
      create mode 100644 LICENSE
      
      • 1
      • 2
      • 3
      • 4
    3. git status 查看一下状态

      $ git status
      On branch master
      nothing to commit, working tree clean
      
      • 1
      • 2
      • 3
    4. git pull origin name 拉取某分支最新的远程代码

      注意:本地开发需求推送远端最好先拉取一下远端仓库的最新代码,避免合并冲突。

      如何解决冲突请参考:https://www.liaoxuefeng.com/wiki/896043488029600/900004111093344

    5. git push origin name 推送分支

      推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git 就会把该分支推送到远程库对应的远程分支上:

      $ git push origin master
      
      • 1

      如果要推送其他分支,比如 dev,就改成:

      $ git push origin dev
      
      • 1

      但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?

      • master 分支是主分支,因此要时刻与远程同步;
      • dev 分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
      • bug 分支只用于在本地修复 bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个 bug
      • feature 分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

      总之,就是在 Git 中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!

    6. 创建本地 dev 分支,并且创建完成后切换到 dev 分支:

      $ git checkout -b dev
      Switched to a new branch 'dev'
      
      • 1
      • 2

      git checkout 命令加上 -b 参数表示创建并切换,相当于以下两条命令:

      $ git branch dev
      $ git checkout dev
      Switched to branch 'dev'
      
      • 1
      • 2
      • 3

      git branch 命令查看当前分支:

      $ git branch
      * dev
        master
      
      • 1
      • 2
      • 3

      git branch 命令会列出所有分支,当前分支前面会标一个 ***** 号

      git checkout 分支,切换到指定的分支

      $ git checkout master
      Switched to branch 'master'
      
      • 1
      • 2

      git checkout – file 丢弃工作区的修改:

      命令 git checkout – readme.txt 意思就是,把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况:

      一种是 readme.txt 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

      • git checkout – file 可以丢弃工作区的修改
      • git checkout – file 命令中的 很重要,没有 ,就变成了**“切换到另一个分支”**的命令

      一种是 readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

      • git reset HEAD 可以把暂存区的修改撤销掉(unstage),重新放回工作区
      • 然后再执行命令 git checkout – file 丢弃工作区的修改

      总之,就是让这个文件回到最近一次 git commitgit add 时的状态。

      # 初始状态
      $ cat readme.txt
      Git is a distributed version control system.
      Git is free software distributed under the GPL.
      Git has a mutable index called stage.
      Git tracks changes of files.
      
      '情况1':修改后还没有被放到暂存区
      # 修改文件
      $ cat readme.txt
      Git is a distributed version control system.
      Git is free software distributed under the GPL.
      Git has a mutable index called stage.
      Git tracks changes of files.
      My stupid boss still prefers SVN.
      
      # 查看工作区状态 (暂存区有修改)
      $ git status
      On branch master
      Changes not staged for commit:
        (use "git add ..." to update what will be committed)
        (use "git checkout -- ..." to discard changes in working directory)
      
      	modified:   readme.txt
      
      no changes added to commit (use "git add" and/or "git commit -a")
      
      # 放弃对文件的修改
      $ git checkout -- readme.txt
      
      # 查看文件对比初始状态(文件内容复原了)
      $ cat readme.txt
      Git is a distributed version control system.
      Git is free software distributed under the GPL.
      Git has a mutable index called stage.
      Git tracks changes of files.
      
      '情况2':已经添加到暂存区后,又作了修改
      # 修改文件
      $ cat readme.txt
      Git is a distributed version control system.
      Git is free software distributed under the GPL.
      Git has a mutable index called stage.
      Git tracks changes of files.
      My stupid boss still prefers SVN.
      
      # 提交到暂存区
      $ git add readme.txt
      
      # 查看工作区状态 (暂存区有修改)
      $ git status 
      On branch master
      Changes to be committed:
        (use "git reset HEAD ..." to unstage)
      
      	modified:   readme.txt
          
      # 把暂存区的修改回退到工作区 (当我们用 HEAD 时,表示最新的版本) 
      $ git reset HEAD readme.txt
      Unstaged changes after reset:
      M	readme.txt
      
      # 查看工作区状态 (暂存区是干净的,工作区有修改)
      $ git status
      On branch master
      Changes not staged for commit:
        (use "git add ..." to update what will be committed)
        (use "git checkout -- ..." to discard changes in working directory)
      
      	modified:   readme.txt
          
      # 放弃对文件的修改
      $ git checkout -- readme.txt
      
      # 查看工作区状态 (没有任何提交,工作区是干净的)
      $ git status
      On branch master
      nothing to commit, working tree clean
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78

      删除文件

      1. 直接删除

        $ rm test.txt
        
        • 1
      2. git rm & git commit

        $ git rm test.txt
        rm 'test.txt'
        
        $ git commit -m "remove test.txt"
        [master d46f35e] remove test.txt
         1 file changed, 1 deletion(-)
         delete mode 100644 test.txt
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
      3. 误删恢复

        可以把误删的文件恢复到最新版本:

        $ git checkout -- test.txt
        
        • 1

        git checkout 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以**“一键还原”**。

    7. 分支合并

      dev 分支的工作完成,我们就可以切换回 master 分支,把 dev 分支的工作成果合并到 master 分支上

      $ git checkout master
      Switched to branch 'master'
      
      $ git merge dev
      Updating d46f35e..b17d20e
      Fast-forward
       readme.txt | 1 +
       1 file changed, 1 insertion(+)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    8. 删除分支

      $ git branch -d dev
      Deleted branch dev (was b17d20e).
      
      • 1
      • 2
    9. switch 用法

      切换分支使用 git checkout ,而前面讲过的撤销修改则是 git checkout – ,同一个命令,有两种作用,确实有点令人迷惑。

      实际上,切换分支这个动作,用 switch 更科学。因此,最新版本的 Git 提供了新的 git switch 命令来切换分支:

      创建并切换到新的 dev 分支

      $ git switch -c dev
      
      • 1

      直接切换到已有的 master 分支

      $ git switch master
      
      • 1

      使用新的 git switch 命令,比 git checkout 要更容易理解。

    10. git remote -v 查看远程库信息

      $ git remote -v
      origin  git@github.com:michaelliao/learn-git.git (fetch)
      origin  git@github.com:michaelliao/learn-git.git (push)
      
      • 1
      • 2
      • 3
    11. 关联一个远程库

      关联一个远程库时必须给远程库指定一个名字,origin 是默认习惯命名

      关联后,使用命令 git push -u origin master 第一次推送 master 分支的所有内容

      此后,每次本地提交后,只要有必要,就可以使用命令 git push origin master 推送最新修改

      $ git remote add origin git@server-name:path/repo-name.git
      
      • 1
    12. 删除远程库

      $ git remote rm origin
      
      • 1

    总结:

    克隆远程仓库到本地仓:git clone

    提交修改到暂存区: git add 或者 git add .

    提交暂存区的修改到当前分支: git commit -m “修改信息”

    查看本地分支状态:git status

    将当前分支的提交推送到远程分支: git push origin name

    查看提交历史:git log

    查看命令历史:git reflog

    拉取远程分支最新代码:git pull origin name

    查看分支:git branch

    创建分支:git branch

    切换分支:git checkout 或者 git switch

    创建+切换分支:git checkout -b 或者 git switch -c

    合并某分支到当前分支:git merge

    删除分支:git branch -d

    查看远程库:git remote -v

    关联一个远程库:git remote add origin

    删除远程库:git remote rm origin

    3. 版本回退

    Git 允许我们在版本的历史之间穿梭,使用命令 git reset --hard commit_id

    实际工作中,版本控制系统肯定有某个命令可以告诉我们历史记录,在 Git 中,我们用 git log 命令查看每次都改了什么内容:

    $ git log
    commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Fri May 18 21:06:15 2018 +0800
    
        append GPL
    
    commit e475afc93c209a690c39c13a46716e8fa000c366
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Fri May 18 21:03:36 2018 +0800
    
        add distributed
    
    commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Fri May 18 20:59:18 2018 +0800
    
        wrote a readme file
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    git log 命令显示从最近到最远的提交日志

    上述示例我们可以看到3次提交,最近的一次是 append GPL ,上一次是 add distributed ,最早的一次是 wrote a readme file

    如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 –pretty=oneline 参数:

    $ git log --pretty=oneline
    1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
    e475afc93c209a690c39c13a46716e8fa000c366 add distributed
    eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
    
    • 1
    • 2
    • 3
    • 4

    友情提示:

    你看到的一大串类似 1094adb… 的是 commit id (版本号),和 SVN 不一样,Gitcommit id 不是 1,2,3…… 递增的数字,而是一个 SHA1 计算出来的一个非常大的数字,用十六进制表示,而且你看到的 commit id 和我的肯定不一样,以你自己的为准。为什么 commit id 需要用这么一大串数字表示呢?因为 Git 是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用 1,2,3…… 作为版本号,那肯定就冲突了。

    每提交一个新版本,实际上 Git 就会把它们自动串成一条时间线。如果使用可视化工具查看 Git 历史,就可以更清楚地看到提交历史的时间线

    Git 必须知道当前版本是哪个版本,在 Git 中,用 HEAD 表示当前版本,也就是最新的提交 1094adb… ,上一个版本就是 HEAD^ ,上上一个版本就是 HEAD^^ ,当然往上100个版本写100个 ^ 比较容易数不过来,所以写成 HEAD~100

    现在,我们要把当前版本 append GPL 回退到上一个版本 add distributed ,就可以使用 git reset 命令:

    $ git reset --hard HEAD^
    HEAD is now at e475afc add distributed
    
    • 1
    • 2

    指定回到未来的某个版本 (git reset --hard commit_id) :

    $ git reset --hard 1094a
    HEAD is now at 83b0afe append GPL
    
    • 1
    • 2

    版本号没必要写全,前几位就可以了,Git 会自动去找。当然也不能只写前一两位,因为 Git 可能会找到多个版本号,就无法确定是哪一个了。

    Git 的版本回退速度非常快,因为 Git 在内部有个指向当前版本的 HEAD 指针,当你回退版本的时候,Git 仅仅是把 HEAD 从指向 append GPL

    ┌────┐
    │HEAD│
    └────┘
       │
       └──> ○ append GPL
            │
            ○ add distributed
            │
            ○ wrote a readme file
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    改为指向 add distributed

    ┌────┐
    │HEAD│
    └────┘
       │
       │    ○ append GPL
       │    │
       └──> ○ add distributed
            │
            ○ wrote a readme file
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    然后顺便把工作区的文件更新了。所以你让 HEAD 指向哪个版本号,你就把当前版本定位在哪。

    现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的 commit id 怎么办?

    Git 中,总是有后悔药可以吃的。当你用 $ git reset --hard HEAD^ 回退到 add distributed 版本时,再想恢复到 append GPL ,就必须找到 append GPLcommit idGit 提供了一个命令 git reflog 用来记录你的每一次命令:

    $ git reflog
    e475afc HEAD@{1}: reset: moving to HEAD^
    1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
    e475afc HEAD@{3}: commit: add distributed
    eaadf4e HEAD@{4}: commit (initial): wrote a readme file
    
    • 1
    • 2
    • 3
    • 4
    • 5

    从输出可知, append GPLcommit id1094adb ,可以使用命令 git reset --hard 1094adb 指定回到这个版本。

    4. 标签管理

    1. 创建标签

    切换到需要打标签的分支上 (默认标签是打在最新提交的 commit 上的) :

    $ git branch
    * dev
      master
    $ git checkout master
    Switched to branch 'master'
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后,敲命令 git tag 就可以打一个新标签:

    $ git tag v1.0
    
    • 1

    可以用命令 git tag 查看所有标签:

    $ git tag
    v1.0
    
    • 1
    • 2

    给指定的 commit 打标签

    # 查看历史提交
    $ git log --pretty=oneline --abbrev-commit
    5dc6824 & simple
    14096d0 AND simple
    b17d20e branch test
    
    # 选择需要的 commit id
    $ git tag v0.9 14096d0
    
    # 查看标签
    $ git tag
    v0.9
    v1.0
    
    '''
    注意:
        标签不是按时间顺序列出,而是按字母排序的
        可以用 git show  查看标签信息
    '''
        
    $ git show v0.9
    commit 14096d049bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Fri May 18 21:56:54 2018 +0800
    
        AND simple
    
    diff --git a/readme.txt b/readme.txt
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    创建带有说明的标签,用 -a 指定标签名,-m 指定说明文字:

    $ git tag -a v0.1 -m "version 0.1 released" 1094adb
    
    • 1

    用命令 git show 可以看到说明文字:

    $ git show v0.1
    tag v0.1
    Tagger: Michael Liao <askxuefeng@gmail.com>
    Date:   Fri May 18 22:48:43 2018 +0800
    
    version 0.1 released
    
    commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
    Author: Michael Liao <askxuefeng@gmail.com>
    Date:   Fri May 18 21:06:15 2018 +0800
    
        append GPL
    
    diff --git a/readme.txt b/readme.txt
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    总结:

    • 新建一个标签:git tag ( 默认为 HEAD,也可以指定一个 commit id )
    • 指定标签信息:git tag -a -m “blablabla…”
    • 查看所有标签:git tag
    • 查看标签信息:git show
    2. 操作标签

    标签打错可以删除:

    $ git tag -d v0.1
    Deleted tag 'v0.1' (was f15b0dd)
    
    • 1
    • 2

    因为创建的标签都只存储在本地,不会自动推送到远程,所以打错的标签可以在本地安全删除。

    如果要推送某个标签到远程,使用命令 git push origin

    $ git push origin v1.0
    Total 0 (delta 0), reused 0 (delta 0)
    To github.com:michaelliao/learngit.git
     * [new tag]         v1.0 -> v1.0
    
    • 1
    • 2
    • 3
    • 4

    或一次性推送全部尚未推送到远程的本地标签:

    $ git push origin --tags
    Total 0 (delta 0), reused 0 (delta 0)
    To github.com:michaelliao/learngit.git
     * [new tag]         v0.9 -> v0.9
    
    • 1
    • 2
    • 3
    • 4

    如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

    $ git tag -d v0.9
    Deleted tag 'v0.9' (was f52c633)
    
    • 1
    • 2

    然后从远程删除,删除命令也是 push,格式如下:

    $ git push origin :refs/tags/v0.9
    To github.com:michaelliao/learngit.git
     - [deleted]         v0.9
    
    • 1
    • 2
    • 3

    要看看是否真的从远程库删除了标签,可以登陆 GitHub 查看

    总结:

    • 推送一个本地标签到远程分支: git push origin
    • 推送全部未推送过的本地标签: git push origin --tags
    • 删除一个本地标签: git tag -d
    • 删除一个远程标签: git push origin :refs/tags/

    参考:https://www.liaoxuefeng.com/wiki/896043488029600

  • 相关阅读:
    十四、综合项目(斗地主)
    蜜雪冰城、茶颜悦色“卷”向咖啡赛道
    TypeScript深度掌握
    OJ练习第168题——课程表 III
    基于点标签的目标检测与计数深度学习框架盘点
    java数组
    【最小的k个数】
    与AIGC的快乐游戏: Prompt提示词的重要性
    word文档太大怎么压缩?快速压缩word文档
    YOLOv5添加注意力机制
  • 原文地址:https://blog.csdn.net/qq_31455841/article/details/127867315