Loading

Learn Git Branching

Learn Git Branching 总结

链接:https://learngitbranching.js.org

主要

基础篇

1.Git Commit
git commit
git commit
2.Git Branch
git branch bugFix
git checkout bugFix
3.Git Merge
git checkout -b bugFix
git commit
git checkout master
git commit
git merge bugFix
4.Git Rebase
git checkout -b bugFix
git commit
git checkout master
git commit
git checkout bugFix
git rebase master

高级篇

1.分离 Head
git checkout c4

2.相对引用 ^
最优解:

git checkout bugFix^

其他解:

git chekcout bugFix
git checkout HEAD^
3.相对引用 2 ~
git branch -f master c6
git branch -f bugFix c0
git checkout c1
4.撤销变更

reset: (local)
git reset通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset 向上移动分支,原来指向的提交记录就跟从来没有提交过一样。

revert: (pushed)
虽然在你的本地分支中使用git reset很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的哦!为了撤销更改并分享给别人,我们需要使用git revert

git reset HEAD^
git checkout pushed
git revert HEAD

移动提交记录

1.Git Cherry-pick
git cherry-pick c3 c5 c7
2.交互式 rebase
git rebase -i HEAD~4

移动提交记录

1.只提取一个提交记录
git rebase -i HEAD~3
git branch -f master bugFix

或者

git cherry-pick bugFix
git branch -f master bugFix
2.提交的技巧 #1
git rebase -i HEAD~2 #修改C2和C3的顺序
git commit --amend
git rebase -i HEAD~2 #修改C3'和C2''顺序
git branch -f master
3.提交的技巧 #2
git checkout master
git cherry-pick newImage
git commit --amend
git cherry-pick caption
4.Git Tag
git tag v0 c1
git tag v1 c2
git checkout c2
5.Git Describe

由于标签在代码库中起着“锚点”的作用,Git 还为此专门设计了一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe

Git Describe 能帮你在提交历史中移动了多次以后找到方向;当你用 git bisect(一个查找产生 Bug 的提交记录的指令)找到某个提交记录时,或者是当你坐在你那刚刚度假回来的同事的电脑前时, 可能会用到这个命令。

git describe 的语法是:

git describe <ref>

可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。

它输出的结果是这样的:

<tag>_<numCommits>_g<hash>

tag 表示的是离 ref 最近的标签, numCommits 是表示这个 ref 与 tag 相差有多少个提交记录, hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。

当 ref 提交记录上有某个标签时,则只输出标签名称。

git commit

高级话题

1.多次 Rebase
git rebase master bugFix
git rebase bugFix side
git rebase side another
git branch -f master another
2.两个父节点
git branch bugWork HEAD~^2~
3.纠缠不清的分支
git checkout one
git cherry-pick c4 c3 c2
git checkout two
git cherry-pick c5 c4 c3 c2
git branch -f three c2

远程

Push & Pull —— Git 远程仓库!

1.Git Clone
git clone
2.远程分支
git commit
git checkout o/master
git commit
3.Git Fetch
git fetch
4.Git Pull

git pull就是git fetchgit merge <just-fetched-branch>的缩写。

git pull
5.模拟团队合作
git clone
git fakeTeamwork 2
git commit
git pull
6.Git Push
git commit
git commit
git push
7.偏离的提交历史

git pull --rebase就是fetchrebase的简写。

git clone
git fakeTeamwork 1
git commit
git pull --rebase
git push

关于 origin 和它的周边 —— Git 远程仓库高级操作

1.推送主分支
git fetch
git rebase o/master side1
git rebase side1 side2
git rebase side2 side3
git rebase side3 master
git push
2.合并远程仓库
git checkout master
git pull origin master
git merge side1
git merge side2
git merge side3
git push origin master
3.远程追踪
git checkout -b side o/master
git commit
git pull --rebase
git push
3.远程追踪
git branch -f side master
git commit
git pull --rebase
git push
4.Git Push 的参数
git push origin master
git push origin foo
5.Git Push 的参数 2
git push origin foo:master
git push origin master^:foo
6.Git Fetch 的参数
git fetch origin master^:foo
git fetch origin foo:master
git checkout foo
git merge master

git pull origin master^:foo
git pull origin foo:master
git branch -f foo
git checkout foo
7.没有 source 的 source
git pull origin :bar
git push origin :foo
8.Git Pull 的参数
git pull origin bar:foo
git pull origin master:sidegit rebase能够将分叉的分支重新合并,之前写过一篇文章介绍它的原理,下面主要介绍它的两个使用场景:

