0


git提交分支

1. git提交分支相关

  • 在本地新建分支,保证和远程分支一样git checkout -b 分支名如果分支已存在,只需要切换的话git checkout 分支名
  • 提交前先把代码拉下来更新一下,确保不会覆盖别人的代码git pull origin 远程分支
  • (如果有)解决冲突
git diff  // 然后查看冲突的原因
  • 查看git状态(哪些还未提交)
git status
  • 提交到缓存区
git add .
  • 提交到本地仓库
git commit -m '我这次提交是为了干啥'
  • 提交到远程仓库(线上仓库)
git push origin 分支名        
  • (如果不存在)本地建立一个你要合并的分支(如你在a分支上开发,现在要和b分支merge并提交到b分支上)
git checkout -b 要合并的分支b
  • 把要合并分支的代码拉下来
git pull origin 要合并的分支b
  • 在本地合并到b分支
git merge 要合并的分支b
  • 如果报错,那么查看git状态
git status

2. 关于.gitigonore 文件详解

这个文件的完整文件名就是“.gitignore”,注意最前面有个“.”。这

一般来说每个Git项目中都需要一个“.gitignore”文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。

实际项目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密码的配置文件等等。

这个文件的内容是一些规则,Git会根据这些规则来判断是否将文件添加到版本控制中。

过滤规则:

/mtk/ 过滤整个文件夹

*.zip 过滤所有.zip文件

/mtk/do.c 过滤某个具体文件

被过滤掉的文件在push的时候不会上传。

需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中:

!*.zip

!/mtk/one.txt

版本规则:

唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。

假如只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理。就需要使用这个!规则:

/mtk/

!/mtk/one.txt

如果在创建.gitignore文件之前就push了项目,那么即使你在.gitignore文件中写入新的过滤规则,这些规则也不会起作用,Git仍然会对所有文件进行版本管理。

出现这种问题的原因就是Git已经开始管理这些文件了,所以你无法再通过过滤规则过滤它们。

重点:在项目开始就创建.gitignore文件的习惯,否则一旦push,处理起来会非常麻烦。

3. git的版本回退

因为在合并分支的过程中,变更太多,是本地环境配置的问题,需要回退到上一个版本,然后再重新提交。

