Close

Git Forks 和 Upstreams:操作方法和实用提示

Nicola Paolucci 头像
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 徽标
查看解决方案

了解 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 trTAB 转换为分隔符 |

git upstream 入门


这是 git upstream 的基本演练——如何在 git 上游设置 git、创建新分支、收集变更、使用 git 拷贝发布,以及远程分支在前面/后面有多少提交的小提示。

Bitbucket Server 包括拷贝同步,这基本上减轻了开发人员了解其拷贝最新状态的所有负担,而 Bitbucket Cloud 有一个简单的一步同步,来看看吧!

关注我 @durdn 和很棒的 @Bitbucket 团队,了解更多 DVCS 优势。

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


分享此文章
下一主题

推荐阅读

将这些资源加入书签,以了解 DevOps 团队的类型,或获取 Atlassian 关于 DevOps 的持续更新。

人们通过满是工具的墙进行协作

Bitbucket 博客

Devops 示意图

DevOps 学习路径

与 Atlassian 专家一起进行 Den 功能演示

Bitbucket Cloud 与 Atlassian Open DevOps 如何协同工作

注册以获取我们的 DevOps 新闻资讯

Thank you for signing up