git入门

image.png

1. git commit --amend

有时你提交过代码之后,发现一个地方改错了,
你下次提交时不想保留上一次的记录;
或者你上一次的commit message的描述有误,
这时候你可以使用接下来的这个命令:git commit --amend
该操作会改变你原来的commit id

2. cherry-pick vs rebase vs merge

2.1. merge
merge合并

image.jpeg
那么git merge topic命令将会把在master分支上二者共同的节点
(E节点)之后分离的节点(即topic分支的A B C节点)重现在master分支上,
直到topic分支当前的commit节点(C节点),并位于master分支的顶部。
并且沿着master分支和topic分支创建一个记录
合并结果的新节点,该节点带有用户描述合并变化的信息
2.2. cherry-pick
对于多分支的代码库,将代码从一个分支转移到另一个分支是常见需求。
这时分两种情况。一种情况是,你需要另一个分支的所有代码变动,那么就采用合并(git merge)。
另一种情况是,你只需要部分代码变动(某几个提交),这时可以采用 Cherry pick。
    a - b - c - d   Master
         \
           e - f - g Feature
  • git cherry-pick 分支
  • git cherry-pick <commitHash>
  • git cherry-pick <HashA> <HashB>
  • git cherry-pick A..B
2.3. rebase

概念:git rebase你其实可以把它理解成是重新设置基线,将你的当前分支重新设置开始点。这个时候才能知道你当前分支于你需要比较的分支之间的差异。

image.png

1.  master  1-2-3 是现在的分支状态
2. 这个时候从master ,checkout出来一个prod分支
3. 然后master提交了4.5,prod提交了6.7
4. 这个时候master分支状态就是1-2-3-4-5,prod状态变成1-2-3-6-7
5. 如果在prod上用rebase master ,prod分支状态就成了1-2-3-4-5-6-7
6. 如果是merge 会出来一个8,这个8的提交就是把4-5合进来的提交

好处:提交直观 便于回退 拉取代码有预处理阶段 不用生成新的节点
注意:不要通过rebase对任何已经提交到公共仓库中的commit进行修改

  • git pull --rebase
  • git rebase -i [startpoint] [endpoint]
    git rebase [startpoint] [endpoint] --onto [branchName]
  • git rebase -i HEAD~n
pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)

3. 什么是 HEAD

3.1 概念:

Git 中的 HEAD 可以理解为一个指针,我们可以在命令行中输入 cat .git/HEAD 查看当前 HEAD指向哪儿,一般它指向当前工作目录所在分支的最新提交或者分支。

切换分支时,HEAD 会移动到指定分支

3.2 HEAD游离状态

使用的是 git checkout < commit id>,即切换到指定的某一次提交,HEAD就会处于 detached状态(游离状态)

HEAD 处于游离状态时,我们可以很方便地在历史版本之间互相切换,比如需要回到
某次提交,直接 checkout 对应的 commit id 或者 tag 名即可。
它的弊端就是:在这个基础上的提交会新开一个匿名分支!
HEAD 就会处于 detached 状态
可以看到,我还没有修改和提交的情况下,切换完成就给我新建了一个分支,并且指明 HEAD 
正游离在 2772886 的 <commit id> 上。
如果不做任何修改,想回到 master 分支,直接 git checkout master 即可,
而不要 checkout master 主干所对应的 <commit id>。
顺利回到主干的话,HEAD 的游离状态会取消,原临时游离分支也会消失。
如果是在游离状态做了修改和提交,则:
切换会 master 分支时,在游离状态所做的修改和提交无法追溯
3.3 git reset [--soft | --mixed | --hard] HEAD^
  • --mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。
$ git reset HEAD^            # 回退所有内容到上一个版本  
$ git reset HEAD^ hello.php  # 回退 hello.php 文件的版本到上一个版本  
$ git  reset  052e           # 回退到指定版本
  • --soft 参数用于回退到某个版本 保留工作目录,并把重置 HEAD 所带来的新的差异放进暂存区
    image.png
什么是「重置 HEAD 所带来的新的差异:
由于 HEAD 从 4 移动了 3,而且在 reset 的过程中工作目录和暂存区的内容没有被清理掉,
所以 4 中的改动在 reset 后就也成了工作目录新增的「工作目录和 HEAD 的差异」。
这就是上面一段中所说的「重置 HEAD 所带来的差异」
  • --hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交:
$ git reset –hard HEAD~3  # 回退上上上一个版本  
$ git reset –hard bae128  # 回退到某个版本回退点之前的所有信息。 
$ git reset --hard origin/master    # 将本地的状态回退到和远程的一样 
注意:谨慎使用 –hard 参数,它会删除回退点之前的所有信息。

4 Gerrit 的 Change-Id

Change-Id 是 gerrit (代码审核平台)的概念

image.png

  • Change-Id的生成
Gerrit 提供了标准的“commit-msg”钩子来实现。
Git 提供了4个提交工作流钩子:pre-commit、prepare-commit-msg、
commit-msg、post-commit。其中 commit-msg 钩子,
会在我们执行 git commit 时被执行。
本质上,commit-msg 钩子是一段脚本程序,放在 .git/hooks 目录下。
commit-msg 脚本可以使用 Shell、Ruby、Python 等语言实现。
  • 案例1