git log
  • 定义:该命令显示从最近到最远的提交日志。每一次提交都有对应的 commit id和 commit message。
    image-20220501172511044
    ```
    git log --pretty=oneline


- 可以将版本号和描述内容在一行内显示,使得输出更加简洁一些
![image-20220501172550786](https://s2.loli.net/2022/05/01/vZd5cjHiU6Cs2Eb.png)

git reset --hard id



- 定义:根据 id 回退到指定的版本,一般要回退的版本号的前7位即可

git push origin HEAD --force



- 推送到本地到远程仓库:让远程仓库代码你本地一样,到当前本地的版本。

git reflog



- 定义:查看命令操作的历史查找到需要的 ***操作id***,依旧使用```*git reset --hard id*```可以回退到先前的版本。

## 4. git的cherry-pick

cherry-pick 的翻译是择优挑选,使用git cherry-pick命令,可以选择将现有的一个或者多个提交的修改引入当前内容。

那么,什么情况下会有到这么不常见的命令呢?

假设你现在正在开发一个项目,有一个功能分支 feature,开发分支 develop。 feature 有3个提交,分别是 A ,B ,C 。develop 分支只想加入 C 功能, 此时合并操作无法满足,因为直接合并 feature,会将3个提交都合并上,我想合并就只有 C,不要 A,B。此时就需要挑樱桃大法–cherry pick!

具体的做法:

1.切换到 develop 分支。
2.通过 git log feature,找到 C 的 SHA1 值。
3.通过 git cherry-pick <C的SHA1> ,将 C 的修改内容合并到当前内容分支 develop 中。
4.若无冲突,过程就已经完成了。如果有冲突,按正常冲突解决流程即可。

![image-20220501172636309](https://s2.loli.net/2022/05/01/mQ3jtNH8P7Ak5SV.png)
从上面简单的小例子上看,我想,小伙伴们,都应该已经对 merge 和 cherry-pick 有了大概的区分,这里做下对比,让大家有个清晰明确的掌握,防止似是而非,以后误操作。

> git merge :将两个提交历史合并。
>  git cherry-pick:将提交对应的内容合并。

这里,非常需要明确的一点,**commit 代表的是修改!**

例中,提交 C 的内容,就是对比 B 上面做的修改,可能是创建了一个文件,或者修改了一个词语。那么 C 内容就是一个文件的添加,和一个词语的修改。

以提交 C 为结束点的提交历史,实际内容是提交 C 和 C 之前所有的修改。

**cherry-pick 操作的对象就是 commit。**
**merge 操作的对象就是 commit history。**

例子:

利用cherry-pick,可以将一个分支中的修改的内容合并到另一个分支上。如要将lyrisgao中的某一个功能提交的内容合并到addsomeparms
![image-20220501172713045](https://s2.loli.net/2022/05/01/9zJs6aE5ko3TVrZ.png)

- 合并之后,可以发现 提交的并不是真正的分支的内容,是分支内容的复制品,因为两者的SHA1的值是不同的,可以确定是两个提交。![image-20220501172726737](https://s2.loli.net/2022/05/01/UyiVFRoCvzhGn3a.png)

## 4.1 cherry-pick 其他常用命令


- 挑选多个提交合并,提交之间用空格相隔。例如,想挑选1号和3号的,就可以用git cherry-pick 4d2951 e4cdff9命令一步到位了。

git cherry-pick <commits>



- 挑选一个范围的多个提交合并,但是这个语法对应操作区别是左开右闭,不包含start-commit。另外要注意两个commit 之间要求有连续关系的,并且前者要在后者之前,顺序不能颠倒。

git cherry-pick <start-commit>..<end-commit>



- 这个和上面一样,区别就是加了一个^符号,就变成闭区间了,包含 start-commit。

git cherry-pick <start-commit>^..<end-commit>



- 挑选 branch 最顶端的提交。例如挑选 3 号樱桃可以用git cherry-pick develop。```git cherry-pick <branch name>``````git cherry-pick --continue  //继续下个操作git cherry-pick --quit //退出git cherry-pick --abort //停止本次操作```以上是关于 cherry-pick 操作控制命令,当 cherry-pick 多个提交时,假设遇到冲突,–continue继续进行下个,–quit结束 cherry-pick 操作,但是不会影响冲突之前多个提交中已经成功的,–abort直接打回原形,回到 cherry-pick 前的状态,包括多个提交中已经成功的。

## 5. git merge 和 git rebase

