Git常用场景下的使用
一. Git 基本知识与安装
以前自己虽然会用 Git,但从来没有系统总结过Git的使用,就借这个机会盘点一下把。
Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。。。。。。这些东西就不说了,百度即可。
Git 主要有以下三个区:
- 工作区:就是你在电脑里能看到的目录。
- 暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
- 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
他们的关系如下:

了解大致关系就行,下面会通过实际演示来掌握Git的使用
安装的话
- Linux 一般都会带 Git, 没有的话 输入sudo apt install git 即可
- Windows 去官网 https://git-scm.com/downloads 下载即可
- Macos 。。贫穷限制了我的。。0.0 其实也是去官网下载
二. 主要场景的使用
1. Git 基本功能的使用
1.1 最简单的流程
这里我们最简单的git使用的一个流程
先在本地建立一个sse文件夹,将该文件夹作为git仓库,然后使用 git init 命令进行初始化。这时候我们用 git status 可以看到仓库是非常干净的。
crazyliu@DESKTOP-TTUBPSH:~$ mkdir sse crazyliu@DESKTOP-TTUBPSH:~$ cd sse crazyliu@DESKTOP-TTUBPSH:~/sse$ ls crazyliu@DESKTOP-TTUBPSH:~/sse$ git init Initialized empty Git repository in /home/crazyliu/sse/.git/ crazyliu@DESKTOP-TTUBPSH:~/sse$ git status On branch master No commits yet nothing to commit (create/copy files and use "git add" to track)
再建立一个read.me文件,并向其中写入first write并保存。这个时候如果再运行git status命令就可看给他提示没有追踪该文件,我们使用 git add命令将其加入暂存区,再次运行 git status,提示暂存区有未提交的change。
crazyliu@DESKTOP-TTUBPSH:~/sse$ touch read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write crazyliu@DESKTOP-TTUBPSH:~/sse$ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) read.me nothing added to commit but untracked files present (use "git add" to track) crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: read.me
最后我们运行 git commit -am "<message>" 即可将暂存区的change进行提交到版本库。再运行 git status 可以看到仓库又变得干净了。运行 git log 可以看到我们刚才的那一次提交的信息。
crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "first commit" [master (root-commit) 663887f] first commit 1 file changed, 1 insertion(+) create mode 100644 read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git status On branch master nothing to commit, working tree clean crazyliu@DESKTOP-TTUBPSH:~/sse$ git log commit 663887ffb57a0feaf2d4f45b0bfa59f932ec2c9e (HEAD -> master) Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:39:57 2020 +0800 first commit
1.2 版本时光穿梭机
Git的一个重要功能就是在版本之间进行穿梭,现在我们来演示一下。在上面的例子中,我们只有一个commit。为了演示,我们按照上面的做法先给read.me文件加一行second write,提交一次。再给read.me 文件加一行 third write, 提交一次。这样我们的read.me文件就有了3行,总共3次提交。
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write second write crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "second commit" [master ff82d97] second commit 1 file changed, 1 insertion(+) crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write second write third write crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "third commit" [master 1186510] third commit 1 file changed, 1 insertion(+) crazyliu@DESKTOP-TTUBPSH:~/sse$ git log commit 118651050aabde2a59e60100580dc9cf2cbc89a2 (HEAD -> master) Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:52:30 2020 +0800 third commit commit ff82d978175d1b240153901d36ae3bfc6cb544e7 Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:51:42 2020 +0800 second commit commit 663887ffb57a0feaf2d4f45b0bfa59f932ec2c9e Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:39:57 2020 +0800 first commit
现在我们是在第三次提交也就是third commit 这里,如果我们要回到第一次提交first commit 那里,要怎么操作呢?可以使用这条命令 git reset --hard HEAD^^,其中HEAD指向当前所在的版本,后面加一个^就是前面的一个版本,加两个^^就是往前走两个版本,如果向前走100个版本,则可以用HEAD~100。这时、用 git log 查看日志可以发现的确回到了过去。
crazyliu@DESKTOP-TTUBPSH:~/sse$ git reset --hard HEAD^^ HEAD is now at 663887f first commit crazyliu@DESKTOP-TTUBPSH:~/sse$ git log commit 663887ffb57a0feaf2d4f45b0bfa59f932ec2c9e (HEAD -> master) Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:39:57 2020 +0800 first commit
那我们要回到刚才 third commit 要怎么办呢?同样是上面的那条命令,只是将 --hard 后面的换成 要去的commit 的id的前几位。要知道这个id可以使用 git reflog 查看穿梭的日志,在其中可以找到third commit 的id前几位为1186510。再次运行 git log 可以看到我们又回到了现在
crazyliu@DESKTOP-TTUBPSH:~/sse$ git reset --hard HEAD^^ HEAD is now at 663887f first commit crazyliu@DESKTOP-TTUBPSH:~/sse$ git log commit 663887ffb57a0feaf2d4f45b0bfa59f932ec2c9e (HEAD -> master) Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:39:57 2020 +0800 first commit crazyliu@DESKTOP-TTUBPSH:~/sse$ git reflog 663887f (HEAD -> master) HEAD@{0}: reset: moving to HEAD^^ 1186510 HEAD@{1}: commit: third commit ff82d97 HEAD@{2}: commit: second commit 663887f (HEAD -> master) HEAD@{3}: commit (initial): first commit crazyliu@DESKTOP-TTUBPSH:~/sse$ git reset --hard 1186510 HEAD is now at 1186510 third commit crazyliu@DESKTOP-TTUBPSH:~/sse$ git log commit 118651050aabde2a59e60100580dc9cf2cbc89a2 (HEAD -> master) Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:52:30 2020 +0800 third commit commit ff82d978175d1b240153901d36ae3bfc6cb544e7 Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:51:42 2020 +0800 second commit commit 663887ffb57a0feaf2d4f45b0bfa59f932ec2c9e Author: crazyliu <xxxxxxxxx@qq.com> Date: Sun Oct 11 14:39:57 2020 +0800 first commit
1.3 文件的回退
上面我们介绍了在版本之间回退与前进,这个部分我们介绍另一个有用的技巧。有时候我们把文件改的乱七八糟,或者把一些不该提交的东西 add进了暂存区,这时候我们就要用到文件的回退。
比如我们把read.me改的一无是处,但是还没有add进暂存取,然后想回到commit完的样子,但又忘记是啥样了或者很麻烦,就可以使用 git checkout -- <filename>, <filename>是要回退的文件名,注意中间有 - 并且是 --。如回退所有地文件,则用git checkout ., 小心使用,会丢失本地所有修改。运行完上面地命令可以看到成功回退了,又可以愉快地玩耍了。
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write second write third write my boss is a stupid fool my boss is a stupid fool my boss is a stupid fool my boss is a stupid fool my boss is a stupid fool crazyliu@DESKTOP-TTUBPSH:~/sse$ git checkout -- read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write second write third write
2. 与远程版本库一起工作
上面介绍了在本地版本库使用的一些git命令,这个部分我们将演示如何连接到远程版本库并一起工作。
2.1 连接到远程仓库
2.1.1本地代码推送到新仓库
上面我们的演示都是在本地的sse仓库进行,这部分演示如何将其推送到github的新仓库上。
我们先在github上建立一个 sse_test 的空仓库,如下所示

