Skip to content

Files

Latest commit

916e738 · Jul 19, 2020

History

History
114 lines (90 loc) · 5.97 KB

项目中版本管理的git使用技巧.md

File metadata and controls

114 lines (90 loc) · 5.97 KB

首先明确一下工作区、暂存区、版本库

上图: git工作区暂存区版本库

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

关于这几个东西的操作不涉及push

所以你的add命令是把你工作区的改动加到了index,也就是俗称暂存区。

然后你的commit命令是把你暂存区的改动的文件加到了本地git版本库。

然后你的push命令会把你本地版本库合并向你的远程git仓库

技巧一、git把某一个分支的修改转移到另一个分支

  • git stash,这回把暂存区的修改存储起来
  • git checkout other_branch,切换到你需要这些改动的分支
  • git stash pop, 这回把存储的修改拿出来,放到这个分支的暂存区

技巧二、git从push中撤回本地master(就是push操作之后你反悔了,你要把它拿回来放在本地版本库)

  • git log 查看你之前提交的版本日志,看看你要回到哪次commit,通常就是你push前的那一次commit,把那一长串版本号拷贝下来
  • git reset --hard 你刚才拷贝的版本号,这就把HEAD指向了这个版本。

技巧三、把技巧二撤回的再撤回本地(也就是进一步把这次commit操作也撤回来)

技巧二有个问题,就是你操作完之后,你用git status查看状态会发现本地的操作tree是干净的。 这说明你还在commit之后的状态,你怎样把这个状态再撤回呢?

首先讲下git status指令,使用这个命令的时候你基本能看到两个状态,我用iterm2的话, 可以清晰地看到你add过的文件是绿色,没有add的文件是红色。红色一般时两种,未准备,未跟踪。 这两种都可以通过add来添加。

所以,这个时候你如果没有之前没有add的文件的话,你撤回这个commit后,再使用git status 命令就会看到清一色的绿色。

最后来看这个撤回当前commit的命令为:git reset --soft HEAD^

这时你就可以去执行git status看看状态了。

注意点

讲解一下图片中出现的命令:

  • 当执行 git rm --cached <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变,就是会把你commit的删掉,这时候你使用git status 时你会看到你的这个文件回到了add之前,用iterm2看会红色显示,你得重新使用add来添加它。
  • 当执行 git checkout . 或者 git checkout -- <file> 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
  • 当执行 git checkout HEAD . 或者 git checkout HEAD <file> 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

cherry-pick在工作中的使用

概念

这个字面可能完全看不出它在干什么,所以简单解释一下:

首先比如你在分支A上提交了三次,假设三次的commit号是:1,2,3

但是如果你需要在另一个分支B上复现这三次提交怎么办?

就可以用cherry-pick把这3次的改动接到B上。比如这样:

# 先把分支切到B上
然后使用如下命令:
git cherry-pick 1 2 3

这样A上的1,2,3这三次提交会加到B上作为B的三次提交。

实际情况

概念解释完了,实际有什么用呢?

一、工作中我遇见过这样的问题: 我在第一个分支A中写了一个特性,提交合并, 然后在分支B中写了另一个特性,但是在本地把develope还是master的变化往分支拉的时候,又把A的特性合道了B上, 我的本意是B分支提交的时候肯定只有它自己的特性,现在我如果要合并就戴上了A,那一定会冲突,也会乱掉。 我的做法是放弃提交合并B,我用git log把分支B的commit号记下来, 然后重新开了分支C,这个分支是干净的,然后我用cherry-pick命令把这些commit按照时间顺序加到了C上,最后提交合并了C。 这样就解决了中间不小心污染分支的问题。

二、还可能会有这样的问题: 比如你的应用已经发布了1.0版本,这个代码分支叫prod-1.0,现在正在开发2.0, 开发的分支叫做dev-2.0,但是有一天产品说,要把正在开发的某个特性提前上线, 也就是要把开发分支dev-2.0上某些提交(commit)移动到prod-1.x的版本上,那么就可以用到cherry-pick。

具体做法如下:

  • 基于prod-1.0分支创建新的分支prod-1.1
git checkout -b prod-1.1 prod-1.0
  • 将dev-2.0分支上的某些提交(commit, 比如c1, c2, c3)在分支prod-1.1上重演
# 做完上一步就在新的分支prod-1.1上了,然后把dev的某些提交接过来
git cherry-pick c1 c2 c3

其他命令

  • git merge --no-ff 分支名A 把A合并到当前分支,并且在看历史时会显示A的分叉出去的提交,可读性会更好。

zsh 相关

常用快捷键

  • gco 分支名 = git check out 分支名 切换分支
  • gc == git commit 提交改动,进入vim编辑界面,界面可看到哪些文件改动了
  • gp == git push 推送远端
  • glola 查看所有分支提交历史,以及各种合并信息

回目录