Toggle navigation
首页
产品中心
全新RDIF.vNext低代码框架
镇店
.NET C/S开发框架
.NET Web敏捷开发框架
.NET 快速开发框架(全新EasyUI版本)
.NET 代码生成器
.NET WebAPI服务端开发框架
客户案例
付款方式
国思学堂
技术文章
新闻资讯
下载
关于
首页
技术文章
挨踢业界
正文
原创
2023-04-25
浏览 (
6847
)
干货|工作中要使用Git,看这篇文章就够了
本文将从 Git 入门到进阶、由浅入深,从常用命令、分支管理、提交规范、vim 基本操作、进阶命令、冲突预防、冲突处理等多方面展开,足以轻松应对工作中遇到的各种疑难杂症,如果觉得有所帮助,还望看官高抬贵手给个赞呗,感谢! 虽说现在工作中使用 Git 都会用一些图形化管理工具来提高开发效率。可事实上使用图形管理化工具的前提,也是基于对命令都基本了解。还有比如我平时用的工具 `Github Desktop` 因为不带第三方合并工具,只能手动解决冲突,而且有的功能没有,只能配合自己手动敲命令。 即使是工具也没有那么完美的工具,掌握命令才是`渔`,工具只是`鱼`。其他的 Git 可视化管理工具比如:小乌龟、SourceTree、还有我们开发用的 IDE 集成的,本篇不过多介绍。 ## 基本概念 Git 是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。 ![Git](http://doc.rdiframework.net/rdiblog/20230424161308.png) Git 的作用与好处是: 可以帮我们保存文件的所有修改记录,并且使用版本号进行区分,让我们随时可以浏览历史版本、对比不同版本的差异、还原到指定版本,起到恢复和保护作用的同时,还能和其他人同时修改,然后通过 Git 来合并修改的部分文件,超级方便。主要有以下特点: - 分支更快、更容易。 - 支持离线工作;本地提交可以稍后提交到服务器上。 - Git 提交都是原子的,且是整个项目范围的,而不像 CVS 中一样是对每个文件的。 - Git 中的每个工作树都包含一个具有完整项目历史的仓库。 - 没有哪一个 Git 仓库会天生比其他仓库更重要。 ![GIT](http://doc.rdiframework.net/rdiblog/20230424161313.png) 不熟的同学别和 Github 搞混了,Git 是工具,Github 是平台,没有什么必然的联系,就像 Java 和 JavaScript 也没有什么必然联系一样 Github 是一个主流的代码托管平台。可以理解为存放和管理代码的网盘,可以把自己的代码传上去进行共享和维护。 ![使用GIT的9个理由](http://doc.rdiframework.net/rdiblog/20230424161317.png) ## 安装配置 安装地址:[Git - Downloads (git-scm.com)](https://git-scm.com/) 安装好后,命令行窗口是使用 `Git Bash`、`CMD`、`Powershell`、`终端`、或者编译器内置的都行,这个就看个人喜好。 接着可以再配置下默认用户名和邮箱,比如配置全局的就用如下两条命令,替换成自己的用户名和邮箱,以后所有的项目都会默认这里配置的用户信息 ```sh git config --global user.name 'xxxx' git config --global user.email 'xxxx@xx.com' ``` 如果只需要在某个特定的项目中用其他的名字和邮箱,不用全局的,就把上面命令中的 `--global` 去掉在项目下执行即可,或者不执行命令,直接在项目下的 `.git/config` 文件里添加如下,也可以 ```sh # xxx 指的是填你自己的用户名和邮箱,不是真的写 xxxx 上去 [user] name = xxxx email = xxxx@xx.com ``` ## 基本操作 先了解一下几个基本概念: - 工作区:开发的地方,开发过程就是对工作区的操作 - 暂存区:执行 `git add xxx` 命令后,会把当前**修改过的文件**添加到暂存区 - 本地仓库:执行 `git commit` 命令完成后,会把当前暂存区的文件放入本地仓库 - 远程仓库:就是用来托管代码的服务器(如:Github、Gitee、GitLab、工蜂、Bitbucket..),执行 `git push` 命令后,会把本地仓库的文件提交到远程仓库 ### 常见选项 再认识一下几个后面会用到多次的命令。 | 命令 | 缩写 | 意思 | | ---------------- | ---- | ---------------- | | --all | -a | 全部 | | --force | -f | 强制 | | --delete | -d | 删除 | | --delete --force | -D | 强制删除 | | --move | -m | 移动或重命名 | | --move --force | -M | 强制移动或重命名 | | -u | | 设置默认远程分支 | ### 基本用法 ![基本用法](http://doc.rdiframework.net/rdiblog/20230424161323.png) 上面的四条命令在工作目录、暂存目录(也叫做索引)和仓库之间复制文件。 - `git add *files*` 把当前文件放入暂存区域。 - `git commit` 给暂存区域生成快照并提交。 - `git reset -- *files*` 用来撤销最后一次`git add *files*`,你也可以用`git reset` 撤销所有暂存区域文件。 - `git checkout -- *files*` 把文件从暂存区域复制到工作目录,用来丢弃本地修改。 你可以用 `git reset -p`, `git checkout -p`, or `git add -p`进入交互模式。 也可以跳过暂存区域直接从仓库取出文件或者直接提交代码。 ![直接提交代码](http://doc.rdiframework.net/rdiblog/20230424161329.png) - `git commit -a `相当于运行 `git add` 把所有当前目录下的文件加入暂存区域再运行。`git commit`. - `git commit files` 进行一次包含最后一次提交加上工作目录中文件快照的提交。并且文件被添加到暂存区域。 - `git checkout HEAD -- files` 回滚到复制最后一次提交。 ### 拉取远程项目 拉取远程项目到本地,先复制远程项目链接,再在本地执行如下命令 ```sh # 拉项目 git clone https://xxxx # 拉项目的同时自动初始化并更新项目中的每一个子模块 git clone --recursive https://xxxx ``` ### 上传本地项目 本地新建的项目,还没有提交到远程仓库,就需要先关联远程仓库。先在远程创建一个空项目,并复制该项目的链接,然后在本地项目根目录依次执行下面命令即可 ```js git init // 初始化本地 Git 仓库,会生成一个 .git 隐藏文件夹 git remote add origin https://xxxx // 将本地项目关联远程仓库,后面的 https://xxxx 就是复制的远程仓库的链接 git pull --rebase origin master // 上传之前更新一下,确保没有冲突,master 为分支名称,--rebase 后面有介绍 git add . // 添加目录下所有发生改变的文件 git commit -m 'xxx' // 添加注释信息 git push -u origin master // 提交到 master 分支 ``` 其中 `git remote add origin https://xxxx`,就是往 `.git/config` 文件里添加下面这一段,手动添加也可以,意思就是与远程仓库建立关联。其他的几条命令后面有介绍,我们先认识下 `origin` 为后面做铺垫; ```sh [remote "origin"] url = https://github.com/rdif/xxxx.git fetch = +refs/heads/*:refs/remotes/origin/* ``` 命令里的 `origin` 类似变量命名,这是默认的而已,没什么特别的意思,可以随便写,假如改成 `abc`,后面的 `git push origin xxx` 改成 `git push abc xxx` 即可,方便区分远程仓库的 由此可得出一个结论,就是一个项目可以关联多个远程仓库,命不同的名就行了 没错 `git remote -v` 可以快速查看当前已经关联的远程仓库列表 ### 关联多个远程仓库 可以使用 `git remote add xxx` 添加多个,或者直接动在 `.git/config` 文件里添加。 比如一个项目同时关联一个 `Github` 仓库和一个 `Gitee` 仓库,添加一个 `remote` 就是了,比如如下: ```sh [remote "github"] url = https://github.com/rdif/xxxx.git fetch = +refs/heads/*:refs/remotes/github/* [remote "gitee"] url = https://gitee.com/xxxx/xxxx.git fetch = +refs/heads/*:refs/remotes/gitee/* [remote "all"] url = https://github.com/rdif/xxxx.git url = https://gitee.com/xxxx/xxxx.git fetch = +refs/heads/*:refs/remotes/all/* ``` 这样当我们提交代码的时候,想提交到 `Github` 就用 `git push github master`,想同时提交到 `Github` 和 `Gitee` 的仓库,只需要 `git push all master` 即可 以命令的方法在某个 `remote` 下添加 `url` 如下,比如在上面 `remote github` 下再添加一个 `url`: ```sh git remote set-url --add github https:/xxxx.git ``` ### 常用命令 add/commit/fetch/merge/pull/push **git add** ```sh # 添加一个文件 test.js 到暂存区,多个文件以空格隔开 git add test.js # 添加全部文件到暂存区 git add . ``` **git commit** ```sh # 会打开 vim 编辑器,vim 编辑器操作在下面展开说明 git commit # 提交暂存区的文件到本地仓库,并备注当前 commit 记录 git commit -m '备注信息' # 相当于 git add . 加上 git commit -m 'xxxx' git commit -am 'xxxx' # 用本地提交替换上次提交,比如不想保留上一次提交或者上一次提交描述信息写错了之类的 git commit --amend ``` **git fetch** ```sh # 获取 remote origin 对应远程仓库指定 master 分支的变更,但是不和本地的合并 git fetch origin master # 意思一个样,拉默认的分支而已 git fetch origin # 也是,等效于 git fetch origin master:master,就是分支配置的默认值 git fetch # 获取默认远程仓库所有分支的变更 git fetch -a ``` **git merge** ```sh # 把本地的 test 分支分并到我当前分支 git merge test # 合并 remote origin 对应远程仓库的 master 分支到当前分支 git merge origin/master # --on-ff 是 no-fast-forward简写,合并并且会在分支上重新生成一个新的 commit 节点 git merge --on-ff origin/master # 加入 --squash 表示合并,但是不生成 commit 记录,通常用于把本地分支合入远程分支 git merge test --squash # 取消合并 git merge --abort ``` **git pull** `pull` 和 `fetch` 都是下载远程分支,区别是 `pull` 会和当前分支合并,`fetch` 不会 ```sh # 拉取 remote origin 对应的远程仓库的 master 分支合并到本地的 test 分支 git pull origin master:test # 这种同理就不解释了 git pull origin # git pull --merge 的简写,默认是 --merge 模式 # 等于 git fetch 加上 git merge,拉远程默认分支到当前分支 git pull # 把合并模式切换成 rebase,等于 git fetch 加上 git rebase,rebase 后面进阶有介绍 git pull --rebase origin master ``` **git push** ```sh # 推送本地 test 分支到 remote origin 对应的远程仓库的 master 分支 git push origin test:master # 上面同理,推送到远程默认分支 git push origin test # 缩写,同理,用默认分支 git push origin git push # 相当于 git push origin master 加上 git branch --set-upstream master origin/master # 推送并设置默认远程分支 git push -u origin master # 强制推送,就算本地和远程有差异也推上去 git push -f origin master # 删除远程主机的 master 分支 git push origin -d master ``` ### vim 基本操作 一点点小插曲 比如 `git commit` 就会打开一个 `vim` 的终端编辑器,让我们写提交说明,新手很容易在这个编辑器上面踩坑,不知道怎么输入,不知道怎么退出,最后只能关闭终端窗口,这也没办法,`vim` 的操作确实有些反人类。 `vim` 打开默认是不能输入的,要按 `a` 或者 `i` 进入编辑模式,输入完成后,再按 `Esc` 退出编辑模式,这时左下角会有输入框,输入如下**英文字符**,注意冒号别打成中文字符,回车即可退出 `vim` 回到终端: - `:w`:保存 - `:q`:退出 - `:wq`:保存并退出 - `!`:强制的意思,不能保存时 `:w!` 强制保存,不能退出时 `:q!` 或 `:wq!` 强制退出 我们继续 git ### 分支管理 branch/switch/checkout 一个人玩,可能分支的作用没那么大,但是团队协作,离不开分支管理。 比如本文开头图片那样一个版本一个分支多方便,是吧 或者现有一个新需求一个页面分为多个模块,分配给多个人负责,每人做一个模块,最后合并成一个完整的页面,如果都在同一个分支上开发,各种逻辑相互穿插,那冲突真的是人都要搞麻了,如果每个人都新建一个分支,开发自己负责的那个功能,最后再合并到同一个分支上去就非常方便了 然后因为多人协作肯定不是在一台电脑上,所以就需要一个服务器,来搭建一个 Git 仓库服务,或者用公共的云服务器仓库存储,常见的代码托管平台有比如:`Github`、`码云(Gitee)`、`腾讯工蜂`、`GitLab`、`Bitbucket`...,关于这个本篇文章不过多展开。 **创建分支** ```sh # 创建本地分支 test,但不切换 git branch test # 创建 test 分支,并切换到 test 分支 git branch -M test # 创建 test 分支,并切换到 test 分支 git checkout -b test # 创建 test 分支,并切换到 test 分支 git switch -c test # 创建本地与远程对应的 test 分支,并切换到 test 分支,全称最好一致 git checkout -b test origin/test ``` **查看分支** ```sh # 查看所有本地分支 git branch # 查看所有远程分支 git branch -r # 查看本地和远程所有分支 git branch -a ``` **切换分支** `checkout` 和 `switch` 的共同点是都能切换分支,不同点是: - `switch` 语义上好点 - `switch` 仅仅用于切换和创建并切换,`checkout` 还能用来还原工作区,后面进阶那有介绍 ```sh # 切换到 test 分支 git checkout test # 新建 test 分支,并切换到 test 分支 git checkout -b test # 切换到 test 分支 git switch test # 新建 test 分支,并切换到 test 分支 git switch -c test ``` **删除分支** ```sh # 删除本地 test 分支 git branch -d test # 删除远程主机的 master 分支 git push origin -d master ``` **删除分支后恢复** ```sh # 查看记录,找到对应的 hash git reflog # 创建test分支,并取对应hash分支所有内容,相当于恢复了被删除的分支 git checkout -b test hash ``` **重命名分支** ```sh # 把本地的 master 分支重命名为 test git branch -m master test # 远程分支没法直接重命名,只能删了重建,主要分几步 # 1. git push origin --delete test 删除远程分支 # 2. git push origin newtest 上传新的远程分支 # 3. 把修改后的本地分支关联远程分支 git branch --set-upstream-to origin/newtest ``` **合并分支** 其实就是上面的 `git merge`。比如要把 `test` 分支合并到 `master` 分支,就: ```sh # 先切换到 master 分支 git checkout master # 拉一下,看有没有更新 git pull # 把 test 分支合进来 git merge test # 查看状态,看有没有冲突的,有就打开 IDE 解决一下 git status # 然后 add、commit、push 几个命令来一轮就 ok 了 ``` ### git commit 提交规范 `git commit` 提交规范指的就是 `git commit -am 'xxxx'` 里的 `xxxx` 的书写规范,比如我在工作中开发了一个新功能提交的时候一般这么写: - `git commit -am 'feat: 添加扫码登录` - `git commit -am 'feat(mobile):添加扫码登录`,或者加个范围说明是添加哪方面的功能 `feat` 就是添加新功能的时候用,更多说明如下: - `feat`:添加新功能 - `fix`:修复问题/BUG - `style`:注意不是指CSS,而是修改了如空格、缩进、逗号等代码风格相关,且不影响运行结果的 - `perf`:优化相关的,比如功能优化、性能提升、提升体验等 - `refactor`:代码重构,没有加新功能或者修复 bug - `revert`:撤消编辑,回滚到上一个版本、撤销上一次的 commit 之类的 - `test`:测试相关,比如单元测试、集成测试等 - `docs`:修改文档/注释,比如 README、CHANGELOG、CONTRIBUTE 等 - `chore`:依赖更新/脚手架配置修改等,比如有改变构建流程、或者增加依赖库、工具之类的 - `workflow`:工作流程改进 - `ci`:持续集成 - `types`:类型定义文件更改 到这里,基础部分内容就结束了 问个问题:`git branch -M ac` 是啥意思?不许翻上面 ## 进阶操作 ### 常用命令 #### Git 别名(alias) 命令难记?没有关系 `Git` 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入完整的 `Git` 命令,可以通过 `git config` 文件来轻松地为每一个命令设置一个别名。 ```sh // 配置全局 branch 命令别名为 b git config --global alias.b branch ``` 然后比如想创建一个名为 `test` 的本地分支,如下即可 ```sh git b test ``` 在创建你认为应该存在的命令时这个技术会很有用。 #### 检出 git checkout/git restore **checkout**命令用于从历史提交(或者暂存区域)中拷贝文件到工作目录,也可用于切换分支。 **restore**指令使得在工作空间但是不在暂存区的文件撤销更改(内容恢复到没修改之前的状态) ```sh # 四个都是:撤销 test.js 从上次提交之后的所有修改 git checkout -- test.js git checkout - test.js git checkout test.js git restore test.js # 只把 test.js 还原成上一个版本的,HEAD^表示上一个版本,HEAD^^上上一个版本 git checkout HEAD^ - test.js # 只把 test.js 重置到某个指定版本 git checkout commitID test.js # 把 master 分支的 test.js 拿过来替换当前分支的 test.js git checkout master - test.js # 都是撤销上一次 commit 之后的所有文件的所有修改 git checkout -- * git checkout -- . git checkout . git restore . # 把暂存区的 test.js 重新放回工作区,和下面的 git reset HEAD test.js 作用一样 git restore --staged test.js ``` #### 重置 git reset `git reset` 通常用来把代码重置到过去的某个版本,有五种模式(`--mixed`、`--soft`、`--hard`、`--merge`),注意看注释有说明区别。 另外 `git reset` 比较暴力,要慎用,比如现在提交五次了,然后使用这个命令重置到第一次,那么第二三四五次提交记录会全部没了的,找不回来的,这种情况记得新建个分支来执行这种操作就没事了,或者使用 `git revert` ```sh # 后面一长串就是我复制的 commitID 或者说是 hash,长得就是这样子的 # 等同于 git reset commitID,因为 --mixed 是默认模式,所以可以不写 # 重置并撤销 git commit 以及 git add,保留编辑器中所有修改 git reset --mixed afcfbcb940164de24cc4f8c866e1da3a18382e10 # 重置并撤销 git commit,但不撤销 git add,保留编辑器中所有修改 git reset --soft commitID # 重置并撤销 git commit 以及 git add,并且删除编辑器中所有修改 git reset --hard commitID # 取消某次合并 git reset --merge commitID git reset --keep commitID # 把暂存区所有文件退回到工作区,相当于撤销 git add . git reset HEAD # 把暂存区的 test.js 重新放回工作区,和 git restore --staged test.js 作用一样 git reset HEAD test.js # 重置到上一个版本 git reset --hard HEAD^ # 重置到上上一个版本,以此类推 git reset --hard HEAD^^ # 重置到指定版本 git reset --hard commitID ``` `commitID` 可以通过三种方法查看 1. 执行 `git log` 命令能看到当前分支本地所有提交记录,上面每一条记录都有对应一个 `commitID` 2. 去远程代码仓库查看历史提交记录,那里每一条提交记录都有一个对应的 `commitID` 3. `git tag` 查看标签列表,如果有的话,再 `git show 标签名` 查看标签详情,里面也会有 `commitID` ```sh # 查看当前分支所有提交记录,详细列表,一条记录有几行信息 git log # 查看当前分支所有提交记录,简要列表,一条记录一行 git log --pretty=oneline # git log --oneline -n5 ``` 另外关于叫法本地仓库一般说重置、还原、撤销都行,远程仓库一般叫回滚 #### 还原 git revert `git revert` 和 `git reset` 有点类似,只是比 `reset` 稍微温柔一点,没那么暴力。git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。 上面介绍了假如现在是第五版,用 `reset` 在重置回第一版本的时候,二三四五版全都会没了,而 `revert` 重置回第一版的时候,只是新增一条提交记录“第六版”,代码变成第一版的代码,原本的一二三四五版记录都会有 另外 revert 还要分两种情况,一种是还原正常的 commit,也就是 git commit 提交的 commit,另一种是用 merge 合并的 commit,如下 ```sh # 第一种查看正常提交的 commit,如下 git show 68be9e548 commit 68be9e548dadbe7b9677874b705662a8f95efd21 # 第二种查看 merge 合并的 commit 如下,多了一行 Merge,后面指的是从哪两个 commit 合并过来的 git show 9c810c1db commit 9c810c1dbf72627dbff10d621c2974b32ed6d929 Merge: 3f6acb587 68be9e548 # 撤销正常提交的 commit git revert commitID # 撤销 merge 的 commit 提交需要加参数来区分撤销哪一个分支上的内容 # 也就是指定上面 Merge: 3f6acb587 68be9e548,这两个 id 中的哪一个 # -m 接收一个参数是数字,取值 1 或 2,表示 Merge 的第一个还是第二个 id git revert -m 1 9c810c1db # 删除最后一次远程提交 git revert HEAD git push origin master git reset --hard HEAD^ git push origin master -f # 还原某次提交 git revert commitID ``` #### 挑拣 git cherry-pick 比如有两个分支 master 和 test,在 test 上修改了,并且提交了 commit 之后,这时候想把这次的提交也给弄到 master 上,就可以复制 test 的 commitID,再换到 master 分支后执行 `git cherry-pick commitID` 就可以了 what?这不就是 merge? 和 merge 不同的是:`cherry-pick` 合并的是某一次 `commit` 提交的文件,`merge` 合并的是整个分支。且 `merge` 会额外多一条 `merge commit` 的记录,而 `cherry-pick` 不会。 而且 `cherry-pick` 更加灵活,在需要把某个/或多个分支中的 commit,合入其他分支的时候都可以用,示例如下 ```sh # 这样就把其他分支的一个 commit 合入当前分支了 git cherry-pick commitID # 如果需要把多个 commit 合过来如下,这多个 commitID 可以是来自不同分支的 git cherry-pick commitID1 commitID2 commitID3 ``` #### 变基 git rebase `git rebase` 和 `git merge` 的区别 git merge 和 git rebase 都是可以合并分支,合并用法也是一样,不同的一个是在 commit 记录的处理上: - `git merge` 会新建一条新的 commit,然后两个分支以前的 commit 记录都指向这个新 commit 记录。这种方法会保留之前每个分支的 commit 历史。 - `git rebase`会先找到两个分支的第一个共同的 commit 祖先记录,然后将提取当前分支这之后的所有 commit 记录,放到目标分的最新提交后面。经过这个合并后,两个分支合并后的 commit 记录就变为了线性的记录了。 这么说可能不太好理解,看如下示例: ```sh # 如下,需要把本地 test 分支合入 dev # 为方便理解,字母表示commit记录,数字表示提交时间顺序,可以理解为1就是1点提交的 dev -> A1 -> B3 -> 这一行是远程 dev 分支的commit记录,A1/B3是你同事提交的 ↘ X2 -> Y4↗ 这一行是拉取了 dev 分支后在本地的 test 分支 commit 记录 # 现在需要把你本地的分支合并到远程的分支去 # 用merge合并后,dev 分支看到的记录是这样的,M为merge记录的commit dev -> A1 -> X2 -> B3 -> Y4 -> M # 用rebase合并后,dev 分支看到的记录是这样的,注意顺序,且没有合并记录的commit # 简单说就是直接把 test 分支的所有新的 commit 拿出来直接拼到 dev 分支末尾,不管提交时间先后 dev -> A1 -> B3 -> X2 -> Y4 ``` - 然后是解决冲突的问题上,merge 是解决一次冲突就行了,rebase 需要一次一次地解决,如上示例的记录顺序也能看出来 - 再就是 `rebase` 可以合并多次 commit。比如本地分支提交了三个 commit,但没有 push 到远程,最后想提交到远程的时候,为了简洁,我们希望把本地的三个 commit 合并成一个 commit 再提交到远程,远程只产生一条 commit 记录,就可以用 `git rebase -i` 处理下先,这命令可以删除指定记录,或者合并多个 commit,对 commit 消息编辑等 ```sh # 删除某次提交,^表示 commitID 的前一次提交 git rebase -i 'commitID'^ # 修改多个提交信息 git rebase -i HEAD~3 ``` #### 贮藏 git stash `git stash` 常用于把修改储存起来,需要的时候再取出来。常用于: - 切换分支并且需要保留修改的时候 - 切换分支并且需要把修改带到新的分支的时候 ```sh # 把当前分支的修改储存起来,两个一样的 git stash git stash save # 存储并添加备注,方便查找 git stash save '备注信息' # 查看储存列表 git stash list # 取出储存中最近一次的修改并删除储存记录 git stash pop # 取出储存中的指定部分修改,stash@{0} 0是默认的不写也行,是啥只要查看储存列表你就知道了 git stash apply stash@{0} # 删除指定储存 git stash drop stash@{1} # 删除所有的储存 git stash clear # 创建一个新分支 test,并恢复储存工作时所在的提交到该分支上,并扔掉储藏 git stash branch test stash@{1} # 不储存暂存区的,也就是 git add 了的 git stash --keep-index ``` #### 清理 git clean 和 `git reset` 的区别是:reset 删除的是己跟踪的文件,并且将已 commit 的回退。clean 删除的是未跟踪的文件/目录 ```sh # 显示如果执行后面删除的命令将会删除的文件和目录,相当于给提前给我们确认下 git clean -n # 删除工作目录中所有没被追踪的文件(-f)以及空的子目录(-d),一起就是 -df git clean -df ``` #### 差异 git diff 用来找出仓库或者文件之间的差异,可以用来预测或者阻止可能产生冲突的合并 ```sh # 工作区 vs 暂存区 git diff # 工作区 vs 版本库 git diff head # 暂存区 vs 版本库 git diff –cached ``` 有多种方法查看两次提交之间的变动,如下面是一些示例。 ![差异](http://doc.rdiframework.net/rdiblog/20230424161345.png) ### 问题预防 - 不要对已经提交到远程仓库的 commit 进行 rebase 变基操作,除非是你一个人玩的分支 - 在切换分支,或者合并分支,或者重置/回滚之前,最好不要有未 `commit` 的文件,如果有并且不想提交就用 `git stash` 先存起来,再执行操作,如果用命令操作的话,取出之后记得清理 - 远程仓库回滚前记得做好备份,比如拉一个分支在本地。并且需要通知团队其他成员,不要悄摸摸地就搞了 ### 解决问题 #### 切换分支保留修改 有时候比如我们在 test 分支上开发了一半,由于某些原因需要切换到 master 分支,但现在又不想提交,又想保留修改并且不带到 master 分支上去,就可以这样: ```sh # 把当前分支的修改储存起来 git stash # 切换到其他分支干你的事 git checkout master # 干完了 # 切换回 test 分支 git checkout test # 取出储存中所有的修改 git stash pop # 删除所有的储存 git stash clear ``` #### 切换分支转移修改 有的时候我们需要在 test 分支上开发,但是忘记了,活快干完了才发现当前原来是 master 分支,可是已经开发了,这时候就需要切换分支到 test,并且把已经开发的部分内容也从 master 分支带到 test 分支来,就可以这样: ```sh # 储存修改 git stash # 切换到 test 分支 git checkout test # 取出储存中的全部修改 git stash pop # 或者 # 查看储存列表 git stash list # 取出储存中的指定部分修改,stash@{0} 是啥只要查看储存列表你就知道了 git stash apply stash@{0} # 再清掉储存 git stash clear ``` 合并时发生冲突用 `git merge abort` 或 `git reset --merge` 都可以取消合并 比如把不想要的代码 commit 了,但是没有 push 比如刚更新的代码出问题了,需要还原这次提交的代码 比如某次提交了不想提交的东西,需要清除掉它 #### revert 之后重新上线 diff 丢失 - 比如在 dev 分到开发了个功能,提交后会产生一条 commit 记录,为了方便理解,我们先把这次提交标记为 a - 然后合并到 master 后,我们把这次合并记录标记为 b - 结果出现了 bug 需要撤销合并,使用 revert b 撤销了,这会产生了一条新的记录 我们标记为 c - 然后继续在 dev 分支开发完成提交,提交记录标记为 d - 这时候再合并到 master 上去,此时合并后的内容不会包含 a 的提交,因为 a 被 revert 丢弃过,不会参与 diff,如果需要包含 a,需要先 revert c 意思是撤销某一次的撤销,再来合并,就 ok 了 #### 合并冲突不想合并了 合并时、或者拉取时等,发现有冲突,可能是其他同事提交的,自己不知道怎么冲突怎么选择,或者其他原因,总之不想合并了,都可以用 `--abort` 取消,比如合并的时候发现有冲突不想合并了 `git merge --abort` 取消合并即可 #### 解决冲突 有的时候合并分支冲突是由于本地主分支没有更新导致,或者有时 `git pull` 的时候冲突,只需要掉本地主分支,再重新拉一下远程分支就好了。 有的时候冲突就只能解决冲突,使用 `git status` 看由于冲突导致没有合并成功的文件是哪些,然后去编辑器打开冲突的文件即可,也可用 `cat <文件路径>` 查看指定文件里冲突的部分,直接去编辑器改 或者就是用命令,比如把 test 分支,合入 master 分支时产生冲突。 ```sh # 只保留 test 的修改 git checkout --theirs test.js # 只保留 master 的修改 git checkout --ours test.js # 都保留 git checkout --ours/theirs test.js # 查看冲突,都行 git diff --theirs git diff --ours # 这个 --theirs 和 --ours 是啥?比如冲突的时候是这样的 # <<<<<<<<< HEAD # console.log('master') // 这个就是 --ours # ========= # console.log('test') // 这个就是 --theirs # >>>>>>>>> test ``` ### Git与SVN的最主要的区别? [Git](http://git-scm.com/)是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑 上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各 自的修改推送给对方,就可以互相看到对方的修改了。 [SVN](http://subversion.tigris.org/)是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活, 干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网 速慢的话,就纳闷了。 ## 参考资料: 图解GIT: [http://marklodato.github.io/visual-git-guide/index-zh-cn.html](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) Git官方:[https://git-scm.com/](https://git-scm.com/) Git参考手册:[https://git-scm.com/docs](https://git-scm.com/docs) ## 结语 如果本文对你有一点点帮助,点个赞支持一下吧,你的每一个【赞】都是我创作的最大动力 ^_^ 更多技术文章请往:[http://www.guosisoft.com/article](http://www.guosisoft.com/article),大家一起共同交流和进步呀 ----- 前往了解**国思RDIF**低代码开发平台:[www.guosisoft.com](http://www.guosisoft.com) ![国思RDIF.vNext低代码快速开发框架](http://doc.rdiframework.net/rdiblog/20230409220406.png) ----- 一路走来数个年头,感谢RDIF框架的支持者与使用者,大家可以通过下面的地址了解详情。 官方网站: [http://www.guosisoft.com/](http://www.guosisoft.com/) [http://www.rdiframework.net/](http://www.rdiframework.net/) 特别说明,框架相关的技术文章请以官方网站为准,欢迎大家收藏! **国思RDIF低代码快速开发框架**由海南国思软件科技有限公司专业团队长期打造、一直在更新、一直在升级,请放心使用! 欢迎关注国思RDI低代码快速开发框架官方公众微信(微信号:guosisoft),及时了解最新动态。 使用微信扫描二维码立即关注 ![微信扫描二维码](http://doc.rdiframework.net/weixin.png )
正文到此结束
本文标签:
项目管理
挨踢业界
常用工具
版权声明:
本站原创文章,由
guosisoft.com
发布,遵循
CC 4.0 by-sa
版权协议,转载请附上原文出处链接和本声明。
上一篇
企业数字化转型如何做?看过来
下一篇
Vue2.x 组件通信方式详解,这篇讲全了
热门推荐
{{article.title}}
热门指数:
浏览({{article.lookCount + 5000}})
相关文章
{{article.title}}
该篇文章的评论功能暂时被站长关闭
说给你听
本文目录
文章标签
RDIF.NET
其他
微信开发
.NET
消息交互
.NetCore
项目管理
常用工具
工作流
Web前端
数据库
挨踢业界
随机文章
RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布
RDIFramework.NET V3.2->Web版本新增新的角色授权管理界面效率更高、更规范
史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式
团队项目开发"编码规范"之一:概述
.NET Core部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx)
信息系统项目管理系列之四:项目可行性研究与评估
RDIFramework.NET V3.3 Web框架主界面新增横向菜单功能
.NET快速信息化系统开发框架 V3.2->WinForm版本新增新的用户权限设置界面效率更高、更规范
微信公众号开发C#系列-6、消息管理-普通消息接受处理
如何快速开发软件?这篇文章说明白了
RDIFramework.NET开发框架用户字典助力Saas数据字典应用
RDIFramework.NET框架基于Quartz.Net实现任务调度详解及效果展示
史上最全面的SignalR系列教程-5、SignalR 实现一对一聊天
信息系统项目管理系列之五:项目整体管理
信息系统项目管理系列之三:项目管理过程
RDIFramework.NET V2.9版本 WinFom部分新增与修正的功能
企业数字化转型如何做?看过来
解放双手,markdown文章神器,Typora+PicGo+七牛云图床实现自动上传图片
JavaScript初学者应知的24条最佳实践(译)
[特别公告]RDIFramework.NET微信公众号迁移通知
网站信息
文章总数:599 篇
标签总数:8 个
分类总数:8 个
留言数量:1385 条
在线人数:
89
人
运行天数:1321天
最后更新:2023-05-18
QQ:406590790
13005007127