然后使用 git remote add origin <远程仓库地址> 将远程仓库地址添加进来,<远程仓库地址> 填入你的远程仓库地址。再使用 git push -u origin master 即可将本地代码推送到远程代码库的master分支上。
如 遇到 Permission Denied, 可以参考 https://blog.csdn.net/gdutxiaoxu/article/details/53573399 添加公钥,以后访问也便捷。
crazyliu@DESKTOP-TTUBPSH:~/sse$ git push -u origin master The authenticity of host 'github.com (13.250.177.223)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'github.com,13.250.177.223' (RSA) to the list of known hosts. Counting objects: 9, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (9/9), 668 bytes | 222.00 KiB/s, done. Total 9 (delta 0), reused 0 (delta 0) To github.com:csflyer/sse_test.git * [new branch] master -> master Branch 'master' set up to track remote branch 'master' from 'origin'.
2.1.2 远程仓库代码拷贝到本地
在一个文件夹下使用 git clone <远程仓库地址> 即可将远程仓库代码拷贝到本地,<远程仓库地址> 填入你的远程仓库地址, 这一过程会在本地新建一个仓库用于存放远程仓库代码
crazyliu@DESKTOP-TTUBPSH:~$ git clone git@github.com:csflyer/sse_test.git Cloning into 'sse_test'... remote: Enumerating objects: 9, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (3/3), done. remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0 Receiving objects: 100% (9/9), done.
2.1.3 本地代码推送到远程仓库
在 2.1.1中介绍了本地代码推送到远程新仓库,这里介绍如何将本地代码推送到不是新建的远程仓库。
在一般情况下我们使用 git push origin master 命令即可,master 为要推送的分支名,分支可以查看下一小节。这里我们对read.me添加一行fourth write并提交,再使用git push origin master 进行推送即可,如下所示
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write second write third write fourth write crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "fourth commit" [master 8a40181] fourth commit 1 file changed, 1 insertion(+) crazyliu@DESKTOP-TTUBPSH:~/sse$ git push origin master Counting objects: 3, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 267 bytes | 267.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:csflyer/sse_test.git 1186510..8a40181 master -> master
注意当远程代码库与本地库不一致时,上面的动作会失败,解决办法请参考2.4.1节
2.3. 多人协作
上面的1,2小节介绍了单人开发的一个流程,在多人协作开发的情况下,会出现新的问题和情况,这就需要我们改变现有的流程
2.3.1 代码拉取与合并
在多人协作的开发模式下,远程代码库容易与本地库不一致,这个时候需要进行代码拉取与合并,代码拉取就是将最新的远程代码库弄到本地仓库上
为了演示,我们在github上的仓库上修改read.me 为每一句话后加一个分号并提交

