如何更新 fork 以发出干净的拉取请求?
How to bring fork up to date to make clean pull requests?
我正在 github
上的分叉副本上为开源回购做出贡献
我通常每隔几个月只修复我发现的奇怪错误,与此同时还会发生很多其他开发。我将拉取请求放入我的分支中以获取新更改。
现在它们出现在我的 pull requests back to the original repo 中。
如何创建仅包含每个修复提交的干净拉取请求?我已经尝试 git 在本地获取原始 repo 并从中进行合并,但我遇到了同样的问题。
tl;dr:分支 upstream/master。不要向你当地的主人承诺。
如果您的分支有本地更改,而您只是与上游合并,您仍然会有那些本地更改。当您基于合并后的母版提交 PR 时,它将包含这些本地更改。
我们来演示一下。这是合并本地更改后的样子。
# Your situation after merging with local changes.
# D - E - F are new changes from upstream.
# 1 - 2 - 3 is your local changes.
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
现在你从 master 创建一个分支并添加一些提交。
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
\
4 - 5 - 6 [feature]
如果您以 upstream/master 为基础将特性作为 PR 提交,它将拖入 1 - 2 - 3 以及 4 - 5 - 6,因为它们都包含与 [=69= 的差异].
这就是为什么要避免直接提交给 master,你不再有新分支的共同基础。相反,在分支机构中完成所有工作并将它们作为 PR 提交。
最简单和最安全的方法是将您的工作分支到 upstream/master 而不是 master。那么你的叉子处于什么状态并不重要。
$ git checkout -b feature upstream/master
# then make a few commits
4 - 5 - 6 [feature]
/
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
如果您有一个现有的 master 分支,请将其变基到 upstream/master。这将重写每个提交,就像您将其写在 upstream/master 之上一样。可能有冲突,按需修复。
# Before with feature based on master.
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
\
4 - 5 - 6 [feature]
# Rebase onto upstream/master the commits from master to feature.
$ git rebase --onto upstream/master master feature
4A - 5A - 6A [feature]
/
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
\
4 - 5 - 6
原来的4-5-6最终会被删除
要恢复你的 fork 的 master,return 你的 master
到你的上游的 master。
首先,在您现有的 master 上创建一个新分支以保留任何本地更改。
$ git checkout master
$ git branch dev # or whatever you want to call it
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
[dev]
现在您对 master 所做的任何本地更改都将保留在您的 dev
分支中。您可以随意命名它,但要避免使用上游已经存在的分支名称。
然后将本地 master 移动到上游的 master。
$ git checkout master
$ git reset --hard upstream/master
[master]
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [dev]
Git 中的分支只是指向提交的标签。 git reset
是您随意移动它们的方式。这会将您的本地 master 移动到 upstream/master 指向的位置。 --hard
指的是如何处理暂存区和检出文件(工作副本)。 --hard
表示也将它们重置为 upstream/master。
现在你的主人就是他们的upstream/master。 dev 有你对 master 的本地更改。
最后,将你的新本地master推送到origin。既然动了,就得用力。 不要使用 --force 使用更安全的 git push --force-with-lease
.
如果您想更新本地主控,只需 git pull
。 git pull
只是 git fetch
加上 git merge
。我们将 git pull
作为两个单独的步骤进行演示。
# Fetch new commits, that's G and H.
$ git fetch upstream
G - H [upstream/master]
/
A - B - C - D - E - F [master]
\ \
1 - 2 - 3 - M [dev]
$ git checkout master
$ git merge upstream/master
[master]
G - H [upstream/master]
/
A - B - C - D - E - F
\ \
1 - 2 - 3 - M [dev]
因为 master 是 upstream/master 的直接祖先,所以不需要合并提交。 Git 将“快进”到 upstream/master。
我正在 github
上的分叉副本上为开源回购做出贡献我通常每隔几个月只修复我发现的奇怪错误,与此同时还会发生很多其他开发。我将拉取请求放入我的分支中以获取新更改。
现在它们出现在我的 pull requests back to the original repo 中。
如何创建仅包含每个修复提交的干净拉取请求?我已经尝试 git 在本地获取原始 repo 并从中进行合并,但我遇到了同样的问题。
tl;dr:分支 upstream/master。不要向你当地的主人承诺。
如果您的分支有本地更改,而您只是与上游合并,您仍然会有那些本地更改。当您基于合并后的母版提交 PR 时,它将包含这些本地更改。
我们来演示一下。这是合并本地更改后的样子。
# Your situation after merging with local changes.
# D - E - F are new changes from upstream.
# 1 - 2 - 3 is your local changes.
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
现在你从 master 创建一个分支并添加一些提交。
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
\
4 - 5 - 6 [feature]
如果您以 upstream/master 为基础将特性作为 PR 提交,它将拖入 1 - 2 - 3 以及 4 - 5 - 6,因为它们都包含与 [=69= 的差异].
这就是为什么要避免直接提交给 master,你不再有新分支的共同基础。相反,在分支机构中完成所有工作并将它们作为 PR 提交。
最简单和最安全的方法是将您的工作分支到 upstream/master 而不是 master。那么你的叉子处于什么状态并不重要。
$ git checkout -b feature upstream/master
# then make a few commits
4 - 5 - 6 [feature]
/
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
如果您有一个现有的 master 分支,请将其变基到 upstream/master。这将重写每个提交,就像您将其写在 upstream/master 之上一样。可能有冲突,按需修复。
# Before with feature based on master.
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
\
4 - 5 - 6 [feature]
# Rebase onto upstream/master the commits from master to feature.
$ git rebase --onto upstream/master master feature
4A - 5A - 6A [feature]
/
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
\
4 - 5 - 6
原来的4-5-6最终会被删除
要恢复你的 fork 的 master,return 你的 master
到你的上游的 master。
首先,在您现有的 master 上创建一个新分支以保留任何本地更改。
$ git checkout master
$ git branch dev # or whatever you want to call it
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [master]
[dev]
现在您对 master 所做的任何本地更改都将保留在您的 dev
分支中。您可以随意命名它,但要避免使用上游已经存在的分支名称。
然后将本地 master 移动到上游的 master。
$ git checkout master
$ git reset --hard upstream/master
[master]
A - B - C - D - E - F [upstream/master]
\ \
1 - 2 - 3 - M [dev]
Git 中的分支只是指向提交的标签。 git reset
是您随意移动它们的方式。这会将您的本地 master 移动到 upstream/master 指向的位置。 --hard
指的是如何处理暂存区和检出文件(工作副本)。 --hard
表示也将它们重置为 upstream/master。
现在你的主人就是他们的upstream/master。 dev 有你对 master 的本地更改。
最后,将你的新本地master推送到origin。既然动了,就得用力。 不要使用 --force 使用更安全的 git push --force-with-lease
.
如果您想更新本地主控,只需 git pull
。 git pull
只是 git fetch
加上 git merge
。我们将 git pull
作为两个单独的步骤进行演示。
# Fetch new commits, that's G and H.
$ git fetch upstream
G - H [upstream/master]
/
A - B - C - D - E - F [master]
\ \
1 - 2 - 3 - M [dev]
$ git checkout master
$ git merge upstream/master
[master]
G - H [upstream/master]
/
A - B - C - D - E - F
\ \
1 - 2 - 3 - M [dev]
因为 master 是 upstream/master 的直接祖先,所以不需要合并提交。 Git 将“快进”到 upstream/master。