Git基础教程

Git仓库

本地仓库

所有的代码压缩存储在.git文件夹下

远程仓库

集中存储了, 所有开发协作者的代码提交, 相当于线上的中心仓库

Git基本概念

文件的状态

  1. 未跟踪状态(Untracked)
    一个新增的文件, 从未交给Git去管理.

    1. Untracked files:
    2. (use "git add <file>..." to include in what will be committed)
    3. test/hello.js
  2. 已跟踪状态
    曾经或历史版本已被Git管理过的文件

  3. 未修改状态
    从本地仓库检出后的代码, 未做任何修改的状态
  4. 已修改状态
    文件内容已被修改的状态

    1. cms-nest-api git:(migaration-job) git status
    2. On branch migaration-job
    3. Changes not staged for commit:
    4. (use "git add <file>..." to update what will be committed)
    5. (use "git checkout -- <file>..." to discard changes in working directory)
    6. modified: src/modules/tracking/AsendiaTracking.job.ts
  5. 暂存状态
    被加入到暂存区域空间中, 等待提交的状态 ```shell ➜ cms-nest-api git:(migaration-job) ✗ git status On branch migaration-job Changes to be committed: (use “git reset HEAD …” to unstage)

    1. modified: src/modules/tracking/AsendiaTracking.job.ts

Untracked files: (use “git add …” to include in what will be committed)

  1. test/hello.js
  1. 6. 已提交状态<br />已经提交到本地仓库中的文件所处的状态
  2. <a name="1e9ae6ba"></a>
  3. #### 配置相关命令
  4. 1. git config -l: 列出所有当前项目仓库的配置信息(当前用户级别/项目级别)
  5. ```shell
  6. # 列出所有当前项目仓库的配置信息(当前用户级别/项目级别)
  7. git config -l
  8. credential.helper=osxkeychain
  9. user.name=xiewenzhen
  10. user.email=xiewenzhen@ftl-express.cn
  11. core.autocrlf=input
  12. core.ignorecase=false
  13. core.repositoryformatversion=0
  14. core.filemode=true
  15. core.bare=false
  16. core.logallrefupdates=true
  17. core.ignorecase=true
  18. core.precomposeunicode=true
  19. remote.origin.url=git@gitlab.com:ftl-group/middle/cms-nest-api.git
  20. remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
  21. # 设置
  22. git config core.autocrlf true
  1. git config name value: 设置项目的Git仓库配置
    1. # 设置了代码换行符转化的策略 仅仅只是演示
    2. git config core.autocrlf true
    3. # 设置git的用户名
    4. git config user.name xiewenzhen

获取与创建项目

  1. git init: 在当前目录初始化一个本地git仓库

    1. git init
    2. Initialized empty Git repository in /Users/xiewenzhen/git_demo/.git/
  2. git clone: 获得一份已经存在了的 Git 仓库的拷贝

    1. git clone https://github.com/libgit2/libgit2

