Git Forks 和 Upstreams:操作方法和实用提示
Nicola Paolucci
开发人员推广人员
拷贝项目来进行自己的变更可以让您轻松整合自己的贡献。但是,如果您不将这些变更发送回上游(这意味着将其发送回父项存储库),则可能会丢失对它们的跟踪,这可能会导致存储库中的行分歧。为确保所有贡献者都来自同一个地方,您需要了解 git forking 如何与 git upstream 交互的一些原则。在这篇博客中,我将向您介绍基础知识、陷阱,甚至还有一个很酷的提示,助您走在潮流前线。
Git 上游:保持最新状态并做出贡献
首先,我们来详细了解与 upstream
存储库交互的常见设置和最基本的工作流。
在标准设置中,您通常有一个 origin
和一个 upstream
远程分支,后者是项目的看门人,或者是您想要贡献的数据源。
首先,确认您已经为 upstream
存储库设置了远程存储库,最好还设置了 origin
库:
git remote -v
origin git@bitbucket.org:my-user/some-project.git (fetch)
origin git@bitbucket.org:my-user/some-project.git (push)
如果您没有 upstream
,可以用 remote
命令轻松添加:
git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git
相关资料
如何移动完整的 Git 存储库
查看解决方案
了解 Bitbucket Cloud 的 Git
验证是否正确添加了远程存储库:
git remote -v
origin git@bitbucket.org:my-user/some-project.git (fetch)
origin git@bitbucket.org:my-user/some-project.git (push)
upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)
现在,您可以使用 fetch
收集 upstream
存储库的最新变更。每次想要获取更新时都要重复此操作:
(如果项目中有尚未合并到主分支的标记,您也应该这样做:git fetch upstream --tags)
git fetch upstream
通常,您希望将本地 main
分支作为 upstream
main
分支的近距离镜像,并在功能分支中执行任何工作,因为它们以后可能会变成拉取请求。
此时,使用 merge
还是 rebase
都没关系,因为结果通常是相同的。我们使用 merge
:
git checkout main
git merge upstream/main
当您想与 main
分支的 upstream
维护人员分享一些工作时,可以创建一个功能分支。等您觉得满意后,将其推送到您的远程存储库。
您也可以改用 rebase
,然后 merge
以确保 upstream
有一组干净的提交(最好是一个)需要评估:
git checkout -b feature-x
#some work and some commits happen
#some time passes
git fetch upstream
git rebase upstream/main
使用 git fork 发布
完成上述步骤后,只需 push
一下,即可在远程拷贝中发布您的工作:
git push origin feature-x
git push -f origin feature-x
就我个人而言,我更喜欢保持历史记录尽可能简洁并选择选项三,但是不同的团队有不同的工作流程。注意:只有在使用自己的拷贝时才应这样做。您永远都不应该重写共享存储库和分支的历史记录。
每日提示:提示中的领先/落后数字
fetch
后,git status
会显示您在同步的 remote
分支前面或后面有多少提交。如果您能在忠实的命令提示符下看到这些信息,那不是很好吗?我也这么想,所以我开始用 bash
尝试并逐渐完善。
配置完成后,它在提示符上的显示效果如下:
nick-macbook-air:~/dev/projects/stash[1|94]$
这就是您需要添加到您的 .bashrc
中的内容或等效函数——只是一个函数:
function ahead_behind {
curr_branch=$(git rev-parse --abbrev-ref HEAD);
curr_remote=$(git config branch.$curr_branch.remote);
curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"
内部运作
对于那些喜欢细节和解释的人,以下是它的工作原理:
我们活动当前 HEAD 的符号名称,即当前分支:
curr_branch=$(git rev-parse --abbrev-ref HEAD);
我们得到了当前分支所指向的远程存储库:
curr_remote=$(git config branch.$curr_branch.remote);
我们得到了应该合并这个远程存储库的分支(用一个便宜的 Unix 技巧来丢弃包括最后一个斜杠 [/] 在内的所有内容):
curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
现在我们有了收集领先或落后提交的计数次数所需的东西:
git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
我们使用古老的 Unix tr
将 TAB
转换为分隔符 |
。
git upstream 入门
这是 git upstream
的基本演练——如何在 git 上游设置 git、创建新分支、收集变更、使用 git 拷贝发布,以及远程分支在前面/后面有多少提交的小提示。
Bitbucket Data Center 包括克隆同步,这基本上减轻了开发人员随时了解其克隆最新状态的所有负担,而 Bitbucket Cloud 则提供了一个简单的一步同步,来看看吧!
分享此文章
下一主题
推荐阅读
将这些资源加入书签,以了解 DevOps 团队的类型,或获取 Atlassian 关于 DevOps 的持续更新。