Git使用小结(二)

引言

上一篇文章中我们简单介绍了如何使用Git进行日常的版本管理,但是Git的功能远不止如此,最重要的功能之一便是分支管理,本文将重点介绍Git中分支的使用,并会涉及到其他一些杂项的命令,最后在文末谈一下自己在Git使用中遇到的一些比较迷的问题以及是如何解决的。

Git中的分支管理

首先我们要理解什么是分支。Git常常把我们的Commit隐喻为工作流(Work Flow),分支亦同,我们每一次的提交都会使流前进一点,当我们在同一个commit的基础上产生了两个不同的新commit的时候,就如同河流在同一点流向不同的方向,从而产生了分支(Branch)。分支有许多的作用,例如不同版本的并行开发,同一版本不同人员的并行开发,做测试分支等等。
在上一篇文章中我们提到的出现冲突时,其实系统就已经形成了一个临时的分支,只是这个分支没有名称,而是以commit的标识号作为标识的临时分支。

当我们新建一个仓库后,默认是在master分支。可以用如下命令来创建一个分支

git checkout -b dev //创建并跳转到dev分支

相当于如下两条命令

git branch dev // 创建分支dev
git checkout dev // 跳转到dev分支

跳转分支时如果工作区(Working directories)还有未staged或commit的文件,会报错,需先处理
其他相关命令:

git branch -d branchName // 删除某条分支

现在我们在dev分支上随意的做些更改,

git commit -a -m "dev changes"
git checkout master // 跳转到主分支
git merge dev // merge dev分支

会看到如下输出

Updating 476259c..3934ab8 //从commit 476259c 到 3934ab8
Fast-forward //merge使用的是fast-forward模式, ff模式表示无冲突的情况下,直接将master分支指向了dev分支的commit,因此合并较快,可以用--no-ff禁用ff模式。另一种模式称为recursive模式,即产生一个新的commit来表示这个merge的过程,这样这个merge过程就会保留,否则如果采取ff模式,删除另一分支后,合并的过程就不复存在了

现在我们来做一个小实验,即两个人同时修改一个文件。
我们从dev 分支建立两个子分支 feature1, feature2
然后同时修改一个文件,然后merge,这时候git会尝试自己merge(一般是两个人修改了同一文件的不同地方),如果成功了

Auto-merging No1_TwoSum.cpp
Merge made by the 'recursive' strategy

否则(一般是两个人修改了文件的相同地方)

Auto-merging No1_TwoSum.cpp
CONFLICT (content): Merge conflict in No1_TwoSum.cpp
Automatic merge failed; fix conflicts and then commit the result.

如果自动merge失败,那么merge失败的文件会在工作区中,我们修改提交后再做commit即完成了merge的过程

<<<<<<< HEAD // 表示当前分支
Creating a new branch is quick & simple.  // 表示当前分支该文件的内容
=======                                                     // 两个分支的分割线
Creating a new branch is quick AND simple. // 要合并分支的内容
>>>>>>> feature1

当一个分支被merge之后,可以如下命令删除之

git merge -d <branchName>
git merge -D <branchName> // 删除分支,即使未被merge

分支小结

到这儿,我们整理了Git分支的使用,跳转,合并,删除。但是更重要的是要理解分支的使用场景。一般分支可以有如下的使用场景:

  • 使用dev分支作为开发分支:始终保持master分支上是稳定的可发布的版本,只有在经过充分的测试之后才将dev分支merge到master分支
  • 使用bug分支来解决某个bug
  • 使用feature分支来增加某个新功能
  • 建立程序员个人分支来保证多人并行开发

原则是多建分支,多做合并

Git commit的指代

其实任何一次commit都可以视为一个临时分支,只是这个分支没有名称,除了git branch命令之外,其他命令中的分支都可以用临时分支代替。临时分支指代有几种方式:

  • commit的ID指代:不需要完整的id,通常我们只需要列出前5-6个字符即可
  • HEAD或其他的分支名称的相对值
    • HEAD^ 代表HEAD的前一个commit (bash中可能HEAD会有歧义,需要用双引号包裹起来)
    • master^^ 代表master的前两个commit
    • HEAD~3 代表HEAD的前三个commit
  • 使用标签(tag)的相对值,方法同分支名称,标签不做介绍,可自行Google