然后我们在本地仓库上编辑read.me 并添加第五行 fifth write 并提交。这个时候本地仓库和远程代码是不一致的,如果我们用 git push origin master 推送会失败
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "fifth commit" [master 6c815a0] fifth commit 1 file changed, 1 insertion(+) crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write second write third write fourth write fifth write; crazyliu@DESKTOP-TTUBPSH:~/sse$ git push origin master Warning: Permanently added the RSA host key for IP address '192.30.255.113' to the list of known hosts. To github.com:csflyer/sse_test.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:csflyer/sse_test.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
这时我们要用 git fetch 拉取远程仓库的代码,再运行git merge 将本地的代码和刚拉取下来的代码合并。为了方便使用,git 有一条命令 git pull,相当于把这两条命令结合起来,这里我们直接运行
razyliu@DESKTOP-TTUBPSH:~/sse$ git pull remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:csflyer/sse_test 8a40181..9a150f4 master -> origin/master Auto-merging read.me CONFLICT (content): Merge conflict in read.me Automatic merge failed; fix conflicts and then commit the result.
可以看到这里直接提示我们 合并的过程中有冲突,需要修改再合并。这里我们运行 git diff 就能看到发生冲突的地方,手动修改完,再commit提交。这个时候运行 git push origin master 就不会报错了
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write; second write; third write; fourth write; fifth write; crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "first merge" [master 24d128f] first merge crazyliu@DESKTOP-TTUBPSH:~/sse$ git push origin master Counting objects: 6, done. Delta compression using up to 8 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 543 bytes | 271.00 KiB/s, done. Total 6 (delta 0), reused 0 (delta 0) To github.com:csflyer/sse_test.git 9a150f4..24d128f master -> master
所以在每次向远程代码库推送的时候都应该先git pull, 合并完所有冲突再提交。
2.3.2 代码分支
分支顾名思义就是指代码仓库有不同的发展分支或方向。在上面的演示中,我们只用到了一个分支 master,那么我们为什么需要多个分支呢,或者多个分支能解决什么问题呢?
比如,一个软件产品往往会发布多个版本,如正式版,beta版,测试版。不同的人在开发中会分配到不同的任务,有的人负责开发新功能,有的人负责解决bug,多项任务同时推进。那么所有人都向一个分支提交代码,
就会使得多项工作之间的关系错综复杂,代码容易出错,需要更多的经历去维护代码的一致性。而分支的出现就能很好解决这个问题,每人每项任务可以单独在一个分支进行,彼此之间完全不受影响,任务完成时再合并到master分支即可,非常方便
分支常用的命令如下:
- 创建分支 git branch <branch name>, 其中 <branch name> 为分支的名字
- 查看所有分支 git branch,显示结果中前面带 * 的为当前所在分支
- 切换分支 git checkout <branch name>, 其中 <branch name> 为分支的名字
- 分支合并 git merge <branch name>, 其中 <branch name> 为分支的名字
- 分支删除 git branch -d <branch name>, 其中 <branch name> 为分支的名字
2.3.2.1 基本流程
分支管理的基本流程就是新创建一个分支,开发完之后再合并到其他分支上。
为了演示,我们假定我们的仓库总共需要两个分支,原来的master分支为主分支,新建一个dev分支用来进行开发,开发完再合并到master分支上。
首先我们用 git branch dev 创建 dev 分支,使用 git branch 可以看到创建成功了,且当前处在master分支
crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch dev crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch dev * master
然后我们进行开发,给read.me文件加一行 write on new branch dev; 并提交
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write; second write; third write; fourth write; fifth write; write on new branch dev; crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "commit on new branch dev" [master 5faed18] commit on new branch dev 1 file changed, 1 insertion(+)
最后我们进行代码合并,先使用 git checkout master 切换到要合并到的分支master上,再使用 git merge dev 合并 dev分支。
crazyliu@DESKTOP-TTUBPSH:~/sse$ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) crazyliu@DESKTOP-TTUBPSH:~/sse$ git merge dev Already up to date.
合并完后 我们可以用 git log --graph 查看合并的log图,因为这里dev分支只是领先一个commit,所以git 直接将HEAD移到了dev分支的最后一个节点,没有出现分叉。最后使用 git branch -d dev删除分支,一次基本的分支合并就完成了
crazyliu@DESKTOP-TTUBPSH:~/sse$ git log --graph * commit 5faed18d5caff886a6286d9698a2ab7c3407efa5 (HEAD -> master) | Author: crazyliu <xxxxxxxxxx@qq.com> | Date: Mon Oct 12 09:50:34 2020 +0800 | | commit on new branch dev | * commit 24d128ff6f4a58624267dee77dac520a192b3992 (origin/master, dev) |\ Merge: 6c815a0 9a150f4 | | Author: crazyliu <xxxxxxxxx@qq.com> | | Date: Sun Oct 11 19:08:13 2020 +0800 | | | | first merge | | | * commit 9a150f4b6d0bac63f7afdae8135ba1e03f08bce6 | | Author: csflyer <xxxxxxxxxx@qq.com> | | Date: Sun Oct 11 18:56:54 2020 +0800 | | | | Update read.me | | * | commit 6c815a0a5758e4fc9892877be35b64cd435dcd7e |/ Author: crazyliu <xxxxxxxxx@qq.com> | Date: Sun Oct 11 18:59:26 2020 +0800 | | fifth commit | * commit 8a40181344b5f959272693263ee1c96220df395f | Author: crazyliu <xxxxxxxxx@qq.com> | Date: Sun Oct 11 17:00:26 2020 +0800 | | fourth commit | * commit 118651050aabde2a59e60100580dc9cf2cbc89a2 | Author: crazyliu <xxxxxxxxx@qq.com> | Date: Sun Oct 11 14:52:30 2020 +0800 | | third commit | * commit ff82d978175d1b240153901d36ae3bfc6cb544e7 | Author: crazyliu <xxxxxxxxx@qq.com> | Date: Sun Oct 11 14:51:42 2020 +0800 | | second commit | * commit 663887ffb57a0feaf2d4f45b0bfa59f932ec2c9e Author: crazyliu <xxxxxxxxxxx@qq.com> Date: Sun Oct 11 14:39:57 2020 +0800 crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch -d dev Deleted branch dev (was 24d128f). crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch * master
2.3.2.2 Git Stash 介绍
上面介绍了在分支进行开发的基本流程。这个部分介绍一个有用的命令 Git Stash,它可以保护我们的现场工作。
为了演示,我们先新建一个 dev 分支,并在 master 分支上修改read.me 添加一行 write on branch master; 但是不 add 也不 commit。
这时我们checkout 到dev 分支查看read.me文件,可以看到read.me也多了这一行。
crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch dev crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch dev * master crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write; second write; third write; fourth write; fifth write; write on new branch dev; write on branch master; crazyliu@DESKTOP-TTUBPSH:~/sse$ git checkout dev M read.me Switched to branch 'dev' crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write; second write; third write; fourth write; fifth write; write on new branch dev; write on branch master;
这说明在本地一个编辑会影响另一个分支,add也是一样。那么当我们在一个分支的工作还没做完,还不能commit 的情况下,需要紧急处理一个bug或者别的任务,需要再开一个新的分支来解决,
那么现在手头上的改动就需要先放到某个地方保存起来,等弄完了再恢复现场。而这就是git stash的功能。
为了演示,我们这里先checkout 到master分支,再 git branch -d dev 删掉刚才的分支,并用 git reset --hard HEAD 回退,清理环境。
开始演示,首先我们给read.me添加一行 unfinished job; 表示 还未完成的工作,但不 add 也不 commit 。这个时候接到一个紧急任务,有个bug需要紧急处理。
我们可以用git stash 保存我们目前的环境,运行完命令后可以看到我们的环境非常干净,再去创建分支就不会影响到新分支。Good Job!
crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write; second write; third write; fourth write; fifth write; write on new branch dev; unfinished job; crazyliu@DESKTOP-TTUBPSH:~/sse$ 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 checkout -- <file>..." to discard changes in working directory) modified: read.me no changes added to commit (use "git add" and/or "git commit -a") crazyliu@DESKTOP-TTUBPSH:~/sse$ git stash Saved working directory and index state WIP on master: 5faed18 commit on new branch dev crazyliu@DESKTOP-TTUBPSH:~/sse$ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean
这时候我们创建新分支 solve-bug 并chekcout 到该分支。再给read.me添加一行 bug has been solved 表示我们解决了这个bug,并commit。最后切换到master分支,合并刚才的solve-bug分支,再删除solve-bug分支即可。
crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch solve-bug crazyliu@DESKTOP-TTUBPSH:~/sse$ git checkout solve-bug Switched to branch 'solve-bug' crazyliu@DESKTOP-TTUBPSH:~/sse$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ cat read.me first write; second write; third write; fourth write; fifth write; write on new branch dev; bug has been solved; crazyliu@DESKTOP-TTUBPSH:~/sse$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/sse$ git commit -am "solve bug" [solve-bug 905e0a1] solve bug 1 file changed, 1 insertion(+) crazyliu@DESKTOP-TTUBPSH:~/sse$ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) crazyliu@DESKTOP-TTUBPSH:~/sse$ git merge solve-bug Updating 5faed18..905e0a1 Fast-forward read.me | 1 + 1 file changed, 1 insertion(+) crazyliu@DESKTOP-TTUBPSH:~/sse$ git branch -d solve-bug Deleted branch solve-bug (was 905e0a1).
这样的一个bug处理就完成了,最后使用 git stash pop 就可以恢复修改bug之前工作区的内容啦。注意这里恢复会产生冲突,所以还要按之前的办法将冲突的地方解决好,但暂时可以不commit。
2.4 Github Fork + Pull Request
这部分我们还是以之前的sse_test 仓库为例,用小号fork该仓库,分别对应下面的左图和右图

