【问题标题】:git: Pushing Single Commits, Reordering with rebase, Duplicate Commitsgit:推送单个提交、使用 rebase 重新排序、重复提交
【发布时间】:2015-03-03 08:21:16
【问题描述】:

我想将几个单一的提交推送到一个 git 远程仓库。我按照 Geoff 的回答在这里找到了这样做:

How can I pushing specific commit to a remote, and not the previous commits?

我要推送的提交不在前面,所以我必须先使用 rebase 重新排序提交,我使用这些说明来这样做:

http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html

基本上我已经完成了:

git clone
git commit
git commit
...
git pull
git rebase -i HEAD~3
git push origin <SHA>:master

我在执行此操作时出错。所以我开始深入研究这个问题。如果我在 rebase 后执行第二次 git pull,我发现我的日志中有重复的提交,例如:

git clone
git commit
git commit
...
git pull
git log --pretty=format:"%h - %an : %s" // log before rebasing
git rebase -i HEAD~3
git pull
git log --pretty=format:"%h - %an : %s" // log after rebasing
git pull 
git log --pretty=format:"%h - %an : %s" // log after rebasing after pulling

所以我发布了这个问题:

git: Duplicate Commits After Local Rebase Followed by Pull

Roger 的回答让我想到了这个问题:为什么我在 rebase 和 pull 后看到重复的提交?

从上面看,变基前的日志如下:

84e4015 - Me : Local Commit 3
0dbe86a - Me : Local Commit 2
d57ba2a - Me : Merge branch 'master' of remote repository
a86ea35 - Me : Local Commit 1 before reordering
2fc4fe7 - Remote User 2 : Remote Commit 2
b7a8656 - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository

变基后的日志如下:

cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository

注意原来的 2 次提交 2fc4fe7 和 b7a8656 有新的 SHA; 9777c56 和 a2d7d8b。我相信这是问题的开始。

现在,在我执行另一个 git pull 后,日志如下所示:

e8e1a85 - Me : Merge branch 'master' of remote repository
cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
2fc4fe7 - Remote User 2 : Remote Commit 2 // duplicate 2
b7a8656 - Remote User 1 : Remote Commit 1 // duplicate 1
8ce80fc - Me : Merge branch 'master' of remote repository

请注意,远程提交现已复制,并且远程提交的原始 SHA 2fc4fe7 和 b7a8656 已返回。

在 Roger 的回应中,他说这看起来像是其他人推送到 git 的错,并且他们正在重新定位他们已经推送的提交。但我相信在本地重新定位推送的提交是我的错。

这是因为我重新设置了已经推送到远程的提交吗?如果是这样,我应该怎么做才能避免这种情况?我需要重新提交我的提交,以便我可以推送一个提交。我应该使用分支系统来执行此操作吗?如果是这样,我将如何使用分支来解决这个问题?

【问题讨论】:

标签: git duplicates git-rebase git-pull


【解决方案1】:

简短的回答是,rebase 不会更改 提交,1 而是复制它们。 Git 通常会隐藏原件,但如果您的原件包括其他用户共享的原件,您(当然还有他们)仍然可以看到这些原件。

作为一般规则,您应该只对自己的私有、未发布的提交进行变基。由于没有人else根据定义拥有这些副本,因此您制作自己的副本然后(通过变基)隐藏您的原件这一事实不是问题:您现在看到的是您的副本而不是您的原件,其他人也看不到,如果需要,您可以继续变基。但是,一旦您发布(通过push 或类似方式)提交,您就不能再更改它,因为其他人现在拥有您的原始副本,包括其 SHA-1 ID,并且他们以后仍将拥有它.

在这种情况下,您所做的是重新设置(即复制)他们的 提交以及您自己的提交。部分问题源于使用git pull,这意味着“提取然后合并”,而您想要的是“提取然后变基”。您可以单独执行这些步骤:

git fetch
git rebase

或使用git pull --rebase:

git pull --rebase

它告诉pull 脚​​本,在进行提取之后,它应该进行变基而不是合并。您还可以将 git 配置为自动执行此操作,无需 --rebase 参数。2

现在的主要问题是您可能不想要一个合并。如果是这样,您将需要“撤消”该合并(使用 git reset;请参阅其他 stackoverflow 帖子)。


1它不能:一个 git 对象,包括一个提交,是由它的对象 ID 命名的,它是它的内容的加密校验和。提交由其父 ID、树的 ID、提交的作者和提交者(姓名、电子邮件和时间戳)以及提交消息组成。如果您更改其中任何一项,您将获得具有不同 ID 的新的不同提交。

2您甚至可以将其配置为使用git pull --rebase=preserve。但是,跨 rebase 操作保留合并是一个单独的主题(我之前在 stackoverflow 帖子中已经讨论过)。

【讨论】:

  • 有道理,在我阅读了您的回答后,我发现了这篇文章:When should I use git pull --rebase?。它补充了这个答案,并且有几个答案解释了 git pull --rebase 的实际作用。我将尝试使用 git pull --rebase 并将您的回复标记为答案(如果/何时有效)。谢谢!
  • 这明白了。 git pull --rebase 重新定位我的本地提交,使它们比远程仓库中的提交位于顶部,即更新。因此,当我重新设置提交以重新排序时,我不会重新设置已推送到远程仓库的提交。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 1970-01-01
  • 2017-07-04
  • 2014-07-13
  • 1970-01-01
  • 2014-10-14
相关资源
最近更新 更多