### Squash the commits with the same Change-Id or ensure Change-Ids are unique for each commit
shell
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 4 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 473 bytes | 473.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4)
remote: Processing changes: refs: 1, done    
To ssh://sg-8-130.hst.xxxxx.net:29418/xxxx/xxxxxx
 ! [remote rejected]   HEAD -> refs/for/dev (same Change-Id in multiple changes.
Squash the commits with the same Change-Id or ensure Change-Ids are unique for each commit)
error: failed to push some refs to 'ssh://xxxxxxxx@sg-8-130.hst.xxxxxx.net:29418/xxxxx/xxxxx'
在dev分支上有重复的change-id,使用
shell
git commit --amend 
  • 案例2 缺失 Change-Id
  1. 如果缺失 Change-Id 的是最后一个 (head) commit, 使用以下命令即可解决问题
  $ git commit --amend
  1. 如果缺失 Change-Id 的不是最后一个 commit,第二个提交缺失 Change-Id, 可用 reset 方法:
  $ git reset 1a9096a34322885ac101175ddcac7dab4c52665d
  $ git commit --amend
  $ git add ......
  $ git commit -m "你的提交日志"
  $ git push review HEAD:refs/for/dev
  1. 使用交互式rebase 找回任意提交位置的 Change-Id 以及有多个 commit 缺失 Change-Id 的情况
// 找到缺失 Change-Id 的那个 commit:
// 执行 git rebase -i, 参数为 该提交的上一个提交的 commit-id (本例中为 "表单" 那个提交):
   $ git rebase -I d714bcde0c14ba4622d28952c4b2a80882b19927
//将缺失了 Change-Id 的 commit 前面的 pick 改为 reword 即可
//逐个编辑 commit-msg 可以不需要修改 保存推出即可
$ git log
commit 8aaaa749db4a5b105aa746659c5cd266ac82fffe
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 17:43:24 2016 +0800
 
    I am commit message 3
     
    Change-Id: Ic89d5ce6ce4de70d1dcb315ce543c86a2b3ac003
 
commit 8e1cad33bcd98e175cba710b1eacfd631a5dda41
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 17:43:00 2016 +0800
 
    I am commit message 2
     
    Change-Id: I9d2af0cc31423cf808cd235de0ad02abf451937d
 
commit 1a9096a34322885ac101175ddcac7dab4c52665d
Author: liux <liux@xxxx.cn>
Date:   Mon Dec 19 15:23:36 2016 +0800
 
    I am commit message 1
 
commit d714bcde0c14ba4622d28952c4b2a80882b19927
Author: shangsb <shangsb@czfw.cn>
Date:   Wed Dec 14 09:20:52 2016 +0800
 
    这是一个提交
     
    Change-Id: I629b2bedff95491875f63634ad3da199612735b6
$ git rebase -I d714bcde0c14ba4622d28952c4b2a80882b19927
这个命令会打开默认的编辑器,一般为 vi. 内容如下:
pick 1a9096a I am commit message 1
pick 8e1cad3 I am commit message 2
pick 8aaaa74 I am commit message 3
# Rebase d714bcd..8aaaa74 onto d714bcd
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
reword 1a9096a I am commit message 1
pick 8e1cad3 I am commit message 2
pick 8aaaa74 I am commit message 3
# Rebase d714bcd..8aaaa74 onto d714bcd
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

疑问

  • A-B-C 应该在最新节点C上追加 假如我想在B或者A上追加应该怎么处理
  • 消息分支已经push 并且已经合并到master-pre 最终合并到master 而我本地追踪的是远程master 但是还是显示超前一个版本
  • 错误操作导致我的分支出现别人的代码节点 并且都处于待push的状态 也就是超前远程仓库n个版本

参考文档:
https://www.jianshu.com/p/4079284dd970
https://www.jianshu.com/p/4a8f4af4e803

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

推荐阅读更多精彩内容

  • 目录: git原理 git fork & cherry-pick & rebase git打patch以及应用pa...
    木小易Ying阅读 1,097评论 0 5
  • git 分支命令 git 分支可以理解为代码的平行世界,你可以在任意一个平行世界里开发代码,其他的平行世界不受影响...
    特立独行的佩奇阅读 528评论 0 0
  • 文件说明 Git开发常用命令,是在 hongiii 的基础上在进行补充 Git介绍 Git是分布式版本控制系统 集...
    微光北下阅读 252评论 0 0
  • 前言 来啦老铁! 时间过得真快啊,2个多礼拜的时间又过去了,又到了不见不散的学习时间~技术来源于工作(总感觉有点怪...
    狄仁杰666阅读 1,920评论 0 1
  • 题外话: git命令真的很多,这里也只是列举了一些常用的,后边的注释很重要,耐心看会看到不同及规律。 热热身:...
    3Q竹林阅读 766评论 0 1