git 的三种状态

  • 已修改表示修改了文件,但还没保存到数据库中。
  • 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
  • 已提交表示数据已经安全地保存在本地数据库中。

    修改文件但未添加和提交操作


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    echo 123 >> a.txt // 写入数据
    // 查看给i他状态
    $ git status
    On branch master
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git restore <file>..." to discard changes in working directory)
    modified: a.txt //已修改

    no changes added to commit (use "git add" and/or "git commit -a")

    修改文件和已添加但未提交操作


    1
    2
    3
    4
    5
    6
    7
    git add . // .代表全部添加(暂存)也可以指定文件

    $ git status
    On branch master
    Changes to be committed:
    (use "git restore --staged <file>..." to unstage)
    modified: a.txt

    修改文件和添加、提交都已完成


    1
    git commit -m 'committed' // 提交文件,-m 添加描述信息

    常用指令

    log查看历史版本

    git log查看历史版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    commit 1db41afa0c09a7247f39b216963e96342b5576c6
    Author: Author <Author@qq.com>
    Date: Sun Oct 2 00:03:51 2022 +0800

    second // 描述信息提交时用户书写

    commit 6bed6372c984dba9e48538f440fbb4fe91698c6e
    Author: Author <Author@qq.com>
    Date: Sat Oct 1 23:56:38 2022 +0800

    first // 描述信息提交时用户书写

    Git 用以计算校验和的机制叫做 SHA-1 散列(hash,哈希)。 这是一个由 40 个十六进制字符
    (0-9 和 a-f)组成的字符串,基于 Git 中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样:

    Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。

    回退版本

    git reset 和 git chekout 都可以回滚快照

    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
    git reset head~   // 回退上个版本
    git reset head~~ // 回退上两个版本
    git reset head~10 // 回退上10个版本

    // 提交完发现文件还是没有改回上个版本的内容但是版本库其实已经修改好了
    $ git status
    On branch master
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git restore <file>..." to discard changes in working directory)
    modified: a.txt

    no changes added to commit (use "git add" and/or "git commit -a")

    // reset参数介绍
    // --hard : 回退版本库,暂存区,工作区。(因此我们修改过的代码就没了,需要谨慎使用)
    // reset 不仅移动 HEAD 的指向,将快照回滚动到暂存区域,它还将暂存区域的文件还原到工作目录。
    // --mixed: 回退版本库,暂存区。(--mixed为git reset的默认参数,即当任何参数都不加的时候的参数)
    // --soft: 回退版本库。

    $ git reset --hard head~
    HEAD is now at 1db41af second // 现在文件夹的文件也会退到上个版本的内容了

    // 不仅可以往回滚,还可以往前滚!
    $ git reflog // 可以看到你提交的所有版本
    1db41af (HEAD -> master) HEAD@{0}: reset: moving to head~
    2691789 HEAD@{1}: commit: third
    1db41af (HEAD -> master) HEAD@{2}: reset: moving to head~
    6897dbc HEAD@{3}: commit: second
    1db41af (HEAD -> master) HEAD@{4}: commit: second
    6bed637 HEAD@{5}: commit (initial): first
    $ git reset --hard 6897dbc // 就可以回到second版本
    1
    未完待续···

    版本对比

    暂存区和工作目录相比

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ git diff
    warning: LF will be replaced by CRLF in a.txt.
    The file will have its original line endings in your working directory
    diff --git a/a.txt b/a.txt
    index fcfc20f..fb9d840 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -1,2 +1,3 @@
    123
    345
    +345

    工作树和最新提交

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ git diff head
    diff --git a/a.txt b/a.txt
    index fcfc20f..fb9d840 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -1,2 +1,3 @@
    123
    345
    +345

    两个历史快照

    1
    2
    3
    4
    5
    6
    7
    8
    $ git diff 5da78a4 c7c0e3b
    diff --git a/b.txt b/b.txt
    deleted file mode 100644
    index 81c545e..0000000
    --- a/b.txt
    +++ /dev/null
    @@ -1 +0,0 @@
    -1234

    比较仓库和暂存区

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ git diff --cached c7c0e3b
    diff --git a/b.txt b/b.txt
    new file mode 100644
    index 0000000..9ab39d5
    --- /dev/null
    +++ b/b.txt
    @@ -0,0 +1,4 @@
    +123
    +1212

    删除文件

    不小心删除文件怎么办?

    1
    2
    3
    4
    5
    6
    7
    8
    $ git status
    On branch master
    Changes not staged for commit:
    (use "git add/rm <file>..." to update what will be committed)
    (use "git restore <file>..." to discard changes in working directory)
    deleted: a.txt // 手动删除工作区的a.txt文件

    $ git checkout -- a.txt // 文件恢复

    重命名文件

    git mv 旧文件名 新文件名

    1
    2
    3
    4
    5
    6
    7
    $ git mv a.txt b.txt

    $ git status
    On branch master
    Changes to be committed:
    (use "git restore --staged <file>..." to unstage)
    renamed: a.txt -> b.txt

    忽略文件

    让Git 识别某些格式的文件,然后自主不跟踪它们

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $ echo 123 >> a.temp
    $ git status
    On branch master
    Untracked files:
    (use "git add <file>..." to include in what will be committed)
    .gitignore
    a.temp
    // 将temp后缀的文件忽略
    $ echo *.temp > .gitignore
    $ git status
    On branch master
    Untracked files:
    (use "git add <file>..." to include in what will be committed)
    .gitignore // a.temp没有被git追踪

    $ echo .gitignore >> .gitignore // 将自己忽略

    分支

    分支是什么

    操作分支

    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
    // 创建分支
    $ git branch V1.0

    // 删除分支
    $ git branch -D v1.1
    Deleted branch v1.1 (was 1d89502).

    // 切换分支
    $ git checkout V1.0
    Switched to branch 'V1.0'

    // 查看分支
    $ git status
    On branch V1.0 // 分支名称
    nothing to commit, working tree clean

    // 操作分支
    $ echo v10 >> v1.txt
    $ git add .
    $ git commit -m 'v10'
    [V1.0 15024da] v10
    1 file changed, 1 insertion(+)
    create mode 100644 v1.txt // 文件提交成功
    $ ls
    a.temp b.txt v1.txt
    // 切换会主分支
    $ git checkout master
    Switched to branch 'master'
    $ ls
    a.temp b.txt //在v10创建的文件没有合并到主分支

    // 切换主分支
    $ git checkout master
    // 合并分支
    $ git merge v1.0
    Updating 7a71280..15024da
    Fast-forward
    v1.txt | 1 +
    1 file changed, 1 insertion(+)
    create mode 100644 v1.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
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      // 创建第二个分支
      $ git branch v1.1

      $ git checkout v1.0
      Switched to branch 'v1.0'
      $ ls
      a.temp b.txt v1.txt
      // v1.0 修改数据
      $ echo 00 >> b.txt

      $ git add .
      $ git commit -m 'merge1'
      [v1.0 7626c97] merge1
      1 file changed, 1 insertion(+)

      // 更改第二个分支
      $ git checkout v1.1
      Switched to branch 'v1.1'
      M b.txt
      // 同时修改b.txt内容
      $ echo 000 >> b.txt

      $ git add .
      $ git commit -m 'merge2'
      [v1.1 1d89502] merge2
      1 file changed, 1 insertion(+), 1 deletion(-)

      $ git checkout master
      Switched to branch 'master'
      $ git merge v1.1
      Auto-merging b.txt
      CONFLICT (content): Merge conflict in b.txt
      Automatic merge failed; fix conflicts and then commit the result.

      // 出现报错
      <<<<<<< HEAD
      00

      =======
      00000
      >>>>>>> v1.1
      多次的修改git不知道merge那个分支可以自行选择删除

    远程操作

    添加一个远程仓库

    1
    $ git remote add origin https://gitee.com/panther125/git-study.git

    把代码推送到远程仓库

    1
    $ git push -u origin master

    列出所有的远程仓库

    1
    git remote -v

    显示某个远程仓库信息

    1
    git remote show [remote]

    开发基本步骤

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 克隆项目代码
    $ git clone https://gitee.com/panther125/git-study/branches/setting

    // 创建分支
    $ git branch v1.1

    // 开发代码
    。。。。。。

    // 合并分支
    $ git checkout dev
    $ git merge v1.1

    // 推送代码
    $ git push

    协议选择

    HTTPS优缺点

  • 优点1: 相比 SSH 协议,可以使用用户名/密码授权是一个很大的优势,这样用户就不必须在使用 Git
    之前先在本地生成 SSH 密钥对再把公钥上传到服务器。 对非资深的使用者,或者系统上缺少 SSH
    相关程序的使用者,HTTP 协议的可用性是主要的优势。 与 SSH 协议类似,HTTP 协议也非常快和高效
  • 优点2: 企业防火墙一般会打开 80 和 443 这两个常见的http和https协议的端口,使用http和https的协议在架设了防火墙的企业里面就可以绕过安全限制正常使用git,非常方便
  • 缺点: 使用http/https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令.
    但是现在操作系统或者其他git工具都提供了 keychain 的功能,可以把你的账户密码记录在系统里,
    例如OSX 的 Keychain 或者 Windows 的凭证管理器。所以也只需要输一次密码就搞定了。

    SSH的优缺点

  • 优点1: 架设 Git 服务器时常用 SSH 协议作为传输协议。 因为大多数环境下已经支持通过 SSH 访问 ——
    即时没有也比较很容易架设。 SSH 协议也是一个验证授权的网络协议;并且,因为其普遍性,架设和使用都很容易。

  • 缺点1: SSH服务端一般使用22端口,企业防火墙可能没有打开这个端口。

  • 缺点2: SSH 协议的缺点在于你不能通过他实现匿名访问。 即便只要读取数据,使用者也要有通过 SSH
    访问你的主机的权限,这使得 SSH 协议不利于开源的项目。 如果你只在公司网络使用,SSH
    协议可能是你唯一要用到的协议。 如果你要同时提供匿名只读访问和 SSH 协议,那么你除了为自己推送架设 SSH
    服务以外,还得架设一个可以让其他人访问的服务。

    总结

  1. HTTPS利于匿名访问,适合开源项目可以方便被别人克隆和读取(但他没有push权限);
    毕竟为了克隆别人一个仓库学习一下你就要生成个ssh-key折腾一番还是比较麻烦,
    所以github除了支持ssh协议必然提供了https协议的支持。

  2. 而SSH协议使用公钥认证比较适合内部项目。
    当然了现在的代码管理平台例如github、gitliab,
    两种协议都是支持的,基本上看自己喜好和需求来选择就可以了。


    1
    2
    3
    4
    5
    ssh-keygen -t rsa -C "510180298@qq.com"  // 按照提示三次回车后生成

    //添加后,在终端(Terminal)中输入
    ssh -T git@gitee.com
    若返回 Hi XXX! You've successfully authenticated, but Gitee.com does not provide shell access. 内容,则证明添加成功