快照基础

  1. git add 将修改的文件加入到Git暂存区.

    1. git add src/common/BasicEntity.ts
    2. git_demo git:(test) git status
    3. On branch test
    4. Changes to be committed:
    5. (use "git reset HEAD <file>..." to unstage)
    6. modified: src/common/BasicEntity.ts
  2. git status: 查看当前工作目录的所有文件状态 ```shell ➜ git_demo git:(next) git status On branch next Changes not staged for commit: (use “git add …” to update what will be committed) (use “git checkout — …” to discard changes in working directory)

    1. modified: src/common/BasicEntity.ts

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

  1. > 提示:
  2. > 细心的小伙伴, 不知道是否已经注意到了
  3. > (use "git add ..." to update what will be committed)
  4. > 这段语句? 这段话告诉我们: 通过git add 把将要提交的文件, 加入到暂存区中去. 然后执行提交命令, 就可以把
  5. > 文件提交到本地git仓库中了.
  6. > git status就像是一个指引者, 通过该命令, 我们可以获得很多指令提示. 多多关注它, 你会收获不一样的惊喜哦.
  7. 3. git diff: 查看你工作环境与你的暂存区的差异(`git diff` 默认的做法),你暂存区域与你最后提交之间的差异(`git diff --staged`),或者比较两个提交记录的差异(`git diff master branchB`)。
  8. 3. git commit -m: 提交暂存区的代码至本地Git仓库中.
  9. ```shell
  10. git commit -m "message"
  1. 命令执行后,提示:

    1. git commit -m "test commit"
    2. [test 4d5ee35] test commit
    3. 1 file changed, 2 insertions(+)
  2. 使用git log查看刚才提交的节点, 结果如下:

    1. commit 4d5ee357220c33949f53ddf8b6db7f8ee3db2b06 (HEAD -> test)
    2. Author: xiewenzhen <xiewenzhen@ftl-express.cn>
    3. Date: Wed Dec 30 18:45:19 2020 +0800
    4. test commit
  3. 漏掉了几个文件没有添加

    1. $ git commit -m 'initial commit'
    2. $ git add forgotten_file
    3. $ git commit --amend
  4. 修改提交信息

    1. $ git commit --amend
  5. 然后按提示操作吧.

  6. git reset: 取消暂存的文件

    1. git reset HEAD src/common/BasicEntity.ts
  7. 执行命令前:

    1. git status
    2. On branch test
    3. Changes to be committed:
    4. (use "git reset HEAD <file>..." to unstage)
    5. modified: src/common/BasicEntity.ts
  8. 文件状态显示: Changes to be committed:
    执行命令后:

    1. git status
    2. On branch test
    3. Changes not staged for commit:
    4. (use "git add <file>..." to update what will be committed)
    5. (use "git checkout -- <file>..." to discard changes in working directory)
    6. modified: src/common/BasicEntity.ts
  9. 文件状态显示: Changes not staged for commit:

  10. git rm: 从工作区,或者暂存区移除文件

    1. $ git rm src/main/java/org/example/demo/ioc/context/test.java
    2. rm 'src/main/java/org/example/demo/ioc/context/test.java'
  11. git clean: 从工作区中移除不想要的文件

    1. $ git clean -df
    2. Removing src/main/java/org/example/demo/ioc/facotry/test.java

分支与合并

  1. git branch: 查看当前分支

    1. $ git branch
  2. git branch -a: 查看所有分支 ```shell git branch -a

  • next remotes/origin/bill-task remotes/origin/deploy-production remotes/origin/deploy-staging remotes/origin/front-trans-route remotes/origin/master remotes/origin/migaration-job remotes/origin/next remotes/origin/refactor-label-format (END) ```
  1. git checkout : 丢弃文件的改动

    1. git checkout -- src/main/java/org/example/demo/ioc/pojo/User.java

    提示:

    1. `git checkout -- <file>` 是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
  2. git checkout next: 检出next分支的代码,并在本地仓库新建一个next分支.

    1. git checkout next

    提示:

    1. git checkout next git checkout -b next的区别分析:
    2. 条件: 如果next分支在远程仓库中存在
    3. 行为:
    4. git checkout next: 会新建next分支,并检出next分支最新的代码
    5. git checkout -b next: 同上
    6. 条件: next分支在远程仓库中不存在
    7. 行为:
    8. git checkout next: 会报错
    9. git checkout -b next: 会新建next分支,并检出next分支最新的代码
  3. git merge: 合并一个或者多个分支到你已经检出的分支中。然后它将当前分支指针移动到合并结果上

    1. $ git checkout master
    2. Switched to branch 'master'
    3. $ git merge git-command-test
    4. Merge made by the 'recursive' strategy.
    5. src/main/java/org/example/demo/ioc/git/GitCommandTest.java | 7 +++++++
    6. 1 file changed, 7 insertions(+)
    7. create mode 100644 src/main/java/org/example/demo/ioc/git/GitCommandTest.java
    8. $ git branch -d git-command-test
    9. Deleted branch git-command-test (was 5dc4e13).
  4. git log: 用来展示一个项目的可达历史记录,从最近的提交快照起 ```shell $ git log commit 041b9d2948dac00d50421b819aa08a8b42c4eb8e Merge: 368e3d6 5dc4e13 Author: wen_xiaoqoing w1064354066@163.com Date: Thu Jan 7 10:47:24 2021 +0800

    Merge branch ‘git-command-test’

commit 5dc4e1319e6176ba19ae3b36335ea46663ba16c9 Author: wen_xiaoqoing w1064354066@163.com Date: Wed Jan 6 17:12:49 2021 +0800

  1. git command test
  1. 6. git stash: 临时地保存一些还没有提交的工作,以便在分支上不需要提交未完成工作就可以清理工作目录<br />适用场景: 就是在一次开发过程中,代码未写完全,突然有紧急的bug要修复, 但是我又不想提交不完全代码. 这时可以使用git stash命令去解决.
  2. ```shell
  3. git stash save
  4. git stash apply
  5. git stash pop
  6. git stash clear
  7. git stash show stashName
  1. 场景如下图:
    image-20201230195249995
    当我本地分支test工作目录有文件改动时, 检出bill-task分支会有报错提示, 这时.可以执行git stash save贮藏本地文件改动
    参考链接: 贮藏与清理