**git rebase 和 git merge是git合并分支的两种方式,然而他们却采用了不同的工作方式**,以下面的一个工作场景说明其区别:
![image-20220501172807189](https://s2.loli.net/2022/05/01/2Zcd1sqomQjh3ea.png)
场景:

> 下图所示:当feature分支有新的需求提交,同时,master 分支也有修改。

这时,如果要将master 上新的提交合并到你的feature分支上,我们有两种选择:merging or rebasing

## 5.1 merge

执行以下命令:

git checkout feature
git merge master
或者执行:
git merge master feature
此时在feature上git 自动会产生一个新的commit(merge commit)


> **注意:**

git 本地分支合并master分支代码 : 提示为 git merge Already up-to-date.
 原因在于merge之前,master分支的代码不是最新代码

做法:
1.应该先切换到master分支
git checkout master

2.拉取代码
git pull origin master

3.再切换到要合并master的分支
git checkout 分支

4.合并代码
git merge master
有冲突则解决冲突


当使用 git log 查看时,发现已经多了一个commit

![image-20220501172841032](https://img-blog.csdnimg.cn/img_convert/e416ac4532391c191554517fad8d98eb.png)

## 5.2 merge 特点

merge 特点:自动创建一个新的commit
 当合并时遇到冲突,修改后重新commit即可
 优点:将commit的实际情况进行记录,便于以后查看
 缺点:由于每次merge会自动产生一个merge commit,所以在使用一些git 的GUI tools,如果commit频繁,这样会使得feature分支很杂乱,这时可以考虑使用rebase来进行合并处理。

## 5.3 rebase

本质是变基,即找公共祖先

执行以下命令:

git checkout feature
git rebase master

![image-20220501172907076](https://s2.loli.net/2022/05/01/rZSi1vRmCJz2ghk.png)
## 5.4 rebase 特点

rebase 特点:将commit历史进行合并
 优点:项目历史比较简单,少了merge commit
 缺点:当发生冲突时不容易定位问题,因为re-write了history

合并时如果出现冲突需要按照如下步骤解决

1.修改冲突部分
2.git add3. git rebase --continue
(如果第三步无效可以执行 git rebase --skip)
4.不要在git add 之后习惯性的执行 git commit命令


The Golden Rule of Rebasing rebase 的黄金法则
 never use it on public branches(不要在公共分支上使用)
 比如说如下场景:如图所示
![image-20220501172920139](https://s2.loli.net/2022/05/01/NJSagP6HsyoGATp.png)
如果你rebase master 到你的feature分支:

rebase 将所有master的commit移动到你的feature 的顶端。问题是:其他人还在original master上开发,由于你使用了rebase移动了master,git 会认为你的主分支的历史与其他人的有分歧,会产生冲突。

所以在执行git rebase 之前 需要认真考虑,

会有其他人看这个分支么?
 if YES 不要采用这种带有破坏性的修改commit 历史的rebase命令
 if NO ok,随你便,可以使用rebase

### 将几个commit log 合并一个

git rebase -i 版本号(需要合并的那几个commit log 之前的那一个commit版本号)

```

  • 之后会显示以下界面image-20220501172954780pick : 代表合并后的提交用这个提交的注释; s : squash命令的简写,代表合并提交中包含这个提交; d : 代表合并提交中排除这个提交。
  • wq保存之后git rebase --continue
  • 设置注释之后
  • 完成以上是将连续的commit id合并,假如是不连续的话,那么你也是拿最早的commit id来执行git rebase -i commit id,然后进入弹出框,你会看到pick中没有最早你要合并的那个commitid,这里你需要按照列表的格式把最早的commit id复制到顶部,格式就是 pick commit id XXX,这个XXX就表示注释(可有可无),然后再把你要合并的几个commit一定复制到当前这个新加的pick下面,然后修改成 (s commit id XXXX),有几个写几个,把重复的去掉,然后保存即可。

5.5 总结

尽量不要在公共分支使用 rebase
本地和远端对应同一条分支,优先使用 rebase ,而不是 merge

因为往后放的这些 commit 都是新的,这样其他从这个公共分支拉出去的人,都需要再 rebase,相当于你 rebase 东西进来,就都是新的 commit 了

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

merge 和 rebase 实际上只是用的场景不一样

​ 更通俗的解释一波:

  • 比如 rebase,你自己开发分支一直在做,然后某一天,你想把主线的修改合到你的分支上,做一次集成,这种情况就用 rebase 比较好。把你的提交都放在主线修改的头上。
  • 如果用 merge,脑袋上顶着一笔 merge 的8,你如果想回退你分支上的某个提交就很麻烦,还有一个重要的问题, rebase 的话,本来我的分支是从3拉出来的, rebase 完了之后,就不知道我当时是从哪儿拉出来的我的开发分支
  • 同样的,如果你在主分支上用 rebase , rebase 其他分支的修改,是不是要是别人想看主分支上有什么历史,他看到的就不是完整的历史课,这个历史已经被你篡改了

结论:

想要干净的历史,少了merge commit的线性历史树,选择git rebase
而如果你想保留历史记录,并且想要避免重写commit history的风险,使用git merge

标签: git github svn

本文转载自: https://blog.csdn.net/weixin_44911248/article/details/124529556
版权归原作者 几窗花鸢 所有, 如有侵权,请联系我们删除。

“git提交分支”的评论:

还没有评论