fork
是类似GitHub、码云等等在线代码托管平台提出来的功能; 原生Git并没有fork操作. fork可以克隆出一个仓库的新拷贝,包含原仓库(即upstream repository,上游仓库)所有内容,如分支、Tag、提交. 若在被克隆项目进行修改和提交, 则完全不影响原仓库. 而若要将修改推到原仓库, 需要pull request,一旦对方接受,修改便合并入原仓库.
branch
是一个Git操作,在原先仓库上开启一个新的分支. 处理分支的方式比起fork十分轻量,创建新分支速度极快,并且在不同分支之间的切换操作也是一样便捷. 默认仓库只有一条master分支:
通过git branch可以创建一个分支,但并不会自动切换到新分支中去:
通过git checkout可以切换到另一个分支:
当接到了一个新的需求,可以在新分支testing修改代码而不影响原主干代码,等修改测试完毕后再合并到主干上去。
cherry-pick
git cherry-pick是本地特性,本地要有这个commit才可以被cherry-pick, 对于fork而来的克隆仓库上的commit, 一旦进行git cherry-pick将得到 fatal: bad object commit_id 的报错.
那么如何cherry-pick其他仓库的提交呢? 通过添加远程版本库, 与本地关联来实现:
git remote add -f origin_xxx git@sqbu-github.xxxxx.com:nyuan/sl-main.git
然后便可以显示所有远程仓库和本地仓库的关联(注意是仓库而不是分支哦):
lajiang@liajiang-lnx:~/Workspace/bumblebee/sl-main$ git remote -v
origin git@sqbu-github.xxxxx.com:SL/sl-main.git (fetch)
origin git@sqbu-github.xxxxx.com:SL/sl-main.git (push)
origin_xxx git@sqbu-github.xxxxx.com:nyuan/sl-main.git (fetch)
origin_xxx git@sqbu-github.xxxxx.com:nyuan/sl-main.git (push)
upstream git@sqbu-github.xxxxx.com:SL/sl-main.git (fetch)
upstream git@sqbu-github.xxxxx.com:SL/sl-main.git (push)
现在就可以cherry-pick远程仓库git@sqbu-github.xxxxx.com:nyuan/sl-main.git的某个commit了.
此外, 如果需要修改或者删除远程仓库可以使用直接修改, 或先删除后添加2种方法:
git remote set-url origin [url]
//or
git remote rm origin
git remote add origin [url]
pull request 和 git merge
上面提到的pull request这个概念和fork一样, 也是代码托管平台而非原生Git提供的. 方式是通过将另一个仓库的某个分支往原仓库的某个分支进行合并, 这可以从github的pull request来体会一下:
当然若因为代码差异或冲突等因素不能merge, 托管平台会有所提示而提前拒绝.
对于branch没有pull request操作, 但开启branch的本意和fork其实差不多, 都是为了修改原仓库主分支功能而在不影响原仓库主分支前提下下进行开发. 只不过在fork更为彻底, 操作更为昂贵. 对于fork来说最进一步的合并操作叫做pull request; 而对于branch最后一步的合并操作叫做 git merge(这是git原生操作), 例如gitlab平台就是基于分支合并的:
要把其他branch并入master, 在代码托管平台应该可以设置相关权限, 如git merge也需要其他人的批准才可以合并, 这和pull request需要其他人approve是类似的.
综上, branch和fork的目的是雷同的, 都是为了开发的分叉和合并. 只是前者基于同一仓库的不同分支, 后者基于克隆整个仓库, 更彻底灵活性更大但是代价也更高而已.
参考:
Git:从某个commit提交,检出为新的分支_琦彦的博客-CSDN博客_git 检出到某个commit
Pull Request 与 Merge Request 的区别_fe_lucifer的博客-CSDN博客