例如我们想把test分支前一次commit所在的分支合并到当前分支中,我们可以:

branch test C0 C1 C2 C3
branch master C0
git merge test~1 // 会把C1和C2merge过来

如果我们只是想要那一次commit的更改,不想要那次commit之前的其他更改呢?

git cherry-pick test~1 // 此时只会把C2这次Commit加到C0后面,没有merge的过程

注:如果想要重新安排commit的顺序,可以用rebase -i (--interactive)

Git 的“后悔药” --- Git revert 与 Git reset

加入我们修改了一些文件,但是我们对我们的修改很不满意,甚至不希望它出现在历史提交记录中以免被同时笑话,那有没有后悔药可以吃呢?答案是有的。

  • 如果你只是想清除你工作区的修改,不包括已经staged的文件

git checkout <filePath>

  • 如果你想只想清除staged区的修改,不包括工作区的文件:

git reset (--mixed) HEAD <filePath> // HEAD可以替换为其他分支

  • 如果你想要跳回到上一次commit,并保留当前工作区和staged区的修改:

git reset --soft HEAD^

  • 如果你想要跳回到某一次commit,并清除工作区和staged区的所有修改:

git reset --hard master~5

  • 如果你的commit已经提交到远端了,那么reset没有意义,因为你的队友是在你的commit的基础上开发的,于是为了撤销你的更改,可以使用revert命令

git revert HEAD^1 HEAD^2 // 重置HEAD前两次commit所涉及到的所有修改,形成一个新的commit(可以增加-n, --no-commit 来使得不会自动形成commit)

Git 杂项命令

git log // 查看git历史提交记录
git log --graph // 以图表方式查看记录
git reflog // 查看最近的git历史命令,包括其他分支的,包括在当前commit之后的命令
git tag // 建立tag
git rm // 删除文件,从工作区和staged区

Git常见问题

  1. 有一些必须存在文件系统,但是又不需要git同步的文件
  • 使用.gitignore,在项目根目录下增加一个这样的文件,然后加入相关的忽略文件,不知道忽略哪些文件?戳这儿
  • 项目进行到一半才增加gitignore导致已经被跟踪的文件无法忽略?

git rm --cached -r <filename/directoryName>//删除staged区的文件/文件夹

  1. 文件名称大小写写错了,git没检测到区别?
  • git 本身是忽略大小写的,可以更改设置使得它不忽略大小写(git config core.ignorecase false),但是可能在不区分大小写的系统上引发bug,一个更好的选择是

git mv -f OldFileNameCase newfilenamecase

  1. (想到了再接着补充)

结语

首先,git还有许多高级的功能还没有介绍(其实笔者也不会 : ) 但是git作为一个工具,想必本文介绍的以足够应付日常生活的使用。其次git的使用其实可以很简单,多掌握一些命令只是有些时候可以更方便用更少的命令的去达到某些目的。至于使用Git命令行还是GUI,我觉得影响不大,只要你确实理解了Git的使用即可。

如果觉得本文对你有帮助的话,请点个喜欢。你的喜欢是对笔者最大的鞭策😊
如果觉得有任何疑问,可以在评论区里提出。

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

推荐阅读更多精彩内容

  • 1.git的安装 1.1 在Windows上安装Git msysgit是Windows版的Git,从https:/...
    落魂灬阅读 12,648评论 4 54
  • Git是目前最流行的版本管理系统,也是最先进的分布式版本控制系统(distributed version cont...
    pro648阅读 5,676评论 1 17
  • 最近两年,过年期间俨然成了同学聚会的专用时间,大学、高中、初中、小学,甚至我们开玩笑啥时来个幼儿园同学聚会。一时间...
    拂尘记阅读 323评论 0 1
  • 燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候。但是,聪明的,你告诉我,我们的日子为什么一...
    明月何曾是两乡阅读 425评论 0 0
  • 两年前,我们夫妻慕名而去求医。 医生姓黄,擅长中医中药,在当地算是有名气,要现场排队才能挂号。他每个星期坐诊三天,...
    丹怡d阅读 372评论 2 5