场景一:本地与远端同一分支提交历史不一致

方式一

多个人在同一个分支上协作时,出现冲突是很正常的,比如现在有一个项目由我和 A 一同开发。

我在修复了一个 bug 以后准备提交

HowiedeiMac:ganlin howie$ git add models/paper.go
HowiedeiMac:ganlin howie$ git commit -m 'fix a bug'
[master 8b76654] fix a bug
 1 file changed, 3 insertions(+), 3 deletions(-)

现在准备推送到远端

HowiedeiMac:ganlin howie$ git push origin master
To https://gitee.com/greenhn/ganlin.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://gitee.com/greenhn/ganlin.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

push 失败了,说明 A 在我之前已经提交了,我本地 master 分支的提交历史已经落后远端了,需要先 pull 一下,与远端同步后才能 push

HowiedeiMac:ganlin howie$ git pull
remote: Enumerating objects: 14, done.
remote: Counting objects: 100% (14/14), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From https://gitee.com/greenhn/ganlin
   a1bc60a..b91f711  master     -> origin/master
Merge made by the 'recursive' strategy.
 controllers/deal_local_data.go | 14 +++++++++++---
 controllers/rtu_interface.go   |  8 ++++----
 models/instrument_type.go      |  3 +++
 models/rtu_interface.go        |  3 +++
 4 files changed, 21 insertions(+), 7 deletions(-)

pull 成功,现在使用 git log 看下一提交历史:

HowiedeiMac:ganlin howie$ git log --oneline --graph
*   f63ecbf (HEAD -> master) Merge branch 'master' of https://gitee.com/greenhn/ganlin
|\
| * b91f711 (origin/master, origin/HEAD) 修正bug,优化内置通道配置
* | 8b76654 fix a bug
|/
* a1bc60a 完善日报接口
* 9f73b5e 增加内置通道设置功能
* a0d464e ...

