美文网首页
git命令详解

git命令详解

作者: CDF_cc7d | 来源:发表于2023-05-13 16:13 被阅读0次

    Git基本概念

    Git是什么

    Git是一个分布式代码管理工具,而SVN则是集中式代码管理工具。

    1. 集中式: 所有的代码都保存在中央服务器,所以提交必须依赖网络,协同工作的人们都通过客户端连接到这台服务器,取出最新的文件或者提交更新
    2. 分布式: 每个终端都是一个仓库,客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整的镜像下来,每一次的提取操作,实际上都是一次对代码仓库的完整备份。因此可以在本地进行提交,并不需要依赖网络。
    git.jpg

    工作区域

    1. 工作区: 实际的工作目录
    2. 暂存区: 代码add以后暂时存储的区域
    3. 仓库区: 分为本地仓库和远程仓库。 本地仓库是commit以后存储的区域, 远程仓库是push以后存储的区域

    commit节点

    每次Git提交以后都会生成一个节点,每个节点都会有一个哈希值作为一个唯一标示,多次提交就会形成一个线性节点链, 如下图所示,C2是最后一个提交节点,那么C2会包含前面C1和C0的提交内容。右边则是每次提交对应的哈希值


    commit节点.jpg

    HEAD

    HEAD相当于一个指针,它可以指向任意一个节点,它指向的那个节点就是当前工作节点。如上图所示,当HEAD指向C2,那么当前工作目录就是C2。

    分支

    分支可以让开发分多条主线同时进行,每条主线互不影响

    假如将整个项目比作一个单机游戏,节点就是玩家保存的进度,HEAD指的就是玩家当前选择的那个进度,而分支可以认为是不同的玩家在玩这个游戏的历程。


    Git命令详解

    1. 初始化

    1.1 初始化本地仓库

    image.png

    1.2 关联远程仓库

    git remote add <自定义仓库名> + 仓库ssh地址
    git init初始化仓库以后需要进行git remote操作,实现本地和远程仓库绑定,这样才算是完整创建本地仓库


    10239771-c1264302673ac2d3.png

    1.3 克隆远程仓库到本地

    可以通过git clone的方式直接将远程仓库克隆到本地,此时远程仓库名默认为origin。


    image.png

    2. 查看文件状态

    2.1 查看文件状态

    git status


    image.png

    2.2 查看文件状态简览

    git status -s
    相对于git status来说显示的内容更简单直观一点

    1. 新添加的未跟踪的文件前面有??, 即test5.txt
    2. 新添加的文件已经放入暂存区的,文件前面会显示A, 即test4.txt
    3. 文件被修改但是没有放入暂存区,右边会出现M, 即 test2.txt和test3.txt
    4. 文件被修改并且已经被放入暂存区,左边会出现M, 即test.txt
    5. 文件被删除但是没有放入暂存区,右边会出现D
    6. 文件被删除并且已经被放入暂存区,左边会出现D
    10239771-7f41019e0b09efa2.png

    3. 查看修改

    3.1 查看工作区所有文件的修改

    git diff

    diff --git a/git_test_demo/README.md b/git_test_demo/README.md
    这一行显示diff下两个文件的对比。 a版本指的是修改前的README.md, b版本指的是修改后的README.md

    deleted file mode 100644
    删除了文件 100指的是普通文件,644代表文件权限
    Index e69de29..000000
    index后面的两个数字表示两个文件的hash值,因为是删除,所以后面的数字hash值为000000。

    diff--git a/git_test_demo/test.txt b/git_test_demo/test.txt
    这一行显示diff下两个文件的对比。 a版本指的是修改前的test.txt, b版本指的是修改后的text.txt

    Index 5d58fcd..f316c8d 100644
    index后面的两个数字表示两个文件的hash值(index区域的5d58fcd与工作区的f316c8d对象对比)

    --- a/git_test_demo/test.txt
    +++ b/git_test_demo/test.txt
    ---表示修改前, +++表示修改后

    @@ -2,3 +2,4 @@
    该行表示接下来下面显示的内容所在的位置。
    -表示修改前, +表示修改后
    -2,3 表示修改前test.txt文件从第2行显示,一直到第4行(2位起始行, 3位向后偏移的行数。即显示修改内容从第2行到第4行)
    +2,4 表示修改后test.txt文件从第2行显示,一直到第5行(2位起始行, 3位向后偏移的行数。即显示修改内容>从第2行到第5行)

    10239771-2fb3db1bfd16f303.png

    3.2 查看暂存区所有文件的修改

    git diff --staged


    10239771-e3829ebce25792f9.png

    3.3 查看两次提交之间的差异

    git diff <commit id1> <commit id2>


    10239771-d3bb8111379d0d9f.png

    3.4 查看两个分支之间的差异

    git diff <branch1> <branch2>


    10239771-f11717788431e6c0.png

    3.5 查看指定提交的修改内容

    git show <commit id>


    image.png

    3.6 查看指定文件的修改历史

    git blame <file>


    10239771-e18d7f154f4a0990.png

    3.7 查看最近N次提交的修改内容

    git log -p -N


    image.png

    4. 查看提交记录

    4.1 查看当前分支的历史提交记录

    git log


    image.png

    4.2 简洁的方式查看提交历史

    git log --pretty=oneline


    10239771-6471d6d5cfb9872b.png

    4.3 查看分支合并图

    git log --graph


    image.png

    4.4 查看所有的操作记录

    git reflog

    任何的操作记录都会显示在reflog上面
    显示内容为Commit id + 执行的命令 + 提交描述


    10239771-6f72efa3f1cf3170.png

    4.5 查看指定提交记录是在哪个分支提交的

    git branch --contains <commit id>


    image.png

    5. 添加文件

    10239771-47fb8043bfa02953.png
    10239771-296f1c6468e5ab64.png
    10239771-2a68331f954423c0.png

    当前目录下修改了三个文件test.txt, test2.txt, test3.txt, 新增了test4.txt, 移除了README.md

    5.1 暂存工作区所有的文件

    git add . / git add -A / git add --all


    10239771-7709bc2ea26a2cc5.png
    10239771-45412a88dcf83b06.png

    5.2 暂存工作区指定的文件

    git add <file1> <file2>


    10239771-bfb5f31b5ab50470.png

    5.3 暂存工作区指定目录的所有文件

    git add {directory}


    10239771-b5ba850285aeee1b.png

    5.4 暂存工作区所有文件,不包含删除的文件

    git add *


    10239771-5f9fab2344181bd5.png

    5.5 暂存工作区所有文件,不包含新增的文件

    git add -u


    10239771-b46ab2da2fddeb3f.png

    6. 分支

    6.1 查看本地分支列表

    git branch (带星号指的是当前的分支)


    10239771-1d9bf08243752c0d.png

    6.2 查看远程分支列表

    git branch -r


    10239771-4484d022e5ab5ca7.png

    6.3 查看所有的分支列表(包括本地和远程)

    git branch -a


    10239771-2869df91a12d34ec.png

    6.4 查看本地每个分支最后一次提交

    git branch -v


    10239771-e57a0587baa5397a.png

    6.5 查看本地每个分支最后一次提交,并且与远程分支进行比较

    git branch -vv


    10239771-91b7c5de7de51b31.png

    6.6 创建分支

    git branch <branch>


    10239771-52f3f1b4d155d705.png

    6.7 删除指定分支

    git branch -d <branch>


    10239771-8ed4001b57a3b2c9.png

    6.8 强制删除指定分支

    git branch -D <branch>


    10239771-07930ec52c2e9341.png

    6.9 删除远端分支

    git push origin --delete <branch>


    10239771-4e2665df236cb6ce.png

    6.10 切换到上一个分支

    git checkout -


    10239771-dc9bd14f83e3cd1e.png

    6.11 切换分支

    git checkout <branch>


    10239771-38038617f5a15dbb.png

    6.12 创建分支并且切换到该分支

    git checkout -b <branch>

    等价于git branch <branch> + git checkout <branch>

    10239771-6683944eee31017d.png

    7. 提交

    7.1 提交暂存区的文件到本地仓库

    git commit -m "message"


    10239771-9aadfd910c9e3b3f.png

    7.2 跳过暂存区直接执行提交

    git commit -a -m "message" / git commit -am "message"
    这种方式可以直接提交工作区修改后的文件,但是新添加的文件是不会提交的,仍然需要先add到暂存区。


    10239771-21c9d92cfb9207a8.png 10239771-dca6e17ba4340ff6.png

    7.3 修改之前已经提交的结果

    git commit --amend

    第二次提交将 代替 上一次提交的结果。适用于提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了的情况。

    10239771-914a58b6dcef53c5.png

    7.4 将本地提交推送至远端

    git push origin <branch>


    image.png

    7.5 强制提交到远端

    git push origin <branch> --force

    以下图为例, 将上面那次commit给撤销以后,然后执行git push origin cdf2发现无法推到远端仓库。
    所以执行了git push origin cdf2 --force强制将远端仓库的那次提交也给撤销掉

    10239771-430dbd91d65bdcef.png

    7.6 将修改提交到远端指定的分支

    git push origin <commit id>:<branch>

    以下图为例

    1. 在cdf2的分支下面提交了一个test4.txt文件
    2. 将test4.txt文件推到了远端cdf4的分支上
    image.png

    8. 拉取

    8.1 拉取远端分支的最新代码

    git fetch

    git fetch --depth=N
    只拉取最近N次的commit, 这样可以加快拉取速度。 但是由于只拉取最近N次的commit,所以相应的本地也只能看到最近的N次commit。

    git fetch 会先将远端的代码拉取下来保存到FETCH_HEAD中,然后通过git merge的方式将FETCH_HEAD的代码merge到当前本地分支


    10239771-67b64e0f2f53700f.png 10239771-e83db2b13ac931b6.png

    8.2 拉取远端分支的最新代码, 并且合并到本地分支

    git pull
    git pull则是git fetch + git merge的操作, 直接更新本地分支的代码


    image.png 10239771-b61f91ce03ec8f65.png 10239771-4e354cb8a01c9f3a.png

    8.3 拉取远端分支的最新代码,并且合并到本地分支

    git pull --rebase

    当本地没有任何提交记录,那么git pull = git pull --rebase。

    当本地提交了一个节点,远端同一个分支也更新了节点
    通过git pull的方式会产生一个merge的提交记录
    如右下图所示

    10239771-19e3e3b7b0d539fa.png
    image.png

    通过git pull --rebase的方式,则会让整个提交记录看起来更线性。


    image.png 10239771-983919b3c732a946.png

    9. 回退

    9.1 清空暂存区

    git reset HEAD/ git reset --mixed


    10239771-54270e4e2704301e.png 10239771-0cfd546d9e72949d.png

    9.2 将HEAD回退N个节点

    git reset HEAD~N

    例如N=2,那么HEAD将往前推2个节点,会指向倒数第三个节点。 回退以后保留修改文件

    image.png

    9.3 重置所有文件到未修改的状态

    git reset --hard


    10239771-f3c5372d1f16df5a.png

    9.4 将HEAD回退一个节点

    git reset --hard HEAD^ / git reset --hard HEAD~1


    image.png

    9.5 将HEAD回退到指定的节点

    git reset --hard <commit id>


    image.png

    9.6 撤销工作区指定文件的改动

    git checkout -- <file> / git restore <file>


    10239771-d87a5c1120702b32.png 10239771-8f90a1d808448176.png

    9.7 将HEAD指向指定节点

    git checkout <commit id>


    image.png image.png

    9.8 将HEAD指向前一个节点

    git checkout HEAD^


    image.png
    10239771-f14c1a85694c95a5.png

    9.9 将HEAD往前移动N个节点

    git checkout HEAD~N

    例如N=2,那么HEAD将往前推2个节点,会指向倒数第三个节点

    image.png 10239771-01646bc292fa7d8e.png

    9.10 还原指定节点的修改

    git revert <commit id>

    revert以后会将原来的修改回退掉,并且新增一条提交记录

    10239771-3a20d7dacbf66618.png

    9.11 还原上次的提交

    git revert HEAD


    image.png

    10. 保存

    10.1 保存当前修改的内容

    git stash


    10239771-5b84eb5c04f1584f.png

    10.2 查看保存的记录列表

    git stash list


    10239771-02692bdba3350226.png

    10.3 将上一次保存的内容恢复到工作区

    git stash apply


    10239771-f8c37eeceebb68d7.png 10239771-928f7f9a24afec73.png

    10.4 删除stash里面上一次保存的记录

    10239771-2a049696306a1935.png

    10.5 上一次保存的内容恢复到工作区,并且删除对应的记录

    git stash pop


    10239771-fca4f47aee9d108d.png

    10.6 清空stash里面所有保存的记录

    git stash clear


    10239771-9da539a36e866489.png

    10.7 删除stash里面指定index的那一条记录

    git stash drop <index>


    10239771-6001e0112d23cb76.png

    11. 标签

    11.1 在指定节点上创建标签

    git tag <tag name> <commit id>


    10239771-afe7a60401aa45b0.png

    11.2 查看所有标签

    git tag


    10239771-eef8ff3a3835b659.png

    11.3 删除本地标签

    git tag -d <tag name>


    10239771-cd0d5e1e5e57a925.png

    11.4 将本地指定标签推送到远端

    git push origin <tag name>


    image.png

    11.5 将本地所有标签推送到远端

    git push origin --tags


    image.png

    12. 合并

    合并整体的链路比较复杂,并且在命令行中不好直观呈现,下一节做比较的时候再详细给出

    12.1 将指定的提交节点复制到当前最新的节点上

    git cherry-pick <commit id>
    执行git cherry-pick <commitid>将其他分支的指定commit记录复制过来提交到当前分支


    10239771-7a13ce6d267207a7.png

    12.2 将指定分支的提交记录复制到当前分支

    git merge <branch>

    1. 执行git merge cdf将cdf分支的代码合并过来
    2. 产生冲突以后,将文件冲突解决掉
    3. 执行git add .命令
    4. 执行git merge --continue。
    5. 然后就会产生一条merge的commit记录
    10239771-2da69ab30c55b310.png
    image.png

    12.3 将指定分支的提交记录复制到当前分支,并且保持线性的提交记录

    git rebase

    1. 执行git rebase cdf将cdf分支的代码合并过来
    2. 产生冲突以后,将文件冲突解决掉
    3. 执行git add .命令
    4. 执行git rebase --continue。
    5. rebase以后的提交记录更具线性
    10239771-2dd4bfa2f26af960.png

    git rebase之前的commit记录

    image.png

    git rebase 之后的commit记录

    image.png

    12.4 将多次的提交合并为一次提交

    12.4.1 git rebase -i HEAD~N

    将最近的N个commit合并为同一个commit。

    12.4.1.1 执行前:
    image.png
    12.4.1.2 执行后:
    image.png

    12.4.2 git rebase -i <commit id1> <commit id2>

    将<commitid1>到<commitid2>之间的提交合并成一个提交,左开右闭。所以如果要合并最近的三个提交,那么只需要<commitid1>填倒数第四个提交的commitid, <commitid2>填最近一个提交的commitid即可

    12.4.2.1 执行前:
    10239771-e0b98eb4eb55f320.png
    12.4.2.2 执行后:
    10239771-dc9137290cfd3eb6.png

    Git相似命令比较

    1. 「git reset HEAD^」 VS 「git checkout HEAD^」

    1.1 git reset HEAD^

    git reset HEAD^在当前分支将HEAD指向了前一个节点,这个时候可以直接执行push origin <branch> --force就可以更新远端分支


    image.png

    1.2 git checkout HEAD^

    git checkout HEAD^则是脱离了当前分支,然后将HEAD指向了前一个节点。但是main分支最新的commit依然是C4, 这个时候执行push origin <branch> --force会提示Everything up-to-date。


    image.png

    2. 「git reset HEAD^」VS 「git revert HEAD」

    2.1 git reset HEAD^

    git reset HEAD^将本地分支最新的commit记录指向了前一个节点,最新的commit已经变成了C3,这个时候可以直接执行push origin <branch> --force就可以更新远端分支


    image.png

    2.2 git revert HEAD^

    git revert HEAD则只是将上一次的提交的记录回滚,并且重新提交了一遍,虽然最后的结果跟reset一样,但是在分支上面会新增一个节点


    image.png

    3. 「git cherry-pick」 VS 「git merge」 VS 「git rebase」

    3.1 git cherry-pick

    下图HEAD指向了main, 我们想将cdf分支的C3复制到当前所在位置的话,就可以使用cherry-pick的方式


    image.png

    如图所示,将cdf分支上C3的提交cp到main分支变成了C3',C3'跟C3就只有提交的内容一样,属于不同的两次提交


    image.png

    3.2 git merge

    下图HEAD 是指向了 main,我们想将 cdf 分支的代码合并到 main 分支上来,那么执行 git merge cdf


    image.png

    合并之后,多了一个C6节点,这个节点的父节点有两个,分别是C4和C5。 main和HEAD指向了合并后的新节点


    image.png

    3.3 git rebase

    下图HEAD指向了main, 我们想将cdf 分支的代码合并到main分支,但是又想让提交的记录比较整洁,这个时候就可以使用git rebase的方式


    image.png

    rebase,顾名思义就是重新以XX为父节点。重新创建一个"分支",将需要rebase的分支提交节点给复制过来,然后再将当前分支的节点放到新"分支"最新的节点上。并且HEAD指向了新"分支"(注:这里的分支打个双引号是因为它其实并不是一个真正意义上的分支,它没有分支名,只有HEAD),而且原来分支节点依然还存在,如果还想用到之前的节点,可以通过checkout 对应的commit id即可


    image.png

    Q&A

    1. 应该如何回退自己的git操作

    1.1 发现自己提交的代码有点问题, 想要撤回上一次的提交,但是又想保留原先的修改,那么执行git reset --mixed或者git reset --soft 。 git reset默认就是mixed

    1.2 发现自己的提交就是有问题的,想要撤回上一次的提交,并且不想保留原先的修改,那么可以执行git reset --hard

    1.3 如果我们想要撤回远端分支的提交,但是远端分支又是一个protected的分支,那么我们只能选择git revert的方式将修改还原,但是会在分支上新增一次提交记录

    2. 应该怎么保存自己的代码?

    2.1 一个feature开发完成或者一个bug修改完成,这个时候需要切换分支去做其他事情,那么可以commit到本地仓库,然后推到远端自己建的分支上面。 但是后续如果有些修改但是又不想再增加commit了,那么可以通过git commit -amend的方式来覆盖上一次commit的记录

    2.2 有时候工作区文件改了一半,但是又不想增加一个commit,但是需要把远端的最新代码拉下来又发现有冲突拉代码失败。 这个时候就可以先通过git add的方式放到暂存区,然后git stash将文件保存起来。

    3. 如何快速查到一段代码的修改记录?

    3.1 如果只是想看这段代码是什么时候提交的,可以通过git blame -L N, +M --<file>查看

    其中N代表是从第N行开始, M代表一共要看M行代码, file就是对应的文件名


    image.png

    3.2 如果需要看到某一行代码的修改记录,那么可以通过git log -L N, +M:<file>查看

    其中N代表是从第N行开始, M代表一共要看M行代码, file就是对应的文件名


    10239771-1139b4292e43a37f.png

    3.3 AndroidStudio自带的git功能也非常好用,选中一段代码,右键Git->Show History for Selection就可以查看所有的修改记录

    image.png

    4. 如何快速查找某个人的提交记录?

    git log --author=<email>


    image.png

    5. 如何快速查找某个commit?

    • 通过git log --grep <key> 关键字搜索的方式搜索出所有相关的commit
    • 找到对应的commitid
    • 通过git show <commitid> 就可以找到对应的修改记录


      10239771-b02b0fa86e073da7.png

    6. 如何知道自己的某个commit 都合入了哪些分支 以及哪些版本(tag)?

    如果知道对应的commitid,那么通过git branch --contains <commitid>


    image.png

    如果并不知道commitid,那么需要先通过git log --all --grep <key>的方式找到对应的提交记录,然后通过git branch --contains <commitid>


    image.png

    7. git reset --hard之后代码丢了,怎么恢复

    7.1 如果你的代码现在在工作区或者是暂存区,你不小心执行了git reset --hard命令,那么真的是神仙难救,所以如果工作区有代码,切忌不要执行git reset --hard方法

    7.2 如果你的代码已经push到了远程仓库,你不小心执行了git reset --hard命令,那么只需要git pull就可以恢复。如下图所示

    image.png
    10239771-afbd94145f2d24ec.png
    image.png

    7.3 如果你的代码已经push到了远程仓库,你不小心执行了git reset --hard命令,并且还强制推送到了远端,那么可以执行下面的步骤,如下图所示

    1. 通过git reflog查看所有的操作记录
    2. 找到撤销之前的那条commit
    3. 通过git reset --hard <commitid>
    4. 通过git push origin <branch> 的方式恢复远端分支

    通过git reflog查看所有的操作记录,找到撤销之前的那条commit


    10239771-886d97ffbd9c603e.png

    通过git reset --hard <commitid>,git push origin <branch> 的方式恢复远端分支


    image.png

    8. 新增的文件刚好命中了.gitignore的规则,怎么提交

    image.png

    当你新增的文件或者修改的文件刚好命中了gitignore的规则,那么你执行git add命令的时候会有上面这段提示。通过git add -f <file>的方式就可以添加到暂存区。


    image.png

    当然如果觉得gitignore的规则不合理,修改.gitignore文件即可

    9. 一个文件里面有多个bug单对应的修改或者是有些修改是测试代码,该怎么提交指定的内容

    9.1 通过git add -p <file>的方式筛选出要提交的代码,如下图所示。

    1. 在test10.txt文件中新增四行,然后保存。


      image.png
      image.png
    2. 执行git add -p test10.txt的命令


      image.png
    3. 这里有几个命令需要执行
      a. y: 同意这段修改放入暂存区
      b. n: 不同意这段修改放入暂存区
      c. q: 退出
      d. a: 同意这段修改和这个文件中所有的其他修改都放入暂存区
      e. d: 不同意这段修改以及这个文件中所有的其他修改放入暂存区
      f. e: 自定义选择放入暂存区
      g. ?: 打印帮助
    4. 选择e进入编辑页面
      a. 新增行,不想提交(但是变更仍然在工作区)。删除整行
      b. 删除行,不想提交。用空格符" "代替"-"字符。
      c. 变更行,不想提交。上面两个结合——对于"+"所在行整行删除,对于"-"所在行,用空格符" "代替"-"字符
    image.png
    1. 删除「add new line 2」和「add new line3」然后保存。然后执行git commit将test10提交到本地仓库


      image.png
    2. 根据commitid查看修改记录


      image.png

    9.2 使用sourcetree提交

    执行命令行来提交指定的内容多少是有点不直观,并且不易上手,采用sourcetree的方式就非常直观,选中指定的提交的内容然后点击暂存行即可


    image.png

    10. git push origin <branch> --force以后,如何回退

    git push origin <branch> --force以后,远端的分支节点已经发生了改变,但是本地分支依然是有以前的commit记录,所以先使用git reflog找到之前的操作记录,通过git reset -hard <commitid>的方式回退到当时的版本, 然后git push origin <branch>来更新远端分支

    相关文章

      网友评论

          本文标题:git命令详解

          本文链接:https://www.haomeiwen.com/subject/mopordtx.html