超~ 超~ 超~详细的Git命令行教程

Git简介

Git是什么?

Git是目前世界上最先进的分布式 版本控制系统(没有之一)

版本控制系统

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统

集中式版本控制系统(Centralized Version Control Systems,简称 CVCS)

问题:
中央服务器的单点故障。 如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。 如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据------包括项目的整个变更历史,只剩下人们在各自机器上保留的单独快照。

思考:
SVN是不是集中式版本控制系统?离线状态下是否可以查看版本修改历史?

分布式版本控制系统 (Distributed Version Control System,简称 DVCS)

客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

思考:
Git是不是分布式版本控制系统吗?离线状态下是否可以查看版本修改历史?

Git的诞生

同生活中的许多伟大事物一样,Git 诞生于一个极富纷争大举创新的年代。

Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。 到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。

到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统。

Git初体验

名词解释

已修改(modified) 已暂存(staged) 已提交(committed)
工作区(工作目录) 暂存区 Git 目录(Git 仓库)
名词说明 名词解释
工作区(工作目录) 工作区是对项目的某个版本独立提取出来的内容;也就是我们在VSCode中打开的代码目录
暂存区 暂存区是一个文件,保存了下次将要提交的文件列表信息,一般在 Git 仓库目录中
Git 目录(Git 仓库) Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。这是 Git 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。

思考:

Git的工作流程?工作区 暂存区 Git目录?

安装

初始化

初始化Git配置

js 复制代码
$ git config --global user.name "Amos" 
$ git config --global user.email "Amos.aa@163.com" 
$ git config --list  // 查看你的git config  
$ git config user.name  // 查看单个git config的值

获取帮助

Git命令行工具很友好,提供了配套的命令行帮助手册:

js 复制代码
$ git help <verb>
$ git <verb> --help

例如:你想要获取git config命令的手册,执行下面命令:

js 复制代码
$ git config --help 

初始化Git仓库

本地目录转换为 Git 仓库
js 复制代码
$ cd workspace-to-git
$ git init   // 主要是这一句 初始化一个Git仓库
$ git status 
$ git add .
$ git commit -m '我已经是一个Git仓库啦!!!'
从其它服务器 克隆 一个已存在的 Git 仓库
js 复制代码
$ git clone git@gitlab.com:amos/git-teaching-project.git

Git工作流

工作目录的文件只有 已跟踪未跟踪 两种状态;
已跟踪 :就是 Git 已经知道的文件
未跟踪:除已跟踪文件外的其它所有文件都属于未跟踪文件

检测当前文件状态:git status

js 复制代码
$ git status // 检查当前文件目录文件文件的状态 
On branch master 
Your branch is up to date with 'origin/master'.  
nothing to commit, working tree clean  // 此时说明工作目录时干净的 

新增UNTRACKED.md文件,再次查看文件状态:

js 复制代码
//增加一行:## 修改README.md文件,查看文件状态:git status
$ echo "新增一个Untracked文件" > UNTRACKED.md  
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)
          UNTRACKED.md

nothing added to commit but untracked files present (use "git add" to track)

跟踪新文件: git add <file>

js 复制代码
// 把当前Untracked文件添加到暂存区中 
$ git add UNTRACKED . md    

// 再次通过git status 查看文件状态 
$ git status
On branch master 
Your branch is ahead of 'origin/master' by 1 commit.   
(use "git push" to publish your local commits)  
Changes to be committed:   
 (use "git restore --staged <file>..." to unstage)
    new file:   UNTRACKED.md  

暂存已修改的文件: git add <file>

js 复制代码
$ vim README . md  // 修改README.md文件 

// 查询当前文件的状态 
$ git status  
On branch master Your branch is ahead of 'origin/master' by 1 commit.   
(use "git push" to publish your local commits)  
Changes to be committed:   
(use "git restore --staged <file>..." to unstage) 
    new file:   UNTRACKED.md  
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:   README.md          

$ git add README.md  // 暂存已修改的文件 

// 再次查询文件状态 
$ git status 
On branch master Your branch is ahead of 'origin/master' by 1 commit.   
(use "git push" to publish your local commits)  
Changes to be committed:   
(use "git restore --staged <file>..." to unstage) 
modified:   README.md         
new file:   UNTRACKED.md 

状态简览: git status -s

js 复制代码
$ git status -s  //打印简洁版的文件状态信息 
M  README.md      // M -- modified 
A  UNTRACKED.md   // A --  new file 
?? ADD.md         // ?? -- Untacked file 

查看已暂存和未暂存的修改:git diff <--staged>

查看暂存区跟工作目录的差异:git diff

js 复制代码
$ git status // 先查看一下当前的文件状态 
On branch master Your branch is ahead of 'origin/master' by 1 commit.   
(use "git push" to publish your local commits)  
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:   README.md  
    Untracked files:   
(use "git add <file>..." to include in what will be committed)         ADD.md         
      UNTRACKED.md  
no changes added to commit (use "git add" and/or "git commit -a") 

// 此时使用git diff 查看的就是暂存区跟工作目录的差异 
$ git diff diff --git a/README.md b/README.md 
index c8730ea..97deb14 100644 
--- a/README.md 
+++ b/README.md 
@@ -1,3 +1,4 @@  
# Git-Teaching-Project  
本项目用于Git练习使用,可以自由贡献  
# Git是分布式版本控制系统吗? 离线状态下你可以看到这条修改记录吧! 
+# 我在修改一下文件,使用git status 就会看我已经被修改了 

查看暂存区跟Git 库的差异:git diff --staged

js 复制代码
// 把UNTACKED.md增加到暂存区 
$ git add UNTRACKED.md  

// 查看当文件状态 
$ git status 
On branch master Your branch is ahead of 'origin/master' by 1 commit.   
(use "git push" to publish your local commits)  
Changes to be committed:   
(use "git restore --staged <file>..." to unstage)         
new file:   UNTRACKED.md  
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:   README.md  
    Untracked files:   
(use "git add <file>..." to include in what will be committed) 
    ADD.md  
    
// 使用 git diff -staged 查看暂存区与Git库之间的差异 
$ git diff --staged 
diff --git a/UNTRACKED.md b/UNTRACKED.md 
new file mode 100644 
index 0000000..f32c764
--- /dev/null 
+++ b/UNTRACKED.md
@@ -0,0 +1 @@ 
+新增一个Untracked文件 

提交更新:git commit -m "commit message"

js 复制代码
// 同样查询文件目录中的文件状态 
$ git status 
On branch master Your branch is ahead of 'origin/master' by 1 commit.   
(use "git push" to publish your local commits) 
Changes to be committed:   
(use "git restore --staged <file>..." to unstage)   
    new file:   UNTRACKED.md 
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:   README.md  
    Untracked files:   
(use "git add <file>..." to include in what will be committed)         ADD.md          
// 使用git commit -m 提交暂存区的修改       
$ git commit -m "add UNTRACKED.md file" 
[master b2c91ad] add UNTRACKED.md file  
1 file changed, 1 insertion(+) 
create mode 100644 UNTRACKED.md  

跳过使用暂存区:git commit -a -m "commit message"

js 复制代码
// 同样还是查看工作目录当前文件的状态 
$ git status 
On branch master Your branch is ahead of 'origin/master' by 2 commits.   
(use "git push" to publish your local commits)  
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:   README.md  
    Untracked files:   
(use "git add <file>..." to include in what will be committed)         ADD.md 

// 跳过暂存区直接提交文件 
$ git commit -a -m "restore staged and commit all file" 
[master a3a9cde] restore staged and commit all file 
1 file changed, 1 insertion(+)   

// 提交完了之后,再次使用 git status 命令来查看当前工作目录文件状态 
$ git status 
On branch master Your branch is ahead of 'origin/master' by 3 commits.   
(use "git push" to publish your local commits)  

Untracked files:  
 (use "git add <file>..." to include in what will be committed)     
     ADD.md
 nothing added to commit but untracked files present (use "git add" to track)

查看提交历史

查看全部提交历史:git log

js 复制代码
// 使用git log可以查看到我们全部的提交记录 
$ git log 
commit a3a9cde7f0c08c0871950f50988aeffa9dd3a3d4 (HEAD -> master) 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 20:24:00 2023 +0800      
    restore staged and commit all file  
    
commit b2c91ad77b3473a5365e7cf94e98ab1f87c6b21f 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 20:19:51 2023 +0800      
    add UNTRACKED.md file  
    
commit a2f63f056dcf970cdd9f0d60c7b62a11e831eeaf 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 17:23:48 2023 +0800     
    再次提交修改  
commit 7142ab54ae17094f8b9673025da5d0d9071ee7af(origin/master, origin/HEAD) 
Author: Amos <amos@163.com>
Date:   Tue Apr 25 14:29:57 2023 +0800     
    git online test  

commit 7aa3a1049c7117fccf21a93cf0177fb9648a3074 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 09:09:47 2023 +0800      
    Initial commit

限制显示的日志条目数量: git log <-num>

js 复制代码
// 限制日志打印的条数为2条 
$ git log -2 
commit a3a9cde7f0c08c0871950f50988aeffa9dd3a3d4 (HEAD -> master) 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 20:24:00 2023 +0800      
    restore staged and commit all file  
    
commit b2c91ad77b3473a5365e7cf94e98ab1f87c6b21f 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 20:19:51 2023 +0800      
    add UNTRACKED.md file 

显示每次提交所引入的差异(修改明细):git log --patch

js 复制代码
// 显示每次提交所引入的明细 
$ git log --patch - 2 
commit a3a9cde7f0c08c0871950f50988aeffa9dd3a3d4 (HEAD -> master) 
Author: Amos <amos@163.com>
Date:   Tue Apr 25 20:24:00 2023 +0800      
    restore staged and commit all file  
    
diff --git a/README.md b/README.md 
index c8730ea..97deb14 100644 
--- a/README.md +++ b/README.md
@@ -1,3 +1,4 @@ 
# Git-Teaching-Project  
本项目用于Git练习使用,可以自由贡献  
# Git是分布式版本控制系统吗? 离线状态下你可以看到这条修改记录吧! 
+# 我在修改一下文件,使用git status 就会看我已经被修改了  

commit b2c91ad77b3473a5365e7cf94e98ab1f87c6b21f 
Author: Amos <amos@163.com> 
Date:   Tue Apr 25 20:19:51 2023 +0800      
    add UNTRACKED.md file  
    
diff --git a/UNTRACKED.md b/UNTRACKED.md 
new file mode 100644 
index 0000000..f32c764 
--- /dev/null 
+++ b/UNTRACKED.md 
@@ -0,0 +1 @@
+新增一个Untracked文件 

提交的简略统计信息:git log --stat

撤销操作

重新提交:git commit --amend

有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令来重新提交

js 复制代码
// 查询当我工作目录文件状态 已修改ADD.md README.md两个文件
$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)

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:   ADD.md
      modified:   README.md

// 只添加了一个文件到暂存区
$ git add ADD.md

// 然后commit 
$ git commit -m "modify ADD.md file"

// 在查询的时候发现 还有一个文件被遗漏
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
       modified:   README.md

//  使用git commit --amend 来重新提交
$ git commit --amend
[master 668a1c8] modify All file and commit file
Date: Wed Apr 26 08:45:45 2023 +0800
2 files changed, 5 insertions(+), 1 deletion(-)

撤销暂存的文件: git restore --staged <file>

js 复制代码
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
       modified:   README.md
           
// 撤销暂存区README的修改
$ git restore --staged README.md 

$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)

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:   README.md

撤销对文件的修改:git restore <file>

js 复制代码
// 查看工作目录文件的状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
   (use "git push" to publish your local commits)

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:   README.md

// 撤销对文件的修改
$ git restore README.md 

// 工作目录已经干净了
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)
    
    nothing to commit, working tree clean

撤销对仓库的文件修改(已经commit):git revert <commitid> / git reset HEAD^

js 复制代码
$ git log -2
commit 297b2a09c4045ee95d53fda11cedead0feaf393b (HEAD -> dev)
Author: Amos <amos@163.com>
Date:   Wed May 10 19:51:35 2023 +0800

   Revert commit message is "add new modify"

   This reverts commit 219de0edd3281fd64e502d5c7869606f9efd667c.

commit 219de0edd3281fd64e502d5c7869606f9efd667c
Author: Amos <amos@163.com>
Date:   Thu Apr 27 16:56:02 2023 +0800

       add new modify

// 根据 commit 回撤记录
$ git revert 297b2a09c4045ee95d53fda11cedead0feaf393b
[dev fbd429d] Revert "Revert commit message is "add new modify"" again
   1 file changed, 1 insertion(+), 1 deletion(-)

// 继续查询提交记录
$ git log -2
commit fbd429d9abc4cbb67b0ce340018eb9a12658dd2b (HEAD -> dev)
Author: Amos <amos@163.com>
Date:   Thu May 11 11:10:39 2023 +0800

   Revert "Revert commit message is "add new modify"" again

   This reverts commit 297b2a09c4045ee95d53fda11cedead0feaf393b.

commit 297b2a09c4045ee95d53fda11cedead0feaf393b
Author: Amos <amos@163.com>
Date:   Wed May 10 19:51:35 2023 +0800

   Revert commit message is "add new modify"

   This reverts commit 219de0edd3281fd64e502d5c7869606f9efd667c.

// git reset HEAD 命令
$ git log -2
commit b9a8ced4762a279f3207ac4672fdb42c2c361f15 (HEAD -> master)
Author: Amos <amos@163.com>
Date:   Thu May 11 11:31:08 2023 +0800

      add second modify

commit a193be1dfd5fc6d1348563c90973e232c46ea3ab
Author: Amos <amos@163.com>
Date:   Thu May 11 11:30:54 2023 +0800

     add first modify


// 此时工作目录已经回退到第一条记录之前了 
$ git reset HEAD^
Unstaged changes after reset:
  M       README.md

//  再次查看一下我们的日志,可以看到什么问题吗? 
$ git log -2
commit a193be1dfd5fc6d1348563c90973e232c46ea3ab (HEAD -> master)
Author: Amos <amos@163.com>
Date:   Thu May 11 11:30:54 2023 +0800

     add first modify

commit 0547a0fe9de6537bb25b6695ed7588dc1195a073
Merge: 705aeda d71cc89
Author: Amos <amos@163.com>
Date:   Thu May 11 08:33:41 2023 +0800

      add a new commit

$ git reset HEAD ^^
$ git reset HEAD ^^^
$ ...
$ git reset HEAD ~ 2
$ ...
$ git reset 582977 da81a7f19d2990830f96200a8cb44f651c
$ ...

远程仓库的使用

远程仓库是指托管在因特网或其他网络中的你的项目的版本库。

词语"远程"未必表示仓库在网络或互联网上的其它位置,而只是表示它在别处。

查看远程仓库:git remote <-v>

js 复制代码
// 查看我本地仓库对应的远程仓库是哪个,默认远程仓库名称是 origin
$ git remote
origin

// 远程仓库详细地址
$ git remote -v
origin  git@gitlab.com:amos/git-teaching-project.git (fetch)
origin  git@gitlab.com:amos/git-teaching-project.git (push)

添加远程仓库:git remote add <shortname> <url>

js 复制代码
// 添加另一个远程仓库 
$ git remote add rr git@gitlab.com:amos/git-teaching-project-remote.git

// 查看远程仓库信息
$ git remote -v
origin  git@gitlab.com:amos/git-teaching-project.git (fetch)
origin  git@gitlab.com:amos/git-teaching-project.git (push)
rr      git@gitlab.com:amos/git-teaching-project-remote.git (fetch)
rr      git@gitlab.com:amos/git-teaching-project-remote.git (push)

从远程仓库中抓取与拉取: git fetch / git pull

js 复制代码
// 从远程库中拉取代码并合并到当前分支  origin -- 远程分支简称  master -- 本地分支名称
$ git pull origin master
From gitlab.com:amos/git-teaching-project
   * branch            master     -> FETCH_HEAD
Already up to date.

推送到远程仓库: git push <remote> <branch>

js 复制代码
// 把我们上面修改的所有的记录推送到远程分支中
$ git push origin master
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Delta compression using up to 8 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (16/16), 1.69 KiB | 864.00 KiB/s, done.
Total 16 (delta 2), reused 0 (delta 0), pack-reused 0
To gitlab.com:amos/git-teaching-project.git
   7142ab5..668a1c8  master -> master

// 执行 git push origin dev 会发生什么??

查看某个远程仓库: git remote show <remote>

远程仓库的重命名与移除: git remote rename <oldName> <newName> / git remote remove <remote>

Git分支

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。有人把 Git 的分支模型称为它的"必杀技特性"

Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。

分支简介

Git 保存的不是文件的变化或者差异,而是一系列不同时刻的 快照

我们假设现在有一个工作目录,里面包含了三个将要被暂存和提交的文件:README test.rb LICENSE

js 复制代码
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'

此时Git 仓库中有五个对象:三个 blob 对象(保存着文件快照)、一个 对象 (记录着目录结构和 blob 对象索引)以及一个 提交 对象(包含着指向前述树对象的指针和所有提交信息)。

做些修改后再次提交,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针。

Git 的分支,其实本质上仅仅是指向提交对象的可变指针 。 Git 的默认分支名字是 master 。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 master 分支会在每次提交时自动向前移动。

创建分支:git branch <branch name>

Git只是为你创建了一个可以移动的新的指针

js 复制代码
// 创建一个testing分支
$ git branch testing

如何知道当前是在哪个分支?HEAD

在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅 创建 一个新分支,并不会自动切换到新分支中去。

分支切换: git checkout <branchname>

arduino 复制代码
// 切换到testing分支
$ git checkout testing

创建并切换分支:git checkout -b <branchname>

合并分支:git merge <branchname>

远程仓库推荐使用gitlab上面的Merge Requests来进行分支之间的合并

合并分支冲突如何解决?

js 复制代码
// 把dev的分支合并到当前分支(master)时代码冲突
$ git merge dev
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
// 查看当前文件状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   README.md

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

这表示 HEAD 所指示的版本(也就是你的 master 分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支)在这个区段的上半部分( ======= 的上半部分),而 dev 分支所指示的版本在 ======= 的下半部分。 为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内容。

js 复制代码
// 修改完后执行git add 命令提交修改到缓存区
$ git add .
// 查看当前文件状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
        modified:   README.md

删除分支:git branch -d <branchname>

Git会检测当前分支是否有修改还未merge,如果有的话会提示删除失败,如果确定要丢弃修改并删除分支的话使用-D参数来删除

js 复制代码
$ git branch -d dev
error: The branch 'dev' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dev'.

贮藏修改和推出修改:git stash / git stash pop

贮藏(stash)会处理工作目录的脏的状态------即跟踪文件的修改与暂存的改动------然后将未完成的修改保存到一个栈上, 而你可以在任何时候重新应用这些改动(甚至在不同的分支上)

js 复制代码
$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)

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:   README.md

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

现在想要切换分支,但是还不想要提交之前的工作;这时可以使用贮藏修改。运行 git stash 命令

js 复制代码
$ git stash
Saved working directory and index state WIP on master: 5ee1887 merge conflicts modify
// 切换分支
$ git checkout dev
Switched to branch 'dev'

// 查看当前修改的贮藏栈的列表
$ git stash list
stash@{0}: WIP on master: 5ee1887 merge conflicts modify

重新应用贮藏的修改:git stash apply <stashid>

js 复制代码
// 不指定stashid 默认是第一条修改记录
$ git stash apply
On branch dev
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:   README.md

删除贮藏的修改记录:git stash drop

js 复制代码
$ git stash list
stash@{0}: WIP on dev: 219de0e add new modify
stash@{1}: WIP on master: 5ee1887 merge conflicts modify

$ git stash drop
Dropped refs/stash@{0} (627e732eee711f65932f9a458c3302f8ea4019fb)

应用贮藏并删除该条记录:git stash pop

分支工作流实践

让我们来思考下下面的一个实际的分支创建和合并的场景:

  1. 小明为了开发一个新需求,创建一个新分支feature-xm, 正在愉快的开发新需求;
  2. 突然有一个线上紧急bug需要修复,此时应该切换到线上分支(master), 创建hotfix紧急分支, 解决完测试上线完成后,合并到线上分支(master)上;
  3. 小明继续切换到工作分支(feature-xm), 继续愉快的撸代码;

想象一下我们最开始分支状态是什么样的?

js 复制代码
$ git checkout -b feature-xm
Switched to a new branch 'feature-xm'

那么此时我们的分支是什么状态的?

小明继续在该分支(feature-xm)上撸代码,并进行了提交

此时,需要修复线上bug, 需要创建一个hotfix分支来进行紧急需求开发

js 复制代码
// 切换到线上分支
$ git checkout master
Switched to branch 'master'
M       README.md
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)
 
  // 基于线上稳定分支创建切换分支到hotfix-0510
 $ git checkout -b hotfix-0510
Switched to a new branch 'hotfix-0510'

小明继续在hotfix-0510上修复了线上bug,并进行了提交

js 复制代码
$ git add .

$ git commit -m "修复线上bug"
[hotfix-0510 705aeda] 修复线上bug
 1 file changed, 5 insertions(+)

修复bug后把hotfix-0510合并到线上分支(master)上

js 复制代码
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)
  
 // 把hotfix-0510合并到master分支上
$ git merge hotfix-0510
Updating 582977d..705aeda
Fast-forward
 README.md | 5 +++++
 1 file changed, 5 insertions(+)

此时,紧急分支hotfix-0510已经不需要了(此时master已经指向了hotfix-0510中最新的提交),可以删除掉,并切换到小明的开发分支(feature-xm)继续开发了

js 复制代码
// 删除分支
$ git branch -d hotfix-0510 
Deleted branch hotfix-0510 (was 705aeda).

// 切换分支
$ git checkout feature-xm
Switched to branch 'feature-xm'

小明继续在feature-xm上面的开发新需求,并进行了提交

此时,小明需求已经开发完成,同样也是需要合并到master分支上

js 复制代码
$ git add .

$ git commit -m "add new page code"
[feature-xm d71cc89] add new page code
 1 file changed, 2 insertions(+)

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)

 // 不出意外的冲突了
$ git merge feature-xm
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

// 使用git status 查看当前工作目录的文件状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)
 // 可以看到我们的REAME.md文件发生了冲突
Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified : README . md

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

如何解决冲突???

修复完了合并完成之后,当前的分支状态变成什么样了?

至此,当前简单的工作流已经结束了,又可以进行下一次的需求开发了。

Git打标签(tag)

Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0v2.0 等等)
它就是指向某个commit的指针

添加标签:git tag <tag> <commitid>

js 复制代码
// 添加一个标签 v1.0
$ git tag v1.0

// 添加一个带说明的标签  -a指定标签名 -m指定说明信息
$ git tag -a v1.1 -m "我是tag v1.1的说明信息"

查看标签:git tag / git show <tagname>

js 复制代码
// 查看标签list 
$ git tag
v1.0
v1.1

// 查看标签信息
$ git show v1.2
tag v1.2
Tagger: Amos 
Date:   Wed Apr 26 10:34:39 2023 +0800

 我是tag v1.2的说明信息
...

删除标签:git tag -d <tagname>

js 复制代码
$ git tag -d v1.1
Deleted tag 'v1.1' (was f14ecfb)

自定义Git

配置命令别名

js 复制代码
$ git config --global alias.co checkout 
$ git config --global alias.br branch 
$ git config --global alias.ci commit 
$ git config --global alias.st status 
相关推荐
web135085886351 分钟前
前端node.js
前端·node.js·vim
m0_512744642 分钟前
极客大挑战2024-web-wp(详细)
android·前端
潜意识起点26 分钟前
精通 CSS 阴影效果:从基础到高级应用
前端·css
奋斗吧程序媛31 分钟前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿40 分钟前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_748256563 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@3 小时前
HTML5适配手机
前端·html·html5
@解忧杂货铺5 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
F-2H6 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
gqkmiss7 小时前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件