Git 常用操作

# 简介

首先,这并不是一篇关于Git基本操作的分享,在看它之前你一要确信自己明白Git的简单操作与版本库、分支等基本概念。虽然小媛混迹Git有段时日,但是渐渐发现git add和git commit已经渐渐不能满足协作开发的需求,于是整理出一些在使用时会接触的到进阶操作,供后人敬仰,哦不,观赏。

ps: 因为各种原因图片未正常显示。


### 版本回退 reset

`git reset --hard commit_id`

HEAD指向当前版本,所以如果你要回退到上一个提交的版本时可以使用 `git reset --hard HEAD~`,回退到上n个版本的时候也可以使用 `git reset --hard HEAD~n`,当然如果你不是记忆很好的话可以使用 `git log`命令查看最近提交的所有版本的 `commit_id`,然后找到你要回退的那一个版本对应的 `commit_id`,使用 `git reset --hard commit_id`命令回退。

操作:

我先使用 `git log`把我当前的所有提交显示出来,如下:

! [](media/14494585670894/14590662264925.jpg)

当前的HEAD是e5534,我准备回退到806dcc那次提交,于是我使用 `git reset --hard HEAD~`,如下:

! [](media/14494585670894/14590664323484.jpg)

它提示我已经切换到上一次提交,当前HEAD指针指向的就是806dcc。

但是如果版本回退完我突然想找回原来的版本e5534怎么办呢。

首先我们需要找到当年的那个 `commit_id`(装作我不知道它是e5534),于是我试了下 `git log`,如下:

! [](media/14494585670894/14590666405032.jpg)

并没有当年的 `commit_id`,因为git log输出的 `commit_id`都是距离当前HEAD最近的提交的所有的 `commit_id`,所以我们要使用 `git reflog`,git reflog是记录了你所有操作的 `commit_id`,我们轻松的找到了要退版本的 `commit_id`为e5334:

! [](media/14494585670894/14590668360252.jpg)

然后使用 `git reset --hard e533474`

! [](media/14494585670894/14590670088945.jpg)

哇哈哈,又回来啦!

其实Git中HEAD指向的就是当前的版本,当你进行版本回退等操作时,改变只是HEAD指针的指向,下面的图很好的说明了我们刚刚的操作:

! [](media/14494585670894/14590674274582.jpg)

### 合并分支 merge

在Git中有一个主分支master,当你创建版本库的时候他就自动生成了,他像一条时间线,上文中说过HEAD指向当前版本,也就是当前提交,但其实HEAD指向的是master,master直接指向提交,如图:

! [](media/14494585670894/14590688517969.jpg)

当我们创建新的分支develop的时候,Git会新建一个develop指针指向master,再将HEAD指针指向develop。当我们在develop上面进行操作的时候并提交的时候,develop指针不断向前移动,master指针原地不动,当我们在develop的开发全部完成时想把这部分功能合并到master时就要切换到master分支,然后使用 `git merge develop`命令,这部分的操作如图:

初始状态:

! [](media/14494585670894/14590694723586.jpg)

git branch develop 

! [](media/14494585670894/14590694897780.jpg)

在develop分支上进行开发后,develop:  git commit -m "develop 开发完成"

! [](media/14494585670894/14590695739112.jpg)

master: git merge develop

! [](media/14494585670894/14590696416639.jpg)

当本地master落后远程的master分支时,合并分支可能有冲突,解决完有冲突的文件再 `git add .``git commit -m "XXX"`就可以了。

上文中分支合并以master与develop为例,其他情况对号替换就好啦。

### 合并分支 rebase

因为上文中的merge会把你的sourceTree搞成这样:

! [](media/14494585670894/14590736138938.jpg)

所以作为一个强加强迫症的程序媛是拒绝的,那我们怎么办呢~ rebase来了,它可以避免merge时屎一样的交叉~

当你在主分支拉下分支开发之后,你的队友在主分支又提交了一次更新,于是远程就变成了如下图的origin,但是你还停留在最初的起点!这时候你开发完了需要把你开发的功能并到主分支去。

! [](media/14494585670894/14590754646435.jpg)

于是你想到了merge,你可以用pull把远程分支拉下来,然后使用merge把更新后的远程分支和你的开发分支进行合并,解决冲突巴拉巴拉,然后就成了下图。

! [](media/14494585670894/14590756698026.jpg)

我们又一次回忆起了那个屎一样的merge图。如果分支很多的话,在sourceTree上这是非常难看的,我们需要一个简洁大气的方式。

你可以这样做:
mywork: git rebase origin
解决冲突
git add .
git rebase --continue

然后就成了下面这样:

! [](media/14494585670894/14590759181553.jpg)

然后再把你原来的开发分支删除,如图:

! [](media/14494585670894/14590761156793.jpg)

结束啦!

### 合并分支 cherry pick

cherry pick 是将某一次commit应用到某分支作为一次提交。先切使用git log,找到要合并的那次提交,复制 `commit_id`,切换到正确的要合并到的分支,使用git cherry-pick commit_id,然后是使用git status解决冲突,再用git add .和git commit(无注释),提交。

! [](media/14494585670894/14590737605050.jpg)

(1) 在A分支最后一次commit上进行cherry pick到B分支,相当于在B分支上加入了A分支上最后的commit的内容并作为在B分支上的一次提交。适用于开发feature、bigfix的情况,直接并入develop分支。
(2) 在更新后的B分支的B·部分新建分支A·,将在旧的B分支上开出来的A分支的最后一次提交cherry pick 到A·分支上,并提交。适用于开发mvp版本时,主线版本落后的情况

### 暂存现场 stash

当你正在develop分支开心的开发新功能时,突然收到指令需要紧急修复一个Bug,但是这时候功能只开发了一半,还不能commit怎么办,这时候你可以使用 `git stash`,将现在的工作保存下来,然后新开分支去修复Bug,结束后回到develop分支使用 `git stash list`,你就可以看到你刚刚暂存的进度,然后是使用 `git stash apply`进行恢复,但此时stash里面的内容并不被删除,你还要使用 `git stash drop`来删除stash里面的内容,所以为了一劳永逸直接使用 `git stash pop`命令就好啦,恢复完事stash内容也被删除啦~

### 重写历史

通俗的说就是把多次本地commit压缩为一次commit(未推到远程仓库)

1. 初始SourceTree:

! [](media/14494585670894/14590734295389.jpg)

我们要将前四条commit合并为一条,选中前四条提交中最早的提交的上一次提交,获得它的 `commit_id`值。

2. 使用命令: git rebase –i commit_id

! [](media/14494585670894/14590734550346.jpg)

3. 我们将后三条提交前面的pick全部改为squash

! [](media/14494585670894/14590734674860.jpg)

4. 回到SourceTree,三次commit已经被合并为一次提交。

! [](media/14494585670894/14590734799579.jpg)

### 参考链接
这是个非常好的教程 [Pro Git中文版](http://git.oschina.net/progit/)
http://git.oschina.net/oschina/git-osc/wikis/Home
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013744142037508cf42e51debf49668810645e02887691000 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值