项目分享与更新

  1. git fetch -p: 从远程仓库拉取代码

    1. git fetch -p
    2. remote: Enumerating objects: 137, done.
    3. remote: Counting objects: 100% (137/137), done.
    4. remotes/origin/bill-task
    5. remotes/origin/deploy-production
    6. remotes/origin/deploy-staging
    7. remotes/origin/front-trans-route
    8. remotes/origin/master
    9. remotes/origin/migaration-job
    10. remotes/origin/next
    11. remotes/origin/refactor-label-format
    12. ...skipping...
    13. remote: Compressing objects: 100% (90/90), done.
    14. remote: Total 1215 (delta 75), reused 65 (delta 43), pack-reused 1078
    15. Receiving objects: 100% (1215/1215), 640.46 KiB | 146.00 KiB/s, done.
    16. Resolving deltas: 100% (682/682), done.
    17. From gitlab.com:ftl-group/middle/cms-nest-api
    18. * [new branch] bill-task -> origin/bill-task
    19. * [new branch] deploy-production -> origin/deploy-production
    20. * [new branch] deploy-staging -> origin/deploy-staging
    21. * [new branch] front-trans-route -> origin/front-trans-route
    22. * [new branch] master -> origin/master
    23. * [new branch] migaration-job -> origin/migaration-job
    24. * [new branch] next -> origin/next
    25. * [new branch] refactor-label-format -> origin/refactor-label-format
    26. * [new tag] v0.3.0 -> v0.3.0
  2. git pull: 基本是 git fetchgit merge 命令的组合体,Git 从你指定的远程仓库中抓取内容,然后马上尝试将其合并进你所在的分支中

  3. git push: 推送当前分支到远程仓库

    1. $ git push origin test
  4. 结果如下:

    1. git push origin test
    2. Enumerating objects: 9, done.
    3. Counting objects: 100% (9/9), done.
    4. Delta compression using up to 8 threads
    5. Compressing objects: 100% (5/5), done.
    6. Writing objects: 100% (5/5), 429 bytes | 429.00 KiB/s, done.
    7. Total 5 (delta 4), reused 0 (delta 0)
    8. remote:
    9. remote: To create a merge request for test, visit:
    10. remote: https://gitlab.com/ftl-group/middle/cms-nest-api/-/merge_requests/new?merge_request%5Bsource_branch%5D=test
    11. remote:
    12. To gitlab.com:ftl-group/middle/cms-nest-api.git
    13. * [new branch] test -> test
  5. git remote add : 添加一个新的远程 Git 仓库,同时指定一个方便使用的简写

    1. git remote add origin git@gitlab.com:ftl-group/middle/cms-nest-api.git
  6. git remote -v: 显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL

    1. git remote -v
    2. origin git@gitlab.com:ftl-group/middle/cms-nest-api.git (fetch)
    3. origin git@gitlab.com:ftl-group/middle/cms-nest-api.git (push)

检查与比较