竟然分叉了!由于我本地 master 的提交历史和远端的 master 分支的提交历史不一致,所以 git 为我进行了自动合并,然后生成了一个新的提交历史(f63ecbf Merge branch 'master' of

对于部分强迫症来说这个不能接受的,不想看到分叉。

这个时候用git rebase就可以解决

HowiedeiMac:ganlin howie$ git rebase
First, rewinding head to replay your work on top of it...
Applying: fix a bug

现在再查看一下提交历史:

HowiedeiMac:ganlin howie$ git log --oneline --graph
* 2e2b995 (HEAD -> master) fix a bug
* b91f711 (origin/master, origin/HEAD) 修正bug,优化内置通道配置
* a1bc60a 完善日报接口
* 9f73b5e 增加内置通道设置功能
* a0d464e ...

完美解决,现在再 push 推送到远端:

HowiedeiMac:ganlin howie$ git push origin master
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 394 bytes | 394.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Powered By Gitee.com
To https://gitee.com/greenhn/ganlin.git
   b91f711..2e2b995  master -> master

再次查看提交历史

HowiedeiMac:ganlin howie$ git lg --oneline --graph
* 2e2b995 (HEAD -> master, origin/master, origin/HEAD) fix a bug
* b91f711 修正bug,优化内置通道配置
* a1bc60a 完善日报接口
* 9f73b5e 增加内置通道设置功能
* a0d464e ...

现在远端 master,远端 head,本地 master 全部统一,问题解决。

方式二

直接执行:
git pull --rebase
效果与上面是一致的,也是最近才发现,推荐使用

场景二:不同分支之间的合并

由于老板突发奇想,要求开发一个新的功能。

先创建一个分支用于开发新功能:

git checkout -b feature

HowiedeiMac:hello howie$ git checkout -b feature
Switched to a new branch 'feature'
HowiedeiMac:hello howie$ git branch
* feature
  master

接下来修改 newFunc.go,增加新的功能,并且保存提交

vim newFunc.go

git add newFunc.go

git commit -m 'add new func'

现在查看一下提交

HowiedeiMac:hello howie$ git log --oneline --graph
* 4f58ab8 (HEAD -> feature) add new func
* 94c134b (master) init base

HowiedeiMac:hello howie\$ git branch

- feature
  master

现在新功能开发完毕,需要将它合并的主分支中。

先尝试通过 merge 合并:

首先切换到 master 分支

git checkout master

HowiedeiMac:hello howie$ git checkout master
  Switched to branch 'master'
  Your branch is up to date with 'origin/master'.

直接合并 feature 分支

git merge feature

HowiedeiMac:hello howie$ git merge feature
  Auto-merging newFunc.go
  CONFLICT (content): Merge conflict in newFunc.go
  Automatic merge failed; fix conflicts and then commit the result.

竟然失败了,说明我两个分支之前的版本已经不同步了,需要手动合并冲突,再提交:

先查看冲突文件:git status

HowiedeiMac:hello howie$ git status
  On branch master
  Your branch is ahead of 'origin/master' by 7 commits.
    (use "git push" to publish your local commits)

You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Unmerged paths:
(use "git add <file>..." to mark resolution)

        both modified:   newFunc.go

打开文件,进行修改

原文件:

func NewFunc() {
<<<<<<< HEAD
=======
    fmt.Println("add new func")
>>>>>>> feature
}

修改后:

func NewFunc() {
    fmt.Println("add new func")
}

现在通过 add 添加,然后 commit 提交

HowiedeiMac:hello howie$ git add newFunc.go

HowiedeiMac:hello howie\$ git commit -m 'merge master and feature'
[master 562ec58] merge master and feature

现在在查看一下分支提交历史:

HowiedeiMac:hello howie$ git log --oneline --graph
*   562ec58 (HEAD -> master) merge master and feature
|\
| * 4f58ab8 (feature) add new func
* | 0e80f97 do something
|/
* 94c134b init base

虽然合并成功,但是 Master 已经保存了合并历史,出现开叉了!对于强迫症患者来说肯定是不能接受的。

通过 rebase 合并分支:

现在将版本退回到合并前,也就是回退一个版本

git reset --hard head^

HowiedeiMac:hello howie$ git reset --hard head^
HEAD is now at 0e80f97 do something

HowiedeiMac:hello howie\$ git log --oneline --graph

- 0e80f97 (HEAD -> master) do something
- 94c134b init base

退回去了,现在是位于 master 分支的init base提交这里。

先切换回 feature 分支:

HowiedeiMac:hello howie$ git checkout feature
  Switched to branch 'feature'

在 feature 分支上执行: git rebase master

这句命令的意识是:以 master 为基础,将 feature 分支上的修改增加到 master 分支上,并生成新的版本。

HowiedeiMac:hello howie$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: add new func
Using index info to reconstruct a base tree...
M       newFunc.go
Falling back to patching base and 3-way merge...
Auto-merging newFunc.go
CONFLICT (content): Merge conflict in newFunc.go
error: Failed to merge in the changes.
Patch failed at 0001 add new func
hint: Use 'git am --show-current-patch' to see the failed patch

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

失败了,原因很简单,两个分支修改个同一个文件,产生了冲突。所以先需要解决冲突:

打开冲突的文件,解决冲突

原文件:

func NewFunc() {
<<<<<<< HEAD
=======
    fmt.Println("add new func")
>>>>>>> add new func
}

修改后:

func NewFunc() {
    fmt.Println("add new func")
}

现在通过 add 添加

HowiedeiMac:hello howie$ git add newFunc.go

现在是重点,之前的 rebase 其实只是完成了一半,由于出现冲突而终止,现在冲突解决,可以通过git rebase —continue继续完成之前的 rebase 操作。

HowiedeiMac:hello howie$ git rebase --continue
Applying: add new func

rebase 完成,再查看一下提交历史:

HowiedeiMac:hello howie$ git log --oneline --graph
* b2593e6 (HEAD -> feature) add new func
* 0e80f97 (master) do something
* 94c134b init base

提交记录已经是一条完美的直线。现在切换到主分支 master,将 feather 分支上的提交合并过来。

git checkout master

git merge feature

HowiedeiMac:hello howie$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 7 commits.
  (use "git push" to publish your local commits)

HowiedeiMac:hello howie\$ git merge feature
Updating 0e80f97..b2593e6
Fast-forward
newFunc.go | 1 +
1 file changed, 1 insertion(+)

再次查看一下提交历史:

HowiedeiMac:hello howie$ git log --oneline --graph
* b2593e6 (HEAD -> master, feature) add new func
* 0e80f97 do something
* 94c134b init base

问题解决,master 上也是一条直线了。

最后收个尾,删除掉 feature 分支:

HowiedeiMac:hello howie$ git branch -d feature
Deleted branch feature (was b2593e6).
posted @ 2021-04-13 13:59  Frank-Link  阅读(598)  评论(0编辑  收藏  举报