我们在小号的仓库上修改 read.me文件 添加一行 pull reqeust; 并提交

到原仓库可以看到小号发起的pull reqeust请求,直接进行合并即可。

这样一个 pull request 流程就完成了,还是挺简单的

2.5 其他
上面介绍了 git使用的常用流程与命令,下面介绍其他有用的工具与命令
2.5.1 标签
标签就是给一个commit 取一个名字,让它更直观更简洁。相关命令如下:
- 创建标签: git tag < tag name> 对当前分支的最新commit打标签 git tag <tag name> <commit id 前几位> 对当前分支的某个 commit 打标签
- 查看所有标签: git tag
- 查看标签信息: git show <tag name>
- 删除标签: git tag -d <tag name>
因为我们上一个commit 是解决bug的,所以这里演示我们添加一个标签solve-tag。使用 git show solve-tag可以看到标签相关的信息,包括作者,时间,备注,修改内容等等
crazyliu@DESKTOP-TTUBPSH:~/sse$ git tag solve-bug crazyliu@DESKTOP-TTUBPSH:~/sse$ git tag solve-bug crazyliu@DESKTOP-TTUBPSH:~/sse$ git show solve-bug commit 905e0a1cb011972638a9d65a31a2bb8e8d2803d7 (HEAD -> master, tag: solve-bug) Author: crazyliu <924105150@qq.com> Date: Mon Oct 12 15:11:28 2020 +0800 solve bug diff --git a/read.me b/read.me index 6840e70..1fb465d 100644 --- a/read.me +++ b/read.me @@ -4,3 +4,4 @@ third write; fourth write; fifth write; write on new branch dev; +bug has been solved;
2.5.2 git cherry-pick
git cherry-pick是一个不那么常用的命令,但有时候很有用,这里简单介绍下。
在2.3.2.2小节中,我们是直接切换到某个分支修改bug再merge。但如果存在很多分支,同时存在该bug急需解决,又不能合并,我们就不得不一个分支一个分支地改,很浪费时间。
git cherry-pick 可以使得只需在其他分支改好,就能将改动的部分应用到本分支,可以节省很多时间。具体命令为 git cherry-pick <commit id 前几位>,这里就不具体演示了
2.5.3 git rebase
多次创建新分支,合并后,log会变得非常乱。类似下图。而git rebase就是帮助我们简化log历史的命令,最简单理解就是美化log的,虽然它和merge命令一样是一种合并的方式.用法就是 git rebase <branch name>, <branch name>
是分支名,以该分支为基础进行合并。

