Git杂烩

2020-01-27  本文已影响0人  高级程序狗

总结一些git的难点,和奇葩操作。

checkout和reset的异同点

checkout和reset是git初学时比较容易混淆的两个概念,具体是干嘛的这里就不赘述了,详见官方文档

它们的主要区别是:
1、如果是在ref/commit层级使用,checkoutreset --hard功能基本是一样的,除了:

2、如果是file/path层级使用,都不会移动HEAD,只会在目标ref中找到对应的文件来覆盖三棵树,具体区别是:

git为啥不能对路径或文件使用hard reset?

修改已经push的某个提交

公司管控提交日志内容,还要记考核,搞不好还要通报“表扬”。特地研究了一下如何修改已经push的某个提交日志、或者追加修改等。

如下命令是交互式变基命令:

git rebase -i HEAD~3

执行该命令后可以对最近3个提交(也可以指定从某一个提交hash开始)进行交互式变基操作。该命令执行后会列出最近的3次提交:

pick d8b6fe9 test2
pick 5094aa9 test3
pick 553e11f test4

# Rebase 00a9f09..553e11f onto 00a9f09 (3 commands)
#
# 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
# d, drop = remove commit
#
# 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

比如这里需要把test3的提交日志改成:"发车",vim修改test3的pick为edit,然后保存:

pick d8b6fe9 test2
edit 5094aa9 test3
pick 553e11f test4

# Rebase 00a9f09..553e11f onto 00a9f09 (3 commands)
# ...

这时会提示如下命令,并且,HEAD已经指向test3:

You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue

然后执行命令修改提交日志(该命令表示重新最近的提交,可以重新填写日志,并且会把当前暂存区的文件一并提交)

git commit --amend

修改test3日志为"发车"

发车

Code Source From: Self Code
Description:
Jira: #
市场项目编号:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Oct 12 19:45:04 2018 +0800
#
# HEAD detached from 668076c
# Changes to be committed:
#       modified:   index.html
#
~
~
~

完成后,执行:

git rebase --continue

这时本地分支已经和origin分支“分离”,使用命令强推(强推有风险,做好备份):

git push origin -f
sevens:redux_todolist admin$ git log --oneline
c1386d6 (HEAD -> fetchtest, origin/fetchtest) test4
5f9e5fc 发车
d8b6fe9 test2
00a9f09 test1
...

在A分支重放B分支上的提交

1、假设目前分支如下,想在master上重放c6、c7但是不想包含c4,怎么做?

-- c1 -- c2 -- c3        //master
           \
           c4 -- c5      //server
             \
             c6 -- c7    //client

这里用到以下命令:

git rebase --onto master server client

翻译成白话就是:取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然后把它们在 master 分支上重放一遍。

2、假设目前分支如下,想在master上重放c6、c7但是不想包含c4、c5,怎么做?

-- c1 -- c2 -- c3        //master
           \
           c4 -- c5 -- c6 -- c7      //client

先创建一个临时分支test:

-- c1 -- c2 -- c3                //master
           \
           c4 -- c5              //temporary
                  \
                   c6 -- c7      //client

然后思路和之前的onto一样,找到client相对temporary之后的提交,在master上重放:

git rebase --onto master temporary client

执行之后是这样:

                c6 -- c7         //client
                /
-- c1 -- c2 -- c3                //master
           \
           c4 -- c5              //temporary

然后执行:

git checkout master
git merge client

3、假设目前分支如下,想在master上只重放c6怎么做?

-- c1 -- c2 -- c3        //master
           \
           c4 -- c5 -- c6 -- c7      //client

还是之前的思路,只是这里在c5、c6创建两个临时分支A、B,找到B相对A的提交c6,onto到master即可。

清理Merge xx into xxx提交

使用git reabse重放会忽略merge提交,但是最好只在本地梳理提交,不要使用git push xxx -f,否则其他开发者拉取时可能会有问题。

上一篇 下一篇

猜你喜欢

热点阅读