git show: 以一种简单的人类可读的方式来显示一个 Git 对象。 一般使用此命令来显示一个标签或一个提交的信息。

  1. $ git show
  2. commit 041b9d2948dac00d50421b819aa08a8b42c4eb8e
  3. Merge: 368e3d6 5dc4e13
  4. Author: wen_xiaoqoing <w1064354066@163.com>
  5. Date: Thu Jan 7 10:47:24 2021 +0800
  6. Merge branch 'git-command-test'

调试

  1. git bisect: 通过自动进行一个二分查找来找到哪一个特定的提交是导致 bug 或者问题的第一个提交

    1. $ git bisect start
    2. $ git bisect bad
    3. $ git bisect good master
    4. Bisecting: a merge base must be tested
    5. [5dc4e1319e6176ba19ae3b36335ea46663ba16c9] git command test
    6. $ git bisect good
    7. 0f1873168ea2d1aa95034156c62b7c4b71fa44fd is the first bad commit
    8. commit 0f1873168ea2d1aa95034156c62b7c4b71fa44fd
    9. Author: wen_xiaoqoing <w1064354066@163.com>
    10. Date: Thu Jan 7 11:32:40 2021 +0800
  2. git blame: 指出文件的每一行的最后的变更的提交及谁是那一个提交的作者

    1. $ git blame -L 1,13 src/main/java/org/example/demo/ioc/pojo/User.java

补丁

  1. git cherry-pick: 获得在单个提交中引入的变更,然后尝试将作为一个新的提交引入到你当前分支上

    1. # 4d5ee357是某个commit节点的id
    2. git cherry-pick 4d5ee357
    3. # 拾取origin/migaration-job分支的头结点
    4. git cherry-pick origin/migaration-job
  2. git rebase: 变更基点
    当前分支是test, 如下图所示:
    image-20201230192511696
    目标: 将test commit 这个节点rebase到origin/bill-task分支上
    执行下面的命令即可:

    1. git rebase origin/bill-task
  3. 校验结果:
    image-20201230192719379

  4. git rebase -i head~3: 压缩节点
    test 分支上有三个节点commit1~3改动如下:
    • commit1提交了BasicEntity.ts文件
    • commit2 提交了commit2.txt文件
    • commit3 提交了commit3.txt文件

如下图所示:
image-20201230193502887
期待结果:
将commit1~3三个节点压缩成一个, rebase-commit节点提交
如下操作:

  1. git rebase -i head~3

接着按下图提示做相应修改.
image-20201230193702615
执行成功后, 结果校验如下图:
image-20201230193848032
若出现异常,可强制停止当前rebase操作:

  1. git rebase --abort
  1. git revert: 将你提交中的变更的以完全相反的方式的应用到一个新创建的提交中,本质上就是撤销或者倒转
    1. $ git log
    2. $ git revert -n 5dc4e1319e6176ba19ae3b36335ea46663ba16c9
    3. $ git commit -m "revert git command test"
    4. [bisect_test fd3e951] revert git command test
    5. Date: Thu Jan 7 11:32:40 2021 +0800
    6. 1 file changed, 7 deletions(-)
    7. delete mode 100644 src/main/java/org/example/demo/ioc/git/GitCommandTest.java

管理

  1. git reflog: 分析你所有分支的头指针的日志来查找出你在重写历史上可能丢失的提交 ```shell $ git reflog 0f18731 HEAD@{0}: checkout: moving from 5dc4e1319e6176ba19ae3b36335ea46663ba16c9 to bisect_test 5dc4e13 HEAD@{1}: checkout: moving from bisect_test to 5dc4e1319e6176ba19ae3b36335ea46663ba16c9 0f18731 HEAD@{2}: commit: bisect test 5dc4e13 HEAD@{3}: checkout: moving from master to bisect_test $ git show HEAD@{3} commit 5dc4e1319e6176ba19ae3b36335ea46663ba16c9 Author: wen_xiaoqoing w1064354066@163.com Date: Wed Jan 6 17:12:49 2021 +0800

+package org.example.demo.ioc.git; + +public class GitCommandTest {

  • public static void main(String[] args) {
  • System.out.println(“This is a git command test!”);
  • } +} ```
  1. git filter-branch: 根据某些规则来重写大量的提交记录,例如从任何地方删除文件,或者通过过滤一个仓库中的一个单独的子目录以提取出一个项目