git 学习(2) ---- git 命令进阶

git 分支命令

git 分支可以理解为代码的平行世界,你可以在任意一个平行世界里开发代码,其他的平行世界不受影响,Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来;真正改变你的开发模式。

举两个分支管理的应用场景

场景一

假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作

场景二

假设一个公司有一套代码,面向不同的客户,每个客户都有自己的客制化功能;如果全部提交到git 上,非常冗余。有了git 的分支技术,就很方便。给每个客户都创建一个单独的分支,如果代码要release 给客户,也可以做到不同客户之间的代码相互保密。

git_4_1.png

git 创建分支

git checkout BranchName # switch to an exist branch

git checkout -b BranchName # create and switch to a new local branch

git branch -d BranchName # delete a local branch

git 查看分支

git branch -av # show all branches

git branch -r # show remote branches

git branch # show local branches

git branch BranchName # create a new local branch

从远程分支 checkout 出来的本地分支,称为跟踪分支(tracking branch)。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。就是将本地分支和远程的分支相互关联

在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如origin 上除了 master 之外的其它分支。

git checkout branchname --track Remote name/BranchName # create and switch to a new branch to track remote branch

比如:

git checkout -b c_cn_9380_yst_cn_an_cus-cus  --track aosp/c_cn_9380_yst_cn_an_cus-cus

git checkout -t 远程的分支 直接切到追踪远程的分支

分支合并

一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支。

git_4_2.png

你可以使用以下命令将任何分支合并到当前分支中去

 git checkout master // 切换到Master分支

 git merge --no-ff develop // 对Develop分支进行合并 --no-ff 参数的含义:

默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将Master分支指向Develop分支。

使用--no-ff参数后,会执行正常合并,在Master分支上生成一个新节点。

git cherry-pick

git cherry-pick + <commit hash>

cherry-pick 命令应用于需要将其他分支的commit 合并到当前分支的情形,cherry-pick 之后会生成一笔新的提交。

git_4_3.png

git blame

git blame +文件名

通过git blame命令,我们可以查出某个文件的每一行内容到底是由哪位大神所写;可以非常方便的定位问题

git patch

本身Linux命令里有diff和patch两个命令可以生成patch和打patch。但是有两个缺点值得注意:

对单个文件或者多个文件,diff和patch这两个文件比较方便。对于git这种以project为单位的修改,尤其是涉及到多个文件夹下的多个文件的改动时,就很不方便,无法保存commit的信息。

git 本身带有patch 的命令,git 生成patch 的命令如下:

git format-patch HEAD^        

生成最近的1次commit的patch

git format-patch HEAD^^      

生成最近的2次commit的patch

$ git format-patch <r1>..<r2>              

生成两个commit间的修改的patch(包含两个commit. <r1>和<r2>都是具体的commit号)

git format-patch -1 <r1>                           

生成单个commit的patch

$ git format-patch <r1>        

生成某commit以来的修改patch(不包含该commit)

$ git format-patch --root <r1>               

生成从根到r1提交的所有patch

合入patch 的命令:git am 和 git apply

git apply --stat 0001-limit-log-function.patch       

查看patch的情况

git apply --check 0001-limit-log-function.patch        

检查patch是否能够打上,如果没有任何输出,则说明无冲突,可以打上

(注:git apply是另外一种打patch的命令,其与git am的区别是,git apply并不会将commit message等打上去,打完patch后需要重新git add和git commit,而git am会直接将patch的所有信息打上去,而且不用重新git add和git commit,author也是patch的author而不是打patch的人)

$ git am 0001-limit-log-function.patch    

将名字为0001-limit-log-function.patch的patch打上

$ git am --signoff 0001-limit-log-function.patch  

添加-s或者--signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者

git am ~/patch-set/*.patch      
将路径~/patch-set/*.patch 按照先后顺序打上
$ git am --abort      

当git am失败时,用以将已经在am过程中打上的patch废弃掉(比如有三个patch,打到第三个patch时有冲突,那么这条命令会把打上的前两个patch丢弃掉,返回没有打patch的状态)

git am --resolved                              

当git am失败,解决完冲突后,这条命令会接着打patch

git rebase

把一个分支的修改合并到当前分支。

假设现在我基于远程的分支(master)建立一个名为A的本地分支,我们在这个分支做一些修改,然后生成两个提交(commit),有些人也在"master"分支上做了一些修改并且做了提交了. 这就意味着"master"和"A"这两个分支各自"前进"了,它们之间"分叉"了。

git_4_4.png

在这里,你可以用"pull"命令把"master"分支上的修改拉下来并且和你的修改合并; 结果看起来就像一个新的"合并的提交"(merge commit):

git_4_5.png

但是,如果你想让"A"分支历史看起来像没有经过任何合并一样,你也许可以用 git rebase:

git checkout A
git rebase master

这些命令会把你的"A"分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把"A"分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到"A"分支上。

git_4_6.png

在rebase的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止rebase并会让你去解决 冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:

git rebase --continue

这样git会继续应用(apply)余下的补丁。

在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。

git rebase --abort

另外,我们在使用git pull命令的时候,可以使用--rebase参数,即git pull --rebase,这里表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把本地当前分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上。

将多笔提交合并为一个提交
git_4_7.png

git rebase -i 命令可以压缩合并多次提交

格式:git rebase -i [startpoint] [endpoint]

其中-i的意思是–interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint] [endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支HEAD所指向的commit(注:该区间指定的是一个前开后闭的区间)。

// 合并从当前head到15abd5678 (commit id)

git rebase -i 15abd5678

或:

// 合并最近的两次提交

git rebase -i HEAD~2

执行这个命令后会跳到一个vi编辑器

里面的提示有:

  • pick:保留该commit(缩写:p)

  • reword:保留该commit,但我需要修改该commit的注释(缩写:r)

  • edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)

  • squash:将该commit和前一个commit合并(缩写:s)

  • fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)

  • exec:执行shell命令(缩写:x)

  • drop:我要丢弃该commit(缩写:d)

保存之后会弹出对话框让你修改你的 commit message,修改完成之后保存就可以了。

1.1.7 总结

git branch/checkout 分支常用指令

git cherry-pick 直接将其他分支的commit 合并回本分支

git blame 查看某个文件所有代码的来源commit

git format-patch/git am/apply 生成patch 合入patch

git rebase 变基命令可以用来合并其他分支的代码到当前分支,也可以将多笔commit 合并为一笔。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容