一、概念
1.Git的四个工作区域
Git本地有四个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)、git仓库(Remote Directory)。文件在这四个区域之间的转换关系如下:
网络异常,图片无法展示
|
Workspace
:工作区,就是你平时存放项目代码的地方Index / Stage
:暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息Repository
:仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本Remote
:远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
2.文件的状态
网络异常,图片无法展示
|
工作目录下的每一个文件都不外乎这两种状态:已跟踪 或 未跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后, 它们的状态可能是未修改,已修改或已放入暂存区。简而言之,已跟踪的文件就是 Git 已经知道的文件。
Untracked
:未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add状态变为Staged
.Unmodify
:文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified
。如果使用git rm移出版本库, 则成为Untracked
文件Modified
:文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过vgit add可进入暂存staged
状态, 使用git checkout则丢弃修改过,返回到unmodify
状态, 这个git checkout即从库中取出文件, 覆盖当前修改。Staged
:暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify
状态. 执行git reset HEAD filename取消暂存,文件状态为Modified
3.文件状态转变图
网络异常,图片无法展示
|
- 新建文件--->
Untracked
- 使用add命令将新建的文件加入到暂存区--->
Staged
- 使用commit命令将暂存区的文件提交到本地仓库--->
Unmodified
- 如果对Unmodified状态的文件进行修改--->
modified
- 如果对Unmodified状态的文件进行remove操作--->
Untracked
二、Stash —— 暂存当前改动
当您想记录工作目录和索引的当前状态,但又想返回一个干净的工作目录时,请使用git stash。该命令将保存本地修改,并恢复工作目录以匹配头部提交。
场景:我在一个分支上修改了代码,但是突然有个bug,我需要修复,并且刚刚修改的代码我不需要提交(即不能混合进修复代码里),此时就可以将修改的代码先保存起来,等修复完bug之后再取出来继续修改。
1.暂存工作目录下的所有改动
git stash git stash -u // 可以使用`-u`来排除一些文件 复制代码
2.暂存时记录消息
git stash save <message> 或 git stash push -m <message> 复制代码
3.暂存指定文件
git stash push working-directory-path/filename1.ext working-directory-path/filename2.ext 复制代码
4.查看暂存记录
$ git stash list 复制代码
5.使用某个指定暂存
git stash apply // 应用最近一次的stash git stash pop // 应用最近一次的stash,随后删除该记录 git stash apply "stash@{n}" // 'n'是`stash`在栈中的位置,最上层的`stash`会是0,drop与pop同理 git stash apply "stash@{2.hours.ago}" //使用时间标记,drop与pop同理 复制代码
6.删除暂存记录
git stash drop // 删除最近的一次stash git stash clear // 删除stash的所有记录 复制代码
二.Cherry-pick——复制commit内容
给定一个或多个现有提交,应用每个提交引入的更改,为每个提交记录一个新的提交(commitHash会改变)。这需要您的工作树清洁(没有从头提交的修改)。
场景:我在一个分支A上提交了很多次代码,此时临近发版阶段,发现有些需求还没开发完毕,此事只需要对分支A上的某些需求进行上线,因此需要对上线的代码进行抽离,将分支A的某几个commit信息,复制到分支B上,然后对分支B上的代码进行上线。
1.将已经提交的 commit,复制出新的 commit 应用到分支里
// 在干净的分支B上执行: git cherry-pick commit1 commit2 // 将commit1 和 commit2 两个提交应用到当前分支 复制代码
2.cherry-pick有冲突
需要先解决代码冲突,重新提交到暂存区后,再执行命令:
cherry-pick --continue 复制代码
3.放弃cherry-pick
gits cherry-pick --abort // 回到操作前的样子,就像什么都没发生过。 git cherry-pick --quit // 不回到操作前的样子。即保留已经 `cherry-pick` 成功的 commit,并退出 `cherry-pick` 流程。 复制代码
参考文章:
Git 不要只会 pull 和 push,试试这 5 条提高效率的命令