以下图为例,C0是最刚开始的状态,C1是修改C0后的提交,以此类推,C4和C3是两个分支,在C5处合并。

使用rebase 就可以将这个log变成一条直线 ,见下图。它删掉了C4节点,将C4的改动部分应用到C3,形成新的节点C4’,上面的C5也不需要了,从而将log历史拉成了一条直线,少了一个节点,变简洁了,也变好看了 0.0,。

为了演示我们新建一个feature分支,在feature分支的read.me 文件添加一行 feature_content 并提交,在master分支的read.me文件添加一行 master_content 并提交,checkout 到feature分支后, 输入git rebase master会提示冲突,如下
crazyliu@DESKTOP-TTUBPSH:~/test$ git rebase master First, rewinding head to replay your work on top of it... Applying: add feature content Using index info to reconstruct a base tree... M read.me Falling back to patching base and 3-way merge... Auto-merging read.me CONFLICT (content): Merge conflict in read.me error: Failed to merge in the changes. Patch failed at 0001 add feature content Use 'git am --show-current-patch' to see the failed patch Resolve all conflicts manually, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort".
所以我们要先解决冲突,解决冲突后将冲突文件git add一下,再输入 git rebase continue 继续变基即可完成。
crazyliu@DESKTOP-TTUBPSH:~/test$ vim read.me crazyliu@DESKTOP-TTUBPSH:~/test$ git add read.me crazyliu@DESKTOP-TTUBPSH:~/test$ git rebase --continue Applying: add feature content crazyliu@DESKTOP-TTUBPSH:~/test$ git log --graph * commit 37c38612c712db1d6383d1563e7956eec5d19ef4 (HEAD -> feature) | Author: crazyliu <xxxxxxxxxx@qq.com> | Date: Mon Oct 12 20:31:57 2020 +0800 | | add feature content | * commit 4497702dc92d7af5592606977c106a41c51428e9 (master) | Author: crazyliu <xxxxxxxxx@qq.com> | Date: Mon Oct 12 20:32:29 2020 +0800 | | add master content | * commit 2872564d9f18c395ceb2c6f7f4bbc22845da86c7 Author: crazyliu <xxxxxxxxx@qq.com> Date: Mon Oct 12 20:30:51 2020 +0800 init
从上面可以看出来是一条直线,而如果用merge则会出现分叉。
三. 总结
Git其实没有那么难,但命令还是有点多,不可能都记住,最后送大家一张图来总结上面常用的命令吧,也可以设成桌面壁纸哟,撒花,完结啦

参考文献:
1.https://mp.weixin.qq.com/s/Km5KuXPETvG0wCGHrvj9Vg ,孟宁
浙公网